工厂(Factory)模式
# 工厂(Factory)模式
工厂模式(Factory Pattern)提供了一种创建对象的最佳方式。我们不必关心对象的创建细节,只需要根据不同情况获取不同产品即可。难点:写好我们的工厂
# 简单工厂 (Simple Factory)
只定义一个具体工厂,由该工厂判断生产哪个产品。
缺点:违背开闭,扩展不易

三个角色
Factory:工厂角色, WuLinFactory
/**
* 简单工厂
* 1.产品数量极少
*/
public class WuLinFactory {
//简单工厂一切从简
public AbstractCar newCar(String type) {
if ("van".equals(type)) {
return new VanCar();
} else if ("mini".equals(type)) {
return new MinCar();
}
return null;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Product:抽象产品角色,Car
/**
* 工厂产品
*/
public abstract class AbstractCar {
String engine;
public abstract void run();
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
ConcreteProduct:具体产品角色, VanCar、MiniCar
public class MinCar extends AbstractCar {
public MinCar() {
this.engine = "四缸发动机";
}
@Override
public void run() {
System.out.println(engine + "被生产");
}
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
public class VanCar extends AbstractCar {
public VanCar() {
this.engine = "单杠柴油机";
}
@Override
public void run() {
System.out.println(engine + "被生产");
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
测试方法:
public static void main(String[] args) {
WuLinFactory factory = new WuLinFactory();
AbstractCar van = factory.newCar("van");
AbstractCar mini = factory.newCar("mini");
AbstractCar qwq = factory.newCar("qwq");
van.run();
System.out.println(van);
mini.run();
System.out.println(mini);
System.out.println(qwq);
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 工厂方法 (Factory Method)
将工厂抽象化,定义多个生产工厂,每个工厂只负责自己生产的产品。
缺点:系统复杂度增加,产品单一

四个角色
Product:抽象产品
/**
* 工厂产品
*
* 怎么把一个功能提升一个层次:定义抽象(抽象类、接口)
* 抽象类,接口 就会有多实现 多实现自然有多功能
*/
public abstract class AbstractCar {
String engine;
public abstract void run();
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
ConcreteProduct:具体产品
三个具体产品
/**
* 继承工厂抽象产品 为一个具体的产品
*/
public class VanCar extends AbstractCar {
public VanCar() {
this.engine = "单杠柴油机";
}
@Override
public void run() {
System.out.println(engine + "被生产");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
public class MiniCar extends AbstractCar {
public MiniCar() {
this.engine = "四缸发动机";
}
@Override
public void run() {
System.out.println(engine + "被生产");
}
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
public class RacingCar extends AbstractCar {
public RacingCar() {
this.engine = "V8发动机";
}
@Override
public void run() {
System.out.println(engine + "被生产");
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
Factory:抽象工厂
将生产方法抽象化
public abstract class AbstractCarFactory {
public abstract AbstractCar newCar();
}
1
2
3
4
2
3
4
ConcreteFactory:具体工厂
有多少个产品就有多少个工厂
public class WulinMiniCarFactory extends AbstractCarFactory{
@Override
public AbstractCar newCar() {
return new MiniCar();
}
}
1
2
3
4
5
6
2
3
4
5
6
public class WulinRacingCarFactory extends AbstractCarFactory{
@Override
public AbstractCar newCar() {
return new RacingCar();
}
}
1
2
3
4
5
6
2
3
4
5
6
public class WulinVanCarFactory extends AbstractCarFactory{
@Override
public AbstractCar newCar() {
return new VanCar();
}
}
1
2
3
4
5
6
2
3
4
5
6
测试类
public static void main(String[] args) {
AbstractCarFactory carFactory = new WulinRacingCarFactory();
AbstractCar abstractCar = carFactory.newCar();
abstractCar.run();
carFactory = new WulinMiniCarFactory();
AbstractCar abstractCar1 = carFactory.newCar();
abstractCar1.run();
carFactory = new WulinVanCarFactory();
AbstractCar abstractCar2 = carFactory.newCar();
abstractCar2.run();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 抽象工厂 (Abstract Factory)


将工厂抽象化 抽象方法为生产抽象类别,需要什么产品就创建什么工厂来生成。
抽象产品族:即抽象类别
public abstract class AbstractCar {
String engine;
public abstract void run();
}
1
2
3
4
5
6
2
3
4
5
6
public abstract class AbstractMask {
Integer price;
public abstract void protecteMe();
}
1
2
3
4
5
6
2
3
4
5
6
产品等级结构:生具体产品族的具体产品
public class MiniCar extends AbstractCar {
public MiniCar() {
this.engine = "四缸发动机";
}
@Override
public void run() {
System.out.println(engine + "被生产");
}
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
public class VanCar extends AbstractCar {
public VanCar() {
this.engine = "单杠柴油机";
}
@Override
public void run() {
System.out.println(engine + "被生产");
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
public class N95Mask extends AbstractMask {
public N95Mask() {
this.price = 2;
}
@Override
public void protecteMe() {
System.out.println("N95口罩被生产 价位为" + price);
}
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
public class CommonMask extends AbstractMask {
public CommonMask() {
this.price = 1;
}
@Override
public void protecteMe() {
System.out.println("普通口罩被生成 价格为" + price);
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
总厂规范:工厂全部产品族
可以再次细分工厂产品族,不生成的类别返回 null,生成的类别为抽象(abstract)方法,让生成工厂实现单一类别的生成产品。
/**
* 总厂规范
*/
public abstract class WulinFactory {
abstract AbstractCar newCar();
abstract AbstractMask newMask();
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
生成工厂:生成指定产品族的指定产品
public class WulinMiniCarFatory extends WulinFactory {
@Override
protected AbstractCar newCar() {
return new MiniCar();
}
@Override
AbstractMask newMask() {
return null;
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
public class WulinVanCarFatory extends WulinFactory {
@Override
protected AbstractCar newCar() {
return new VanCar();
}
@Override
AbstractMask newMask() {
return null;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
public class WulinN95MaskFactory extends WulinFactory{
@Override
protected AbstractCar newCar() {
return null;
}
@Override
AbstractMask newMask() {
return new N95Mask();
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
public class WulinCommonMaskFactory extends WulinFactory{
@Override
protected AbstractCar newCar() {
return null;
}
@Override
AbstractMask newMask() {
return new CommonMask();
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
测试方法:
public static void main(String[] args) {
WulinFactory wulinFactory = new WulinCommonMaskFactory();
AbstractMask commonMask = wulinFactory.newMask();
commonMask.protecteMe(); //只生成普通口罩
wulinFactory = new WulinN95MaskFactory();
AbstractMask N95 = wulinFactory.newMask();
N95.protecteMe(); //生成N95
wulinFactory = new WulinMiniCarFatory();
AbstractCar miniCar = wulinFactory.newCar();
miniCar.run();
wulinFactory = new WulinVanCarFatory();
AbstractCar vanCar = wulinFactory.newCar();
vanCar.run();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 工厂模式的退化
- 当抽象工厂模式中每一个具体工厂类只创建一个产品对象,也就是只存在一个产品等级结构时,抽象工厂模式退化成工厂方法模式;当工厂方法模式中抽象工厂与具体工厂合并,提供一个统一的工厂来创建产品对象,并将创建对象的工厂方法设计为静态方法时,工厂方法模式退化成简单工厂模式。
# 应用场景
- NumberFormat、SimpleDateFormat
- LoggerFactory:
- SqlSessionFactory:MyBatis
- BeanFactory:Spring 的 BeanFactory(就是为了造出 bean)
JDK 中的 Calendar 类中,就使用了简单工厂模式
import java.util.Calendar;
public class Factory {
public static void main(String[] args) {
// TODOAuto-generated method stub
// getInstance 是 Calendar 静态方法
Calendar cal = Calendar.getInstance();
// 注意月份下标从 0 开始,所以取月份要+1
System.out.println("年:" + cal.get(Calendar.YEAR));
System.out.println("月:" + (cal.get(Calendar.MONTH) + 1));
System.out.println("日:" + cal.get(Calendar.DAY_OF_MONTH));
System.out.println("时:" + cal.get(Calendar.HOUR_OF_DAY));
System.out.println("分:" + cal.get(Calendar.MINUTE));
System.out.println("秒:" + cal.get(Calendar.SECOND));
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Calendar.java
package com.atguigu.jdk;
import java.util.Calendar;
public class Factory {
public static void main(String[] args) {
// TODOAuto-generated method stub
// getInstance 是 Calendar 静态方法
Calendar cal = Calendar.getInstance();
// 注意月份下标从 0 开始,所以取月份要+1
System.out.println("年:" + cal.get(Calendar.YEAR));
System.out.println("月:" + (cal.get(Calendar.MONTH) + 1));
System.out.println("日:" + cal.get(Calendar.DAY_OF_MONTH));
System.out.println("时:" + cal.get(Calendar.HOUR_OF_DAY));
System.out.println("分:" + cal.get(Calendar.MINUTE));
System.out.println("秒:" + cal.get(Calendar.SECOND));
}
}
public static Calendar getInstance() {
return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
}
private static Calendar createCalendar(TimeZone zone,
Locale aLocale) { //根据 TimeZone zone, locale 创建对应的实例
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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# 工厂模式小结
- 工厂模式的意义将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系的解耦。从而提高项目的扩展和维护性。
- 三种工厂模式 (简单工厂模式、工厂方法模式、抽象工厂模式)
- 设计模式的依赖抽象原则
- 创建对象实例时,不要直接 new 类,而是把这个 new 类的动作放在一个工厂的方法中,并返回。有的书上说,变量不要直接持有具体类的引用。
- 不要让类继承具体类,而是继承抽象类或者是实现 interface (接口)
- 不要覆盖基类中已经实现的方法。
编辑 (opens new window)
上次更新: 2023/12/13, 06:06:02