Update 工厂模式.md

master
Omooo 4 years ago
parent 6e7b4b9709
commit 7164e09415
  1. 157
      blogs/DesignMode/工厂模式.md

@ -10,6 +10,7 @@
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
4. 应用
#### 思维导图
@ -23,102 +24,138 @@
##### 简单工厂模式
我们写一个试图解析文件的例子。
```java
//定义抽象产品类
public abstract class Product {
public abstract void method();
public interface IFileParse {
String parse();
}
```
```java
//定义具体产品
public class ProductA extends Product {
public class JsonFileParse implements IFileParse {
@Override
public void method() {
System.out.println("产品A");
public String parse() {
return "Json";
}
}
public class ProductB extends Product {
public class XmlFileParse implements IFileParse {
@Override
public void method() {
System.out.println("产品B");
public String parse() {
return "Xml";
}
}
```
```java
//定义一个工厂用来生产产品
public class Factory {
public static Product createProduct(String type) {
switch (type) {
case "A":
return new ProductA();
case "B":
return new ProductB();
default:
return null;
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;
}
}
```
```java
//客户端根据传入的参数生成不同的产品
public class Client {
public static void main(String[] args) {
ProductA productA = (ProductA) Factory.createProduct("A");
if (productA != null) {
productA.method();
} else {
System.out.println("不存在产品A");
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 abstract class Factory {
public abstract Product createProduct();
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 FactoryA extends Factory {
public class FileParseFactory {
public interface IFileParseFactory {
IFileParse createFileParse();
}
public class XmlFileParseFactory implements IFileParseFactory {
@Override
public Product createProduct() {
return new ProductA();
public IFileParse createFileParse() {
return new XmlFileParse();
}
}
public class FactoryB extends Factory {
}
public class JsonFileParseFactory implements IFileParseFactory {
@Override
public Product createProduct() {
return new ProductB();
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 Client {
public static void main(String[] args) {
Factory factory = new FactoryA();
ProductA productA = (ProductA) factory.createProduct();
productA.method();
public class BitmapFactory {
new FactoryB().createProduct().method();
public static Bitmap decodeFile(String pathName, Options opts) {
//...
}
}
```
缺点也是显而易见的,一个工厂只能生产一种产品,而且每一个产品都必须对应一个工厂,系统类成对增加,在一定程度上增加了系统的复杂度。
public static Bitmap decodeResource() {
//...
}
##### 抽象工厂模式
public static Bitmap decodeByteArray() {
//...
}
}
```

Loading…
Cancel
Save