创建型-工厂模式
# 简单工厂(Simple Factory)
- 应用多态或设计模式来替代 if 分支判断逻辑,也并不是没有任何缺点的,它虽然提高了代码的扩展性,更加符合开闭原则,但也增加了类的个数,牺牲了代码的可读性。
- 简单工厂模式看作是工厂方法模式的一种特例。
public class RuleConfigSource {
public RuleConfig load(String ruleConfigFilePath) {
String ruleConfigFileExtension = getFileExtension(ruleConfigFilePath);
IRuleConfigParser parser = null;
if ("json".equalsIgnoreCase(ruleConfigFileExtension)) {
parser = new JsonRuleConfigParser();
} else if ("xml".equalsIgnoreCase(ruleConfigFileExtension)) {
parser = new XmlRuleConfigParser();
} else if ("yaml".equalsIgnoreCase(ruleConfigFileExtension)) {
parser = new YamlRuleConfigParser();
} else if ("properties".equalsIgnoreCase(ruleConfigFileExtension)) {
parser = new PropertiesRuleConfigParser();
} else {
throw new InvalidRuleConfigException(
"Rule config file format is not supported: " + ruleConfigFilePath);
}
String configText = "";
//从ruleConfigFilePath文件中读取配置文本到configText中
RuleConfig ruleConfig = parser.parse(configText);
return ruleConfig;
}
private String getFileExtension(String filePath) {
//...解析文件名获取扩展名,比如rule.json,返回json
return "json";
}
}
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
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
# 工厂方法
- 工厂方法模式比起简单工厂模式更加符合开闭原则。
- 为工厂类再创建一个简单工厂,也就是工厂的工厂,用来创建工厂类对象。
- 基于这个设计思想,当对象的创建逻辑比较复杂,不只是简单的 new 一下就可以,而是要组合其他类对象,做各种初始化操作的时候,我们推荐使用工厂方法模式。
- 将复杂的创建逻辑拆分到多个工厂类中,让每个工厂类都不至于过于复杂。
public interface IRuleConfigParserFactory {
IRuleConfigParser createParser();
}
public class JsonRuleConfigParserFactory implements IRuleConfigParserFactory {
@Override
public IRuleConfigParser createParser() {
return new JsonRuleConfigParser();
}
}
public class XmlRuleConfigParserFactory implements IRuleConfigParserFactory {
@Override
public IRuleConfigParser createParser() {
return new XmlRuleConfigParser();
}
}
public class YamlRuleConfigParserFactory implements IRuleConfigParserFactory {
@Override
public IRuleConfigParser createParser() {
return new YamlRuleConfigParser();
}
}
public class PropertiesRuleConfigParserFactory implements IRuleConfigParserFactory {
@Override
public IRuleConfigParser createParser() {
return new PropertiesRuleConfigParser();
}
}
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
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
# 抽象工厂
- 我们可以让一个工厂负责创建多个不同类型的对象(IRuleConfigParser、ISystemConfigParser 等),而不是只创建一种 parser 对象。这样就可以有效地减少工厂类的个数。
# 代码
public interface IConfigParserFactory {
IRuleConfigParser createRuleParser();
ISystemConfigParser createSystemParser();
//此处可以扩展新的parser类型,比如IBizConfigParser
}
public class JsonConfigParserFactory implements IConfigParserFactory {
@Override
public IRuleConfigParser createRuleParser() {
return new JsonRuleConfigParser();
}
@Override
public ISystemConfigParser createSystemParser() {
return new JsonSystemConfigParser();
}
}
public class XmlConfigParserFactory implements IConfigParserFactory {
@Override
public IRuleConfigParser createRuleParser() {
return new XmlRuleConfigParser();
}
@Override
public ISystemConfigParser createSystemParser() {
return new XmlSystemConfigParser();
}
}
// 省略YamlConfigParserFactory和PropertiesConfigParserFactory代码
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
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
# 对应 UML
# 工厂设计模式的思考
# 使用工厂模式的场景
- 封装变化:创建逻辑有可能变化,封装成工厂类之后,创建逻辑的变更对调用者透明。
- 代码复用:创建代码抽离到独立的工厂类之后可以复用。
- 隔离复杂性:封装复杂的创建逻辑,调用者无需了解如何创建对象。
- 控制复杂度:将创建代码抽离出来,让原本的函数或类职责更单一,代码更简洁。
# 简单工厂和工厂方法差异?
- 工厂方法只会返回一种类型的实例,最好具有父类或者共同实现的接口。
- 简单工厂:用来生产同一等级结构的任意产品(对于任意新增的产品,无能为力)
- 工厂方法:用来生产同一等级结构中的固定产品(支持增加任意产品)
- 抽象工厂:用来生产不同产品族的全部产品。(对于新增的产品,无能为力,只是多种实现定义好的产品生成,实例的组合,支持添加产品族,就是产品的下线由谁生产,但是生产什么是事先固定好的)
# 工厂方法和抽象工厂差异?
- 抽象工厂关键在于产品之间的抽象关系,所以至少要两个产品,工厂方法在于生成产品,不关注产品键的关系,所以可以只生成一个产品。
- 抽象工厂中客户端把产品的抽象关系理清楚,在最终使用的时候,一般使用客户端和(其接口),产品之间的关系是被封装固定的;而工厂方法是在最终使用的时候,使用产品本身。
- 抽象工厂更像一个复杂版本的策略模式,策略模式通过更换策略来改变处理方式或者结果,而抽象工厂的客户端,通过更改工厂来改变结果,所以在使用的时候,就使用客户端和更换工厂,而看不到产品本身。
- 工厂方法的目的是生产商品,所以能看到商品,而且还是要使用商品,当然如果产品在创建者内部使用,那么工厂方法就是为了完善创建者,从而可以使用创建者,另外创建者本身是不能更换所生成的产品的。
- 抽象工厂的工厂是类,工厂方法的工厂是方法。
上次更新: 2020/09/08, 15:09:00