You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
android-notes/blogs/DesignMode/工厂模式.md

162 lines
4.2 KiB

---
工厂方法模式
---
#### 目录
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() {
//...
}
}
```