【设计模式 01】简单工厂

Java
324
0
0
2022-11-26

通过传给工厂类的参数的不同,返回不同的对象

简单工厂模式

简单工厂通过传给工厂类的参数的不同,返回不同的对象,包括三部分组成:

  1. 具体的”产品“
  2. 工厂类(实例化并返回”产品“)
  3. 客户端(使用”产品“)

为什么使用简单工厂:

  1. ”产品“的创建过程可能很复杂,涉及到多个不同类之间的依赖,通过简单工厂将创建过程隐藏在工厂类中,一方面减轻了客户端使用该产品的难度,另一方面也防止了客户端错误创建产品造成的安全问题。
  2. 将产品的生产和消费过程分离开,这样如果要有了一个新的产品,只需要把它加入到工厂类中,客户端需要时工厂类就会返回给它,否则的话,每次添加一个新的产品,都需要修改客户端代码,违反开闭原则。

简单工厂的缺点:

  1. 系统过度依赖工厂类,工厂类作为一个”上帝类“,负责创建客户端需要的所有对象,导致一旦工厂类出错,整个系统就会崩溃。
  2. 如果”产品类“特别多,工厂类中就会有很多个分支,造成工厂类异常庞大,难以维护。
  3. 每次添加新的产品都要修改工厂类,从工厂类的角度看违反了”开闭原则“,也不利于系统拓展。
  4. 工厂方法一般是静态方法,不利于继承。

适用场景

1、工厂类负责创建的对象比较少:由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。

2、客户端只知道传入工厂类的参数,对于如何创建对象不关心:客户端既不需要关心创建细节,甚至连类名都不需要记住,只需要知道类型所对应的参数。

例:

如果需要获取不同的手机对象,就可以使用简单工厂,具体的手机对象依赖于CPU, Camera等,通过简单工厂的封装,客户端获取 Phone 对象时就不需要了解具体的 ”生产过程“了.

实例化CPU, Camera 等配件时,也应该使用简单工厂。

img

package pers.junebao.simple_factory;

import pers.junebao.simple_factory.fitting.*;
import pers.junebao.simple_factory.phone.Honor;
import pers.junebao.simple_factory.phone.OnePlus;
import pers.junebao.simple_factory.phone.Phone;

public class PhoneFactory {
    /**
     * 一个用来产生 Phone 对象的工厂方法
     * @param name 根据 name 产生不同的 Phone 的子类对象
     * @return 返回实例化后的对象,name 不匹配返回 null
     */ 
    public static Phone getPhone(String name) {
        if(name.toLowerCase().equals("oneplus")){
            // TODO:使用简单工厂重构 
            CPU cpu = new Qualcomm();
            Camera camera = new Sony();
            return new OnePlus(cpu, camera);
        } else if (name.toLowerCase().equals("honor")) {
            CPU cpu = new Kirin();
            Camera camera = new Leica();
            return new Honor(cpu, camera);
        } else {
            return null;
        }
    }
}
package pers.junebao.simple_factory;

import pers.junebao.simple_factory.phone.Phone;

public class Consumer {
    public static void main(String[] args) {
        Phone phone = PhoneFactory.getPhone("Honor");
        assert phone != null;
        phone.printConfig();
    }
}

GitHub | 完整代码