shusheng007
Published on 2020-02-16 / 262 Visits
0
1

秒懂设计模式之工厂方法模式(Factory Method Pattern)

[版权申明] 非商业目的注明出处可自由转载 出自:shusheng007

设计模式汇总篇,一定要收藏:

https://blog.shusheng007.top/archives/design-pattern

前言

人在IT江湖飘,不懂设计模式咋装X?

上一篇文章讨论了https://blog.shusheng007.top/archives/simple-factory-pattern,文末留了个坑,说其违背了开闭原则,因为引入新的产品需要不断的修改那个工厂方法,于是工厂方法模式就来了。。。

类型

创建型(creational)

难度

2颗星

定义

来小朋友们,让我们干了定义这杯苦酒吧:

Define an interface for creating an object, but let subclasses decide which class to instantiate. The Factory method lets a class defer instantiation it uses to subclasses.

定义一个用于创建对象的接口,让子类决定实例化哪个类

使用场景

最重要的知识点,这是最重要的知识点,这是最重要的知识点!

首先当然是在你需要new一个类的对象的时候,此时各种状况出现啦:

  1. 你不想直接new这个类的对象,怕以后这个类改变的时候你需要回来改代码,而此时依赖这个类的地方已经到处都是了。

  2. 这个类的对象构建过程非常复杂,你不愿意将这么复杂的构建过程一遍又一遍的写在需要用到此对象的地方。

  3. 这个类的对象在构建过程中依赖了很多其他的类,而你无法在调用的地方提供。

工厂方法模式是简单工厂方法模式的升级版本,为了克服简单工厂方法模式的缺点而生,作用和简单工厂方法完全一样。

UML

工厂方法模式的核心思想:讨论的仍然是如何构建同一类型产品(都实现同一个接口)的问题,只不过是通过为每一种要生产的产品配备一个工厂,就是说每个工厂只生产一种特定的产品。这样做的好处就是当以后需要增加新的产品时,直接新增加一个对应的工厂就可以了,而不是去修改原有的工厂,符合编程原则的开闭原则

工厂方法模式为每一种产品生成一个对应的工厂,从而替换掉简单工厂方法模式中那个静态工厂方法。

实例

在上一篇文章我们讲到,王二狗的基友骆驼所在的富士康承接了小米和苹果公司的笔记本生产订单,所以说可能最近很忙不能出来和二狗喝酒了,但没想到过了3天就约二狗出来撸串,这是发生了什么?原来是因为公司又接了联想笔记本的生产订单,工人在安装这条生产线的时候把工厂的线路搞坏了,这下好了,整个工厂就停产了...

可以看到这就是简单工厂的弊端,产生新的产品需要去修改工厂方法,一不小心就出bug了,所以改完了还得调试,测试才能上线,万一没测试好就废了...于是工厂方法模式闪亮登场了。

下面我们看下具体代码:

第一步:定义一个电脑的抽象基类

里面有一个为电脑安装操作系统的抽象方法,这个就是产品要实现的共同接口。

public abstract class Computer {
    public abstract void setOperationSystem();
}

第二步:实现具体品牌的电脑类

例如苹果电脑和小米电脑。

public class MacComputer extends Computer {
    @Override
    public void setOperationSystem() {
        System.out.println("Mac笔记本安装Mac系统");
    }
}
public class MiComputer extends Computer {
    @Override
    public void setOperationSystem() {
        System.out.println("小米笔记本安装Win10系统");
    }
}

第三步:定义工厂

首先定义一个抽象工厂ComputerFactory 接口,里面定义了生产方法,通过这个方法就可以生产出电脑,但是生产不同品牌的电脑的具体方式肯定是不同的,例如生产小米电脑的流水线和生产苹果电脑的流水线肯定是有区别的,所以这个接口方法由具体产品工厂去实现。

public interface ComputerFactory {
     Computer makeComputer();
}

下面是实现了生成苹果电脑的MacComputerFactory 工厂和生产小米电脑的MiComputerFactory 工厂。

public class MacComputerFactory implements ComputerFactory {
    @Override
    public Computer makeComputer() {
        return new MacComputer();
    }
}
public class MiComputerFactory implements ComputerFactory {
    @Override
    public Computer makeComputer() {
        return new MiComputer();
    }
}

简单工厂模式中那个静态工厂方法就被上面的那些工厂类代替了。

第四步:客户端使用

使用具体的工厂来生产相应品牌的电脑,例如要生产Mac电脑,就先构建Mac的生产工厂,然后去生产mac电脑。

public static void main(String[] args) {
    //生产Mac电脑
    ComputerFactory macFactory=new MacComputerFactory();
    macFactory.makeComputer().setOperationSystem();

    //生产小米电脑
    ComputerFactory miFactory=new MiComputerFactory();
    miFactory.makeComputer().setOperationSystem();
}

输出:

Mac笔记本安装Mac系统
小米笔记本安装Win10系统

优缺点

  • 优点:不直接在客户端创建具体产品的实例,降低了耦合性。

  • 缺点:每增加一种产品就要相应的增加一个工厂类,类增多了。

技术要点总结

  • 构建的都是同一类型的对象,即实现相同的接口

  • 每一类对象对应一个工厂

总结

骆驼和二狗喝的正酣,他领导来电话了,让他赶紧回去开会,又来大活了。小米和苹果把手机生产的订单也给富士康拉... 于是抽象工厂模式要登场了

源码

一如既往,你可以从Github上得到本文的源码:

https://github.com/shusheng007/design-patterns

,星星点一点,从此不迷路。


Comment