设计模式专题——工厂设计模式

258 阅读6分钟

每天进步一点点,坚持下去,你总是会不一样的。加油!

最近在整理java常用的一些基础、ZooKeeper、Spring全家桶、源码、Dubbo、Elasticsearch、Redis、MySql、RabbitMQ、Kafka、Linux 、微服务等技术栈。

持续更新,欢迎关注我的公众号 后端架构进阶

今天主要分享的是工厂设计模式,能帮我们节省很多时间,省去冗余的代码。在后面我们学到spring源码、AOP、事物等内容的时候就能很清楚的知道工厂设计模式的强大。

老规矩,先上目录:

一、工厂设计模式简介

二、工厂设计模式分类

三、简单工厂设计模式

四、工厂方法设计模式

五、抽象工厂设计模式

六、三种模式小结

一、工厂设计模式简介

工厂设计模式是我们最常用的实例化对象模式,利用工厂模式可以降低程序的耦合性,为后期的维护修改提供了很大的便利。将选择实现类、创建对象统一管理和控制。从而将调用者跟我们的实现类解耦。

二、工厂设计模式分类

工厂设计模式分为三种: 简单工厂设计模式、工厂方法设计模式、抽象工厂设计模式。

每种设计模式都各有优缺点,根据不同的业务场景来具体的使用。 下面我们就具体的来对每一种设计模式做介绍和演示具体是怎么一回事儿。

三、简单工厂设计模式

我们都知道,我们每天用的笔记本有很多品牌,比如:联想、戴尔、华硕等等。每种品牌都是由不用的厂商生产的。我们用简单工厂设计模式来实现下:

我们创建了一个电脑接口,联想和戴尔分别实现电脑接口,创建了一个工厂。用来生产电脑,然后创建了个客户端去使用。具体我们贴上代码

/**
 * @description: 简单工厂
 * @author:aerCool
 * @since:2020-03-15 09:23
 * @version:v1.0.0
 */
public interface Computer {

    void run();
}
public class Lenovo implements Computer {

    @Override
    public void run() {
        System.out.println("我是联想笔记本");
    }
}
public class Dell implements Computer {

    @Override
    public void run() {
        System.out.println("我是戴尔笔记本");
    }
}
public class Factory {

    public static Computer create(String name) {

        if (name == null) {
            return null;
        }

        if ("联想".equals(name)) {
            return new Lenovo();
        }

        if ("戴尔".equals(name)) {
            return new Dell();
        }

        return null;
    }
}
public class Client {

    public static void main(String[] args) {
        Computer lenovo = Factory.create("联想");
        Computer dell = Factory.create("戴尔");

        lenovo.run();
        dell.run();
    }
}

输出结果

我是联想笔记本
我是戴尔笔记本

简单工厂模式的优缺点

优点:简单工厂模式能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。明确区分了各自的职责和权力,有利于整个软件体系结构的优化。

缺点:很明显工厂类集中了所有实例的创建逻辑,违背了高内聚的责任分配原则。

四、工厂设计方法模式

工厂方法模式Factory Method,又称多态性工厂模式。在工厂方法模式中,核心的工厂类不再负责所有的产品的创建,而是将具体创建的工作交给子类去做。该核心类成为一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。

我们具体演示下,我们做了调整,具体如下

我们不再是让同一个工厂生产电脑,而是交给具体的电脑厂商来进行生产。职责更明确,联想电脑让联想工厂生产,戴尔电脑让戴尔工厂生产,包产到户。

public class LenovoFactory implements Factory {

    @Override
    public Computer create() {
        return new Lenovo();
    }
}
public class DellFactory implements Factory {

    @Override
    public Computer create() {
        return new Dell();
    }
}

最终,简单工厂生产电脑的时候就这样生产了

public class Client {

    public static void main(String[] args) {
        Computer lenovo = new LenovoFactory().create();
        Computer dell = new DellFactory().create();

        lenovo.run();
        dell.run();
    }
}

输出结果如下

我是联想笔记本
我是戴尔笔记本

我们发现这样就很方便维护不同类型的产品,单一职责原则。

但是如果有一天老板说我们不仅要生产电脑,零部件我们也要自己生产,不去外面买了。我们又怎么去实现呢?

这个时候,我们的抽象工厂设计模式就登场了,请继续往下看。

