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

4.2 KiB

工厂方法模式

目录

  1. 思维导图
  2. 概述
  3. 三种实现方式
    • 简单工厂模式
    • 工厂方法模式
    • 抽象工厂模式
  4. 应用

思维导图

概述

工厂模式,也是创建型设计模式之一,它提供了一种创建对象的最佳方式。

在任何需要生成复杂对象的地方,都可以使用工厂模式。复杂对象适用工厂模式,用 new 就可以完成创建的对象无需使用工厂模式。

实现方式

简单工厂模式

我们写一个试图解析文件的例子。

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 缓存起来。

具体写法就是:

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);
    }
}
工厂方法模式
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。

public class BitmapFactory {
    
    public static Bitmap decodeFile(String pathName, Options opts) {
        //...
    }
    
    public static Bitmap decodeResource() {
        //...
    }
    
    public static Bitmap decodeByteArray() {
        //...
    }
}