一 简单工厂模式
1.1 基本介绍
- 简单工厂模式是属于
创建型模式
,是工厂模式的一种。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例
。简单工厂模式是工厂模式家族中最简单实用的模式 - 简单工厂模式:定义了一个
创建对象的类
,由这个类来封装实例化对象的行为
(代码) - 在软件开发中,当我们会用到大量的创建
某种、某类或者某批对象
时,就会使用到工厂模式.
1.2 实现
普通方法
//orderType 返回对应的Pizza 对象
public Pizza createPizza(String orderType) {
Pizza pizza = null;
System.out.println("使用简单工厂模式");
if (orderType.equals("greek")) {
pizza = new GreekPizza();
pizza.setName(" 希腊披萨 ");
} else if (orderType.equals("cheese")) {
pizza = new CheesePizza();
pizza.setName(" 奶酪披萨 ");
} else if (orderType.equals("pepper")) {
pizza = new PepperPizza();
pizza.setName("胡椒披萨");
}
return pizza;
}
静态方法
//简单工厂模式 也叫 静态工厂模式
public static Pizza createPizza2(String orderType) {
Pizza pizza = null;
System.out.println("使用简单工厂模式2");
if (orderType.equals("greek")) {
pizza = new GreekPizza();
pizza.setName(" 希腊披萨 ");
} else if (orderType.equals("cheese")) {
pizza = new CheesePizza();
pizza.setName(" 奶酪披萨 ");
} else if (orderType.equals("pepper")) {
pizza = new PepperPizza();
pizza.setName("胡椒披萨");
}
return pizza;
}
1.3 小结
- 为什么要用工厂模式?
因为传统的实现,如果一个父类想扩展新的实现。如果类的实例化过程都是放在调用类内部
的话。就需要对所有的调用类代码都进行代码调整
而如果将实例化过程放在一个工厂类中,那么我们只需要修改
工厂类(或者新的实现,开闭原则
).就可以完成代码的调整。
提高了代码的可扩展性。 - 自己的体会
其实自己写代码也会用到这种思想。就是将某一类相似的代码都封装到一个方法中·。然后其他地方都是掉这个方法,这样如果有改动就会方便修改
- 什么情况下用工厂模式?
首先不可能什么地方都用。但既然目的时为了便于扩展
。
那我觉得就应该是用在一些本来就想要别人来扩展
(经常会扩展)/想要简化别人的创建流程
(创建流程比较麻烦或特俗,也可以结合单例模式)等等场景
二 工厂方法模式
2.1 基本介绍
- 工厂方法模式设计方案:将
披萨项目的实例化功能抽象成抽象方法
,在不同的口味点餐子类中具体实现。 - 工厂方法模式:定义了一个
创建对象的抽象方法
,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类
。
2.2 案例类图

2.3 小结
感觉这里不是很清晰,就是将工厂的创建方法设置成抽象的,由子类来实现。便于子类工厂扩展。
三 抽象工厂模式
3.1 基本介绍
- 抽象工厂模式:定义了
一个 interface
用于创建相关或有依赖关系的对象簇,而无需指明具体的类
- 抽象工厂模式可以将简单工厂模式和工厂方法模式进行
整合
。 - 从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为
进一步的抽象
)。 - 将工厂抽象成
两层
,AbsFactory(抽象工厂)
和 具体实现的工厂子类
。程序员可以根据创建对象类型使用对应 的工厂子类
。这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展。
3.2 示例的类图

3.3 小结
这个感觉和前面的工厂方法模式差不多,都是抽象
,不过一个是继承,一个是实现.
反正就是为了方便扩展,我们需要对一些工厂类进行抽象,由子类自己去实现。
四 jdk应用
最常用的Calendar肯定不陌生
public static Calendar getInstance()
{
return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
}
...
private static Calendar createCalendar(TimeZone zone,
Locale aLocale)
{
CalendarProvider provider =
LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale)
.getCalendarProvider();
if (provider != null) {
try {
return provider.getInstance(zone, aLocale);
} catch (IllegalArgumentException iae) {
// fall back to the default instantiation
}
}
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;
}
}
}
if (cal == null) {
// If no known calendar type is explicitly specified,
// perform the traditional way to create a Calendar:
// create a BuddhistCalendar for th_TH locale,
// a JapaneseImperialCalendar for ja_JP_JP locale, or
// a GregorianCalendar for any other locales.
// NOTE: The language, country and variant strings are interned.
if (aLocale.getLanguage() == "th" && aLocale.getCountry() == "TH") {
cal = new BuddhistCalendar(zone, aLocale);
} else if (aLocale.getVariant() == "JP" && aLocale.getLanguage() == "ja"
&& aLocale.getCountry() == "JP") {
cal = new JapaneseImperialCalendar(zone, aLocale);
} else {
cal = new GregorianCalendar(zone, aLocale);
}
}
return cal;
}
五 总结
- 工厂模式的意义 将实例化对象的代码
提取出来
,放到一个类中统一管理和维护
,达到和主项目的依赖关系的解耦
。从而提高项目的扩展和维护性。 - 三种工厂模式 (简单工厂模式、工厂方法模式、抽象工厂模式)
- 设计模式的依赖抽象原则
- 创建对象实例时,不要直接 new 类, 而是把这个 new 类的动作放在一个工厂的方法中,并返回。有的书上说, 变量不要直接持有具体类的引用。
- 不要让类
继承具体类
,而是继承抽象类或者是实现 interface(接口)
- 不要
覆盖基类中已经实现
的方法。
网友评论