转载整理至:微信公众号 程序小灰

一、工厂模式介绍

  • 分类:

    简单工厂:通过工厂类创建对象,并且根据传入参数决定具体子类的在做法
    工厂方法:利用多态特性动态创建对象的模式
    抽象工厂:把产品分类,组内不同产品对应同一工厂类的不同方法的设计模式

二、漫画讲解

640 (1).png

640 (2).png

——————————第二天 —————————

640 (1).png

640 (3).png

640 (4).png

640 (5).png

640 (6).png

640 (7).png

640 (8).png

————————————————————————

640 (9).png

640 (10).png

640 (11).png

640 (12).png

640 (13).png

640 (14).png

640 (15).png

ClassA a = new ClassA();
ClassB b = new ClassB();

640 (16).png

640 (17).png

640 (18).png

640 (19).png

640 (20).png

640 (21).png

640 (22).png

假设我们的业务代码当中,有一个被广泛引用的“口罩类”,这个类实例需要在许多地方被创建和初始化,而初始化的代码也比较复杂。

public class Mask {
    //构造函数
    public Mask(){
        // .....
        // 100行初始化代码
    }
}

针对这种情况,我们可以构建一个“口罩工厂”专门负责创建口罩对象,把口罩的初始化代码迁移到工厂类的创建方法当中:

public class MaskFactory {

    public Mask createMask() {
        Mask mask = new Mask();
        // .....
        // 100行初始化代码
        return mask;
    }
}

640 (23).png

640 (24).png

假设口罩类只是一个抽象接口,有两个子类“高端口罩”和“低端口罩”分别实现了这个接口:

public interface IMask {
    void show();
}

public class HighEndMask implements IMask {
    @Override
    public void show() {
        System.out.println("我是高端口罩");
    }
}

public class LowEndMask implements IMask {
    @Override
    public void show(){
        System.out.println("我的低端口罩");
    }

}

那么口罩工厂该如何创建这两种类型的口罩呢?

很简单,在创建方法中传入参数(这里的参数是type),根据参数来做条件判断,决定创建什么样的口罩:

blic class MaskFactory{

    public IMask createMask(String type) {
        IMask mask = null;
        if("高端口罩".equals(type)){
            mask = new HighEndMask();
            // .....
            // HighEndMask的100行初始化代码
        }else if("低端口罩".equals(type)){
            mask =  new LowEndMask();
            // .....
            // LowEndMask的100行初始化代码
        }
        return mask;
    }
}

在客户端,想要创建什么样的口罩对象,只需传入对应的类型名称:

public class Test {

    public static void main(String[] args) {
        MaskFactory factory = new MaskFactory();
        IMask maskA = factory.createMask("高端口罩");
        IMask maskB = factory.createMask("低端口罩");
        maskA.show();
        maskB.show();
    }
}

640 (25).png

640 (26).png

640 (27).png

(注:所谓面向对象的开放-封闭原则,就是在程序中对“扩展”开放,对“修改”封闭。如果每次业务改动都要增加新的if-else,就涉及对旧有代码的修改,不但容易出错,可读性也不好。)

640 (28).png

640 (29).png

让我们根据这个思路,重构一下工厂类的逻辑:

public interface IMaskFactory {
    IMask createMask();
}

public class HighEndFactory implements IMaskFactory{

    @Override
    public IMask createMask() {
        IMask mask =  new HighEndMask();
        // .....
        // HighEndMask的100行初始化代码
        return mask;
    }
}

public class LowEndFactory implements IMaskFactory{

    @Override
    public IMask createMask() {
        IMask mask =  new LowEndMask();
        // .....
        //  LowEndMask的100行初始化代码
        return mask;
    }

在代码中,工厂类变成了抽象的接口,高端口罩工厂和低端口罩工厂这两个子类分别实现了该接口。

在客户端,想要创建什么样的口罩对象,只需实例化不同的工厂子类,调用相同的创建方法,无需再传入参数:

public class Test {