五、抽象工厂设计模式

抽象工厂简单地说是工厂的工厂,抽象工厂可以创建具体工厂,由具体工厂来产生具体产品。

把具体的工厂理解为包装厂可能更贴切,比如联想包装厂需要组装好产品,包括显示器、主板、内存等等。

我们具体来看看

我们有显卡厂商,主板厂商,显卡有:AMD和GTX显卡,主板有:技嘉和微星。

比如我们联想电脑是搭配GTX显卡,技嘉主板;戴尔搭配AMD显卡,微星主板,我们看看具体代码怎么实现

/**
 * @description: 显卡
 * @author:aerCool
 * @since:2020-03-15 10:18
 * @version:v1.0.0
 */
public interface Display {

    void show();
}
/**
 * @description: 主板
 * @author:aerCool
 * @since:2020-03-15 10:20
 * @version:v1.0.0
 */
public interface MainBoard {

    void run();
}
/**
 * @description:AMD显卡
 * @author:aerCool
 * @since:2020-03-15 10:22
 * @version:v1.0.0
 */
public class AMDDisplay implements Display {

    @Override
    public void show() {
        System.out.println("AMD一般显卡");
    }
}
/**
 * @description:GTX显卡
 * @author:aerCool
 * @since:2020-03-15 10:21
 * @version:v1.0.0
 */
public class GTXDisplay implements Display {

    @Override
    public void show() {
        System.out.println("GTX高性能显卡");
    }
}
/**
 * @description: 技嘉主板
 * @author:aerCool
 * @since:2020-03-15 10:23
 * @version:v1.0.0
 */
public class JiJiaMianBoard implements MainBoard {

    @Override
    public void run() {
        System.out.println("技嘉主板");
    }
}
/**
 * @description: 微星主板
 * @author:aerCool
 * @since:2020-03-15 10:24
 * @version:v1.0.0
 */
public class WeiXinMainBoard implements MainBoard {

    @Override
    public void run() {
        System.out.println("微星主板");
    }
}

零部件准备好了,我们要包装联想和戴尔

/**
 * @description: 联想包装厂
 * @author:aerCool
 * @since:2020-03-15 09:48
 * @version:v1.0.0
 */
public class LenovoFactory implements Factory {

    @Override
    public Display createDdisplay() {

        //搭配的是GTX显卡
        return new GTXDisplay();
    }

    @Override
    public MainBoard createMainBoard() {

        //搭配的是技嘉主板
        return new JiJiaMianBoard();
    }
}
/**
 * @description: 戴尔包装厂
 * @author:aerCool
 * @since:2020-03-15 09:48
 * @version:v1.0.0
 */
public class DellFactory implements Factory {

    @Override
    public Display createDdisplay() {

        //使用AMD显卡
        return new AMDDisplay();
    }

    @Override
    public MainBoard createMainBoard() {

        //使用微星主板
        return new WeiXinMainBoard();
    }
}

ok,我们看看效果

/**
 * @description: 测试类
 * @author:aerCool
 * @since:2020-03-15 09:30
 * @version:v1.0.0
 */
public class Client {

    public static void main(String[] args) {

        Factory lenovo = new LenovoFactory();

        Display levDisplay = lenovo.createDdisplay();
        MainBoard levMainBoard = lenovo.createMainBoard();

        levDisplay.show();
        levMainBoard.run();

        System.out.println("------------------------------------");

        Factory dell = new DellFactory();

        Display dellDdisplay = dell.createDdisplay();
        MainBoard dellMainBoard = dell.createMainBoard();

        dellDdisplay.show();
        dellMainBoard.run();

    }
}

输出结果如下

GTX高性能显卡
技嘉主板
------------------------------------
AMD一般显卡
微星主板

抽象工厂模式可能不是很好理解,自己动手试试,后面我们分析Sping源码的时候再进一步的进行拆分讲解。结合Spring的bean工厂我们就能很好的理解它了。

六、三种模式小结

1、如果产品比较确定,变动比较小,建议使用简单工厂。

2、平时工作中工厂方法使用场景比较多。

3、抽象方法在一些大型项目和一些源码中使用比较广泛。,比如Spring的Bean工厂。

好了,以上就是今天的内容。有错误的地方欢迎指正。

喜欢记得关注我的公众号:后端架构进阶 一起学习探讨!!!