diff --git a/blogs/DesignMode/工厂模式.md b/blogs/DesignMode/工厂模式.md index 812e302..e8fb1fa 100644 --- a/blogs/DesignMode/工厂模式.md +++ b/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 { -```java -//具体的工厂,生产不同的产品 -public class FactoryA extends Factory { - @Override - public Product createProduct() { - return new ProductA(); + private static HashMap hashMap = new HashMap<>(4); + + static { + hashMap.put("xml", new XmlFileParse()); + hashMap.put("json", new JsonFileParse()); } -} -public class FactoryB extends Factory { - @Override - public Product createProduct() { - return new ProductB(); + + public IFileParse createFileParse(String name) { + return hashMap.get(name); } } ``` +##### 工厂方法模式 + ```java -//用户决定要生产哪个产品 -public class Client { - public static void main(String[] args) { - Factory factory = new FactoryA(); - ProductA productA = (ProductA) factory.createProduct(); - productA.method(); - - new FactoryB().createProduct().method(); +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() { + //... + } +} +``` +