工厂模式
1.简单工厂(不属于23种)
概念:简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例
实现:定义一个创建对象的类,由这个类来封装实例化对象的行为
应用场景:当我们会大量地创建某种、某类或者某批产品时,可以使用简单工厂模式
如图一,Pizza是一个抽象类,CheessPizza和GreekPizza为实现类,多个OrderPizza可以根据需求创建Pizza对象,然而这种做法在增加新的实现类时,我们要把每个OrderPizza的具体实现都重新更改,十分不合理
如图二,通过简单工厂的方式,我们可以将Pizza作为PizzaFactory的聚合对象,在Factory中调用方法统一创建Pizza对象实例然后返回,每个OrderPizza中聚合了一个Factory对象,直接根据用户输入来调用Factory中的方法来获取 Pizza对象,当增加新的Pizza实现类时,只需要修改Factory中的创建规则,不需要修改每一个OrderPizza
也可以将工厂中的方法定义为静态方法,这样OrderPizza可以直接调用PizzaFactory.getPizza()方法来创建披萨,看需求
2.工厂方法模式
思路:定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将都对象的实例化推迟到了子类
我们将简单工厂中的例子进阶,现在我们不仅有多个种类的披萨,还有多个地区,即北京披萨和天津披萨等,这里简单工厂便不再适用,采取如下的结构,BJOrderPizza和TJOrderPizza就类似于简单工厂,但它们继承于OrderPizza抽象类,该类为一个总的工厂,提供了一个创建pizza实例的抽象方法,由子类各自去实现
3.抽象工厂模式
概念:定义了一个interface用于创建相关或者有依赖关系的对象簇,而无需指明具体的类;可以将抽象工厂模式看成简单工厂和工厂方法的整合
如下,我们定义一个工厂接口,抽象工厂的好处在于还可以再生产更多的产品,创建好对应的产品,在Factory接口中定义多一个对应的方法,由子类实现,使用方的只需要聚合Factory接口,对应创建工厂实例,就可以创建产品对象;无论时增加新的厂商还是增加新的产品,只需要在提供方增加相应的类,在使用方都是调用Factory接口的方法来实现,则完美遵守开闭原则
- 当只有一种产品时,抽象工厂等于工厂方法,当有多种产品是就不再是工厂方法而是抽象工厂
JDK源码示例
简单工厂:Calender对象实例的创建使用了简单工厂
public static Calendar getInstance()
{
return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
}
private static Calendar createCalendar(TimeZone zone,
Locale aLocale)
{
.........................................................
//声明实例对象
Calendar cal = null;
//通过判断传入的后缀来决定创建的实例类型
if (aLocale.hasExtensions()) {
String caltype = aLocale.getUnicodeLocaleType("ca");
if (caltype != null) {
switch (caltype) {
case "buddhist":
cal = new BuddhistCalendar(zone, aLocale);
break;
case "japanese":
cal = new JapaneseImperialCalendar(zone, aLocale);
break;
case "gregory":
cal = new GregorianCalendar(zone, aLocale);
break;
}
}
}
.....................................
}
小结
-
工厂模式的意义
将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到项目解耦的目的,提高了项目的扩展性和可维护性
-
工厂模式的依赖抽象原则
- 创建对象实例时,不要直接new类,而是要在工厂的方法中new,即变量不要直接持有具体类的引用
- 不要让类直接继承具体类,而是要继承抽象类或者实现接口
- 不要覆盖基类中的方法