「软件工程-设计模式」 工厂模式

Posted by Dawn-K's Blog on February 21, 2021

工厂模式

[toc]

简单工厂模式

假设我们要制造小米和苹果的笔记本, 我们声明一个 Computer 抽象类, 然后派生 MiComputer 和 MacComputer 两个子类. 但是直接用new的话, 就无法将装配工作统一接口. 维护起来就会很麻烦.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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系统");
    }
}

简单工厂模式是说, 我们将构建过程也抽象出来, 我们传给工厂不同的参数, 以命令其生产不同的电脑, 而内部其生产过程其实是用各个电脑子类的构造方式, 我们无需关心.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class SimpleComputerFactory {
    public static Computer makeComputer(String brand) {
        Computer computer=null;
        switch (brand) {
            case "mac":
                computer=new MacComputer();
                break;
            case "mi":
                computer=new MiComputer();
                break;
            default:
                break;
        }
        return computer;
    }
}
// 使用方法,如果要修改,直接将 mi 改为 mac 即可
//  Computer computer= SimpleComputerFactory.makeComputer("mi");
//  computer.setOperationSystem();

工厂模式

工厂模式是简单工厂模式的升级版. 简单工厂模式虽然解决了构建的问题, 但是带来了严重的耦合, 一旦我们新加产品, 需要不停改动工厂类. 我们引入工厂模式, 是将工厂本身也抽象出来, 让工厂成为接口, 各自的产品分别使用各自的工厂(都是继承自工厂接口) 将简单工厂模式的工厂修改如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public interface ComputerFactory {
     Computer makeComputer();
}
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电脑
// ComputerFactory macFactory=new MacComputerFactory();
// macFactory.makeComputer().setOperationSystem();

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

// 如果后面要修改电脑的类型的话,只需要改 new 后面的构造函数名称即可,具有很好的扩展性.

抽象工厂模式

抽象工厂其实是另一种模式了. 这个是面向更大的问题, 比如上文中的苹果和小米, 如果它们不仅仅生产电脑, 还生产手机, 那么就需要更多的工厂. 我们可以考虑将一些相关的产品组成一个”产品族”,

新增手机类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public abstract class MobilePhoto {
    public abstract void setOperationSystem();
}
public class IPhoto extends MobilePhoto {
    @Override
    public void setOperationSystem() {
        System.out.println("苹果手机安装IOS系统");
    }
}
public class MiPhoto extends MobilePhoto {
    @Override
    public void setOperationSystem() {
        System.out.println("小米手机安装Android系统");
    }
}

然后修改工厂, 让一个工厂既能建造电脑, 又能建造手机.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public interface AbstractFactory {
     Computer makeComputer();
     MobilePhoto makeMobilePhoto();
}
public class AppleFactory implements AbstractFactory {
    @Override
    public Computer makeComputer() {
        return new MacComputer();
    }

    @Override
    public MobilePhoto makeMobilePhoto() {
        return new IPhoto();
    }
}
public class XiaoMiFactory implements AbstractFactory {
    @Override
    public Computer makeComputer() {
        return new MiComputer();
    }

    @Override
    public MobilePhoto makeMobilePhoto() {
        return new MiPhoto();
    }
}

但是抽象工厂模式有个缺陷就是: 对于添加产品族容易, 直接实现抽象工厂接口即可, 比如新增戴尔的手机和电脑工厂. 但是对于产品类的扩展比较困难, 比如我们新增鼠标类, 那么就必须修改所有的工厂, 包括抽象工厂. 这叫对开闭原则的倾斜性.

参考资料

简单工厂模式 工厂模式 抽象工厂模式