    public static void main(String[] args) {
        IMaskFactory factoryA = new LowEndFactory();
        IMaskFactory factoryB = new HighEndFactory();
        IMask maskA = factoryA.createMask();
        IMask maskB = factoryB.createMask();
        maskA.show();
        maskB.show();
    }
}

640 (30).png

640 (31).png

640 (32).png

比如,业务中需要创建口罩、防毒面具、防护服这三种产品,而每一种产品有包含高端和低端两类,按照工厂方法模式的解决方案,需要创建的类如下:

640 (33).png

如图所示,每一个产品类都对应着一个工厂类,当产品数量很多的时候,工厂类的数量也会越老越多,搞得系统非常复杂。

640 (34).png

640 (35).png

640 (36).png

640 (37).png

首先看一下产品类的代码,口罩和防护服是两个抽象接口,分别拥有高端和低端两个实现类:

public interface IMask {
    void showMask();
}

public class LowEndMask implements IMask {
    @Override
    public void showMask(){
        System.out.println("我的低端口罩");
    }
}

public class HighEndMask implements IMask {
    @Override
    public void showMask() {
        System.out.println("我是高端口罩");
    }
}

public interface IProtectiveSuit {
    void showSuit();
}

public class LowEndProtectiveSuit implements IProtectiveSuit {
    @Override
    public void showSuit() {
        System.out.println("我是低端防护服");
    }
}

public class HighEndProtectiveSuit implements IProtectiveSuit {
    @Override
    public void showSuit() {
        System.out.println("我是高端防护服");
    }
}

接下来是工厂类,由于产品分成了高端和低端两大组,工厂也相应分成了高端工厂和低端工厂,各自负责组内产品的创建:

public interface IFactory {
    //创建口罩
    IMask createMask();
    //创建防护服
    IProtectiveSuit createSuit();
}

public class LowEndFactory implements IFactory {
    @Override
    public IMask createMask() {
        IMask mask =  new LowEndMask();
        // .....
        //  LowEndMask的100行初始化代码
        return mask;
    }

    @Override
    public IProtectiveSuit createSuit() {
        IProtectiveSuit suit =  new LowEndProtectiveSuit();
        // .....
        //  LowEndProtectiveSuit的100行初始化代码
        return suit;
    }
}

public class HighEndFactory implements IFactory {
    @Override
    public IMask createMask() {
        IMask mask =  new HighEndMask();
        // .....
        // HighEndMask的100行初始化代码
        return mask;
    }

    @Override
    public IProtectiveSuit createSuit() {
        IProtectiveSuit suit =  new HighEndProtectiveSuit();
        // .....
        //  HighEndProtectiveSuit的100行初始化代码
        return suit;
    }
}

最后是客户端代码,通过实例化不同的工厂子类,调用不同的创建方法,可以创建出不同的产品:

public class Test {

    public static void main(String[] args) {
        IFactory factoryA = new LowEndFactory();
        IFactory factoryB = new HighEndFactory();
        //创建低端口罩
        IMask maskA = factoryA.createMask();
        //创建高端口罩
        IMask maskB = factoryB.createMask();
        //创建低端防护服
        IProtectiveSuit suitA = factoryA.createSuit();
        //创建高端防护服
        IProtectiveSuit suitB = factoryB.createSuit();

        maskA.showMask();
        maskB.showMask();
        suitA.showSuit();
        suitB.showSuit();
    }

640 (38).png

640 (39).png

640 (40).png

简单工厂模式:

简单工厂模式有唯一的工厂类,工厂类的创建方法根据传入的参数做if-else条件判断,决定最终创建什么样的产品对象。

工厂方法模式:

工厂方法模式由多个工厂类实现工厂接口,利用多态来创建不同的产品对象,从而避免了冗长的if-else条件判断。

抽象工厂模式:

抽象工厂模式把产品子类进行分组,同组中的不同产品由同一个工厂子类的不同方法负责创建,从而减少了工厂子类的数量。