|
|
|
---
|
|
|
|
工厂方法模式
|
|
|
|
---
|
|
|
|
|
|
|
|
#### 目录
|
|
|
|
|
|
|
|
1. 思维导图
|
|
|
|
2. 概述
|
|
|
|
3. 三种实现方式
|
|
|
|
- 简单工厂模式
|
|
|
|
- 工厂方法模式
|
|
|
|
- 抽象工厂模式
|
|
|
|
4. 应用
|
|
|
|
|
|
|
|
#### 思维导图
|
|
|
|
|
|
|
|
#### 概述
|
|
|
|
|
|
|
|
工厂模式,也是创建型设计模式之一,它提供了一种创建对象的最佳方式。
|
|
|
|
|
|
|
|
在任何需要生成复杂对象的地方,都可以使用工厂模式。复杂对象适用工厂模式,用 new 就可以完成创建的对象无需使用工厂模式。
|
|
|
|
|
|
|
|
#### 实现方式
|
|
|
|
|
|
|
|
##### 简单工厂模式
|
|
|
|
|
|
|
|
我们写一个试图解析文件的例子。
|
|
|
|
|
|
|
|
```java
|
|
|
|
public interface IFileParse {
|
|
|
|
String parse();
|
|
|
|
}
|
|
|
|
|
|
|
|
public class JsonFileParse implements IFileParse {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String parse() {
|
|
|
|
return "Json";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public class XmlFileParse implements IFileParse {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String parse() {
|
|
|
|
return "Xml";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public class FileParseFactory {
|
|
|
|
|
|
|
|
public IFileParse createFileParse(String name) {
|
|
|
|
if ("xml".equals(name)) {
|
|
|
|
return new XmlFileParse();
|
|
|
|
} else if ("json".equals(name)) {
|
|
|
|
return new JsonFileParse();
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public class Resources {
|
|
|
|
|
|
|
|
public String parse(String name) {
|
|
|
|
IFileParse fileParse = new FileParseFactory().createFileParse(name);
|
|
|
|
if (fileParse != null) {
|
|
|
|
return fileParse.parse();
|
|
|
|
}
|
|
|
|
throw new InvalidParameterException();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
这个就是一个简单工厂方法的写法,不过呢,每次调用 createFileParse 都会创建一个新的 FileParse 类。实际上,如果 FileParse 可以复用,为了节省内存和对象创建的时间,我们可以把 FileParse 缓存起来。
|
|
|
|
|
|
|
|
具体写法就是:
|
|
|
|
|
|
|
|
```java
|
|
|
|
public class FileParseFactory {
|
|
|
|
|
|
|
|
private static HashMap<String, IFileParse> hashMap = new HashMap<>(4);
|
|
|
|
|
|
|
|
static {
|
|
|
|
hashMap.put("xml", new XmlFileParse());
|
|
|
|
hashMap.put("json", new JsonFileParse());
|
|
|
|
}
|
|
|
|
|
|
|
|
public IFileParse createFileParse(String name) {
|
|
|
|
return hashMap.get(name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
##### 工厂方法模式
|
|
|
|
|
|
|
|
```java
|
|
|
|
public class FileParseFactory {
|
|
|
|
|
|
|
|
public interface IFileParseFactory {
|
|
|
|
|
|
|
|
IFileParse createFileParse();
|
|
|
|
}
|
|
|
|
|
|
|
|
public class XmlFileParseFactory implements IFileParseFactory {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public IFileParse createFileParse() {
|
|
|
|
return new XmlFileParse();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public class JsonFileParseFactory implements IFileParseFactory {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public IFileParse createFileParse() {
|
|
|
|
return new JsonFileParse();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public IFileParse createFileParse(String name) {
|
|
|
|
if (name.equals("xml")) {
|
|
|
|
return new XmlFileParseFactory().createFileParse();
|
|
|
|
} else if (name.equals("json")) {
|
|
|
|
return new JsonFileParseFactory().createFileParse();
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
就是为每个 FileParse 在创建一个对应的 Factory,但是用到它时仅仅只是 new 创建了一个对象而已,这样写反而增加了复杂性,而且需要创建诸多的 Factory 类。在这个设计场景中,其实完全没有必要,简单工厂模式简单好用,比工厂方法更加适用。
|
|
|
|
|
|
|
|
那么时候该用工厂方法模式,而非简单工厂模式呢?
|
|
|
|
|
|
|
|
当对象的创建逻辑比较复杂,而不是简单的 new 一下就可以,而是要组合其他类对象,做各种初始化操作的时候,我们推荐使用工厂方法模式,将复杂的创建逻辑拆分到多个工厂类中,让每个工厂类都不至于过于复杂。而使用简单工厂模式,将所有的创建逻辑都放到一个工厂类中,会导致这个工厂类变得很复杂。
|
|
|
|
|
|
|
|
##### 抽象工厂模式
|
|
|
|
|
|
|
|
抽象工厂模式的应用场景比较特殊,没有前两种常用,所以不作为重点,简单了解一下就行了。
|
|
|
|
|
|
|
|
#### 应用
|
|
|
|
|
|
|
|
在 Android 中,BitampFactory 用到了简单工厂模式,因为会根据的不同类型去创建 Bitmap。
|
|
|
|
|
|
|
|
```java
|
|
|
|
public class BitmapFactory {
|
|
|
|
|
|
|
|
public static Bitmap decodeFile(String pathName, Options opts) {
|
|
|
|
//...
|
|
|
|
}
|
|
|
|
|
|
|
|
public static Bitmap decodeResource() {
|
|
|
|
//...
|
|
|
|
}
|
|
|
|
|
|
|
|
public static Bitmap decodeByteArray() {
|
|
|
|
//...
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|