人的知识就好比一个圆圈,圆圈里面是已知的,圆圈外面是未知的。你知道得越多,圆圈也就越大,你不知道的也就越多。

0%

设计模式--工厂模式

简单工厂方法

简单工厂方法不是一个设计模式,更像是一种编程习惯。

类图

SimpleFactory UML

实现

1
2
3
4
5
6
7
8
9
10
11
12
public class SimpleFactory {

public static Product create(String type) {
if ("A".equals(type)) {
return new ProjectA();
} else if ("B".equals(type)) {
return new ProjectB();
} else{
throw new RuntimeException("不支持该类产品的创建");
}
}
}

工厂方法模式

定义

工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。

类图

Factory UML

实现

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
public interface Factory {

Product create(String type);
}

public class FactoryA implements Factory {

public Product create(String type) {
if ("A".equals(type)) {
return new ProjectA();
} else{
throw new RuntimeException("不支持该类产品的创建");
}
}
}

public class FactoryB implements Factory {

public Product create(String type) {
if ("B".equals(type)) {
return new ProjectB();
} else{
throw new RuntimeException("不支持该类产品的创建");
}
}
}

抽象工厂模式

定义

抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确执行具体类。

类图

AbstractFactory UML

实现

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
public interface Factory {

ProductA createProductA(String type);

ProductB createProductB(String type);
}

public class FactoryA implements Factory {

public ProductA createProductA(String type) {
if ("1".equals(type)) {
return new ProductA1();
} else{
throw new RuntimeException("不支持该类产品的创建");
}
}

public ProductB createProductB(String type) {
if ("1".equals(type)) {
return new ProductB1();
} else{
throw new RuntimeException("不支持该类产品的创建");
}
}
}

public class FactoryB implements Factory {

public ProductA createProductA(String type) {
if ("2".equals(type)) {
return new ProductA2();
} else{
throw new RuntimeException("不支持该类产品的创建");
}
}

public ProductB createProductB(String type) {
if ("2".equals(type)) {
return new ProductB2();
} else{
throw new RuntimeException("不支持该类产品的创建");
}
}
}

小结

  • 所有的工厂都是用来封装对象的创建
  • 工厂方法使用继承:把对象的创建委托给子类,子类实现工厂方法来创建对象
  • 工厂方法允许类将实例化延迟到子类中执行

模式应用

ThreadFactory

在使用线程池时,我们可以传递ThreadFactory参数到ThreadPoolExecutor构造函数中,这样就可以方便的设置从池中获取到的线程的名字等属性。在Executors中提供了默认实现:

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
public class Executors {

...

static class DefaultThreadFactory implements ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;

DefaultThreadFactory() {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
namePrefix = "pool-" +
poolNumber.getAndIncrement() +
"-thread-";
}

public Thread newThread(Runnable r) {
Thread t = new Thread(group, r,
namePrefix + threadNumber.getAndIncrement(),
0);
if (t.isDaemon())
t.setDaemon(false);
if (t.getPriority() != Thread.NORM_PRIORITY)
t.setPriority(Thread.NORM_PRIORITY);
return t;
}
}

...

}

Spring IoC

BeanFactory

实际应用

根据页面类型决定使用哪一个PageDataBuilder构建页面数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class PageDataBuilderFactory {

public static PageDataBuilder getPageDataBuilder(String pageType) {
PageTypeEnum pageTypeEnum;
try {
pageTypeEnum = PageTypeEnum.valueOfName(pageType);
} catch (Exception e) {
throw new RuntimeException(String.format("尚未支持该页面类型:%s", pageType));
}

switch (pageTypeEnum) {
case LIST_PAGE:
return new ListPageDataBuilder();
case CARD_PAGE:
return new CardPageDataBuilder();
default:
throw new RuntimeException(String.format("尚未支持该页面类型:%s", pageTypeEnum.getName()));
}
}
}
小礼物走一走,来 Github 关注我