通过传给工厂类的参数的不同,返回不同的对象
简单工厂模式
2020 / 4 / 30 参考:
- CSDN|简单工厂模式
简单工厂通过传给工厂类的参数的不同,返回不同的对象,包括三部分组成:
- 具体的”产品“
- 工厂类(实例化并返回”产品“)
- 客户端(使用”产品“)
为什么使用简单工厂:
- ”产品“的创建过程可能很复杂,涉及到多个不同类之间的依赖,通过简单工厂将创建过程隐藏在工厂类中,一方面减轻了客户端使用该产品的难度,另一方面也防止了客户端错误创建产品造成的安全问题。
- 将产品的生产和消费过程分离开,这样如果要有了一个新的产品,只需要把它加入到工厂类中,客户端需要时工厂类就会返回给它,否则的话,每次添加一个新的产品,都需要修改客户端代码,违反开闭原则。
简单工厂的缺点:
- 系统过度依赖工厂类,工厂类作为一个”上帝类“,负责创建客户端需要的所有对象,导致一旦工厂类出错,整个系统就会崩溃。
- 如果”产品类“特别多,工厂类中就会有很多个分支,造成工厂类异常庞大,难以维护。
- 每次添加新的产品都要修改工厂类,从工厂类的角度看违反了”开闭原则“,也不利于系统拓展。
- 工厂方法一般是静态方法,不利于继承。
适用场景
1、工厂类负责创建的对象比较少:由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。
2、客户端只知道传入工厂类的参数,对于如何创建对象不关心:客户端既不需要关心创建细节,甚至连类名都不需要记住,只需要知道类型所对应的参数。
例:
如果需要获取不同的手机对象,就可以使用简单工厂,具体的手机对象依赖于CPU, Camera等,通过简单工厂的封装,客户端获取 Phone 对象时就不需要了解具体的 ”生产过程“了.
代码语言:javascript复制实例化CPU, Camera 等配件时,也应该使用简单工厂。
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;
}
}
}
代码语言:javascript复制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 | 完整代码