设计模式系列
创建型设计模式
Java 设计模式之静态工厂、工厂方法、抽象工厂和 Builder 模式的区别
结构型设计模式
写在前面
先来一个迟到的祝福,祝大家中秋节快乐!应个景吧,工厂模式系列的例子和代码,将以 “月饼” 为主题进行。
工厂模式细分起来,分为三种:静态工厂方法模式、工厂方法模式、抽象工厂方法模式。本文我们先来了解最简单的静态工厂方法模式。
定义
静态工厂方法模式,又称为 简单工厂模式,属于创建型设计模式,但不属于 GOF 提出的 23 种设计模式之一。这种形式的工厂模式,是最常用,也最简单、最容易理解的工厂模式,其是由一个工厂类对象决定创建哪一种产品类的实例。
示例
场景
来我们来考虑一个场景:
1、小A有一家月饼工厂,叫做 MooncakesFactory
2、月饼有 五仁月饼 FiveKernel
、豆沙月饼 Beansand
等
3、我们抽象出月饼的产品抽象类 Mooncakes
,拥有“吃”的行为(当然,应该是人吃月饼,而不是月饼吃自己,这里为了好理解,就将吃的行为赋给了月饼)。
4、当想要某种类型的月饼时,通过工厂类得到相应的月饼类即可进行生产
UML类图
让我来看下它们的 UML 类图吧,如图 1 :
程序代码
下面我们阅读下程序代码。
public abstract class Mooncakes{
abstract void eat();
}
可以看到,抽象类 Mooncakes
简单的抽象了一种行为,就是吃月饼 eat()
。
public class FiveKernel extends Mooncakes{
@Override
public void eat() {
System.out.println("吃一个五仁月饼");
}
}
public class Beansand extends Mooncakes{
@Override
public void eat() {
System.out.println("吃一个豆沙月饼");
}
}
下面我们来看下工厂类的代码:
public class MooncakesFactory {
public static Mooncakes makeMooncakes(String type) {
Mooncakes mooncakes = null;
switch (type) {
case "FiveKernel":
mooncakes = new FiveKernel();
break;
case "Beansand":
mooncakes = new Beansand();
break;
}
return mooncakes;
}
}
当想要某种类型的月饼时,通过工厂类得到相应的月饼类,即可开始生产。
这就通过工厂,实现了对产品类实例的管理。
那么,如果有了一种的新的月饼类型,比如蛋黄月饼,那么我们需要扩展一个新类 Yolk
继承抽象产品类 Mooncakes
,同时还需要对工厂类 MooncakesFactory
进行修改,以便适应新的月饼类型(int type
)。
我们知道,我们的程序应该“ 面向扩展开放,面向修改关闭 ”,我们对工厂类的修改自然是不符合" 开闭原则 " 的,让我们用反射对工厂类进行优化吧:
public class MooncakesFactory {
public static <T extends Mooncakes> T makeMooncakes(Class<T> clz) {
Mooncakes mooncakes = null;
try {
mooncakes = (Mooncakes) Class.forName(clz.getName()).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return (T) mooncakes;
}
}
这样,无论我们扩展多少种月饼类型,只需要将相应的月饼类注入工厂的 makeMooncakes()
方法即可,不需要再对工厂类的代码进行修改。
最后,我们在主函数中调用工厂得到月饼类的实例,即可开始生产。
public class Main {
public static void main(String[] args) {
MooncakesFactory.makeMooncakes(FiveKernel.class).eat();
MooncakesFactory.makeMooncakes(Beansand.class).eat();
}
}
结果示例,如图 2 :
总结
至此,静态工厂方法模式基本就聊完了。
大家会发现,这种模式十分简单,优点也是十分明显:
用户只需要关心自己想要什么类型的产品对象,而对产品对象的创建过程无须关心,全部交给工厂来做,降低了用户与产品类的耦合,也便于对产品的类型进行扩展。
然而,正如前文所说,“ 静态工厂方法模式 ” 不属于 GOF 提出的 23 种设计模式之一,“ 工厂方法模式 ” 则包含其中,让我们移步下一讲,一起学习下 Java 设计模式之工厂方法模式 吧!
另外,源码也有放在 Gihub 上:StaticFactoryPattern
感谢
- 《Android源码设计模式解析与实战》 何红辉 关爱民
- 《Android进阶之光》 刘望舒