美文网首页
工厂设计模式浅析

工厂设计模式浅析

作者: 碧云天EthanLee | 来源:发表于2021-07-26 12:50 被阅读0次
概述

就像六大原则一样,每一种设计模式也都是一种思想,而不是一种特定的形式,所以要灵活求变。这次简单分析一下工厂设计模式在实际开发当中的应用。工厂设计模式分为三大类:简单工厂、工厂方法、抽象工厂。而工厂方法又分为两种形式:单工厂形式和多工厂形式。这次将结合数据存储的三种类型,对工厂模式的各个形式来分析一下。这三种类型分别是内存存储(LRUCache)、SharedPreferece、Disk磁盘存储,它们将作为产品由工厂生产。

一、简单工厂

下面我们先定义一个产品存取数据的接口,它将作为三种类型的数据存储的规范。

/**
 * String 、int、boolean类型数据存储接口
 */
public interface ISaveHandler {

    String getString(String key);

    int getInt(String key);

    boolean getBoolean(String key);

    ISaveHandler putString(String key, String value);

    ISaveHandler putInt(String key, int value);

    ISaveHandler putBoolean(String key, boolean value);
}

上面定义了 String 、int、boolean三种数据类型存取的抽象方法,这里可以扩展。然后我们分别定义三种数据存储类型的实现类:

/**
 * LruCache 内存缓存
 */
public class MemoryHandler implements ISaveHandler{
    private Context mContext;
    private LruCache<String, Object> mLruCache;
    private MemoryHandler() {
        initRes();
  }
    @Override
    public String getString(String key) {
        return (String) mLruCache.get(key);
    }
    @Override
    public int getInt(String key) {
        return (int) mLruCache.get(key);
    }
    @Override
    public boolean getBoolean(String key) {
        return (boolean) mLruCache.get(key);
    }
    @Override
    public ISaveHandler putString(String key, String value) {
        mLruCache.put(key, value);
        return this;
    }
    @Override
    public ISaveHandler putInt(String key, int value) {
        mLruCache.put(key, value);
        return this;
    }
    @Override
    public ISaveHandler putBoolean(String key, boolean value) {
        mLruCache.put(key, value);
        return this;
    }
    private static class MemoryHolder {
        public static MemoryHandler mHolder = new MemoryHandler();
    }
    public static MemoryHandler getInstance() {
        return MemoryHolder.mHolder;
    }
    private void initRes() {
        mContext = BaseApplication.getBaseApplicationContext();
        int size = (int) (Runtime.getRuntime().maxMemory() / 1024 / 8);
        mLruCache = new LruCache<String, Object>(size){
            @Override
            protected int sizeOf(String key, Object value) {
                return super.sizeOf(key, value);
            }
        };
    }
}

上面 MemoryHandler 继承自 ISaveHandler ,实现LruCache 内存缓存。

/**
 * SharedPreference 缓存
 */
public class SharedPreferenceHandler implements ISaveHandler{
    private SharedPreferences mSharedPreferences;
    private SharedPreferences.Editor mEditor;
    private Context mContext;
    private SharedPreferenceHandler(){
        initRes();
    }
    private static class ShareHolder{
        public static SharedPreferenceHandler mHolder = new SharedPreferenceHandler();
    }
    public static SharedPreferenceHandler getInstance(){
        return ShareHolder.mHolder;
    }
    private void initRes(){
        mContext = BaseApplication.getBaseApplicationContext();
        mSharedPreferences = mContext.getSharedPreferences("Factory_Share_Store", Context.MODE_PRIVATE);
        mEditor = mSharedPreferences.edit();
    }
    @Override
    public String getString(String key){ // 在子线程中调用
        return mSharedPreferences.getString(key,"default");
    }
    @Override
    public int getInt(String key){ // 在子线程中调用
        return mSharedPreferences.getInt(key,-1);
    }
    @Override
    public boolean getBoolean(String key){ // 在子线程中调用
        return mSharedPreferences.getBoolean(key, false);
    }
    @Override
    public SharedPreferenceHandler putString(String key, String value){ // 在子线程中调用
        mEditor.putString(key, value);
        return this;
    }
    @Override
    public SharedPreferenceHandler putInt(String key, int value){ // 在子线程中调用
        mEditor.putInt(key, value);
        return this;
    }
    @Override
    public SharedPreferenceHandler putBoolean(String key, boolean value){ // 在子线程中调用
        mEditor.putBoolean(key, value);
        return this;
    }
    public void commit(){ // 在子线程中调用
        mEditor.commit();
    }
}

上面 SharedPreferenceHandler 继承自 ISaveHandler ,实现SharedPreference 缓存。还有磁盘缓存就不写了,有兴趣的可以自己扩展。这里主要讲解一下工厂设计模式。下面开始写简单工厂,简单确实也很简单,一个工厂一个switch语句:

/**
 * 简单工厂
 */
public class SimpleFactory {
    private SimpleFactory() {
    }
    public enum StoreType {
        TYPE_SHARED,
        TYPE_MEMORY,
        TYPE_DISK
    }
    public static ISaveHandler createStore(StoreType type) {
        switch (type) {
            case TYPE_SHARED: // SharedPreference对象
                return SharedPreferenceHandler.getInstance();
            case TYPE_MEMORY: //  MemoryHandler对象
                return MemoryHandler.getInstance();
            case TYPE_DISK: // DiskStoreHandler 对象
                return DiskStoreHandler.getInstance();
        }
        return SharedPreferenceHandler.getInstance();
    }
}

上面就是通过传入的枚举类型生成相应的存储对象。不多说,看一下用法吧:

public class SimpleActivity extends AppCompatActivity {
    private static final String TAG = "SimpleActivity";
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
        super.onCreate(savedInstanceState, persistentState);
        init();
    }
    private void init() {
        ISaveHandler iSaveHandler = SimpleFactory.createStore(SimpleFactory.StoreType.TYPE_SHARED);
        iSaveHandler.putString(KEY_USER_NAME, "碧云天");
        String name = iSaveHandler.getString(KEY_USER_NAME);
        Log.d(TAG, "name = " + name);
    }
}

这种枚举类型的简单工厂模式好处就是清楚明了类型少,没那么多拐弯抹角。不好的地方就是,当数据存储类型(产品类型)需要扩展的时候,需要改动工厂。下面我们来看一下第二种:工厂方法模式。

二、工厂方法模式

开头说了,工厂方法模式由两种形式,一种是多工厂形式,一种是单工厂形式。

  • 多工厂形式
/**
 * SharedPreference 工厂
 */
public class SharedMethodFactory implements IFactory{
    @Override
    public ISaveHandler createHandler() {
        return SharedPreferenceHandler.getInstance();
    }
}

上面我们看到了一个工厂里面一个方法,就用于生成 SharedPreference形式的存储。如果要生成其他形式的存储,那么就再造一个相应的工厂。别的工厂这里就不贴出来了。其实这种方式更加一目了然,但缺点也很一目了然,就是工厂贼多。那下面就看一下工厂比较少的形式。

  • 单工厂形式
/**
 * 工厂方法
 * 
 * 单工厂形式
 */
public class SingleFactory{
    public static ISaveHandler createHandler(Class<? extends ISaveHandler> clz) {
        try {
            // 反射创建对象
            return clz.newInstance();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
        return null;
    }
}

上面就是通过类型,然后反射获取存储类型的对象。这种模式和简单工厂有点类似,只不过这里不需要维护枚举类。当需要扩展数据存储方式时,只需要增加数据存储类型就可以了,并不需要改变工厂。这种方式应该是应用最广泛的一种工厂模式。下面再简单看下它的使用吧:

public class MethodFactoryActivity extends AppCompatActivity {
    private static final String TAG = "SimpleActivity";
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
        super.onCreate(savedInstanceState, persistentState);
       SingleModel();
    }
    private void SingleModel() {
        ISaveHandler iSaveHandler = SingleFactory.createHandler(SharedPreferenceHandler.class);

        assert iSaveHandler != null;
        iSaveHandler.putString(KEY_USER_NAME, "长亭外");
        String name = iSaveHandler.getString(KEY_USER_NAME);
        Log.d(TAG, "name = " + name);
    }
}
三、抽象工厂

抽象工厂模式其实和工厂方法的多工厂模式有点类似,容易混淆。这两者的区别是,单工厂方法模式下,一个工厂只能生产一个产品,而抽象工厂模式下,一个工厂需要生产一组产品。比如我这里需要一个工厂能同时生产内存存储对象和SharedPreferece对象。或者,一个工厂能同时生产内存存储对象和磁盘存储对象等等。在实际开发过程中,如果用到了这种抽象工厂模式,那么一般来说,一个工厂能生产的这两个对象之间会有一定的关联性。比如说汽车工厂,它能同时生产出轴承和轮胎,这两者关系就很密切。下面看一下抽象工厂模式:

// 接口、抽象
public interface AbstractFactory {

    ISaveHandler createHandlerOne();

    ISaveHandler createHandlerTwo();
}

/**
 * 生产 Memory 和 Disk两种存储方式
 */
public class MemoryAndDiskFactory implements AbstractFactory{
    @Override
    public ISaveHandler createHandlerOne() {
        return null;
    }
    @Override
    public ISaveHandler createHandlerTwo() {
        return null;
    }
}

/**
 * 生产 SharedPreference 和 Memory两种存储方式
 */
public class SharedAndMemoryFactory implements AbstractFactory{
    @Override
    public ISaveHandler createHandlerOne() {
        return SharedPreferenceHandler.getInstance();
    }

    @Override
    public ISaveHandler createHandlerTwo() {
        return MemoryHandler.getInstance();
    }
}

上面一个工厂可以生产两种产品,当然,上面例子里面工厂的两种产品木有很强的关联。刚才说了,使用到这种抽象工厂方式时,一般一个工厂的产品之间会有一定的关联。就像汽车的轴承和轮胎。相对来说,在日常的开发当中,工厂方法模式可能应用的更广泛一些。
Demo:Factory

相关文章

  • 浅析Java设计模式【1】——观察者

    前情内容 浅析Java设计模式【1】——观察者 浅析Java设计模式【2】——适配器 浅析Java设计模式【3】—...

  • 浅析Java设计模式【2】——适配器

    前情内容 浅析Java设计模式【1】——观察者 浅析Java设计模式【2】——适配器 浅析Java设计模式【3】—...

  • 浅析Java设计模式【3】——代理

    1. 前情内容 浅析Java设计模式【1】——观察者 浅析Java设计模式【2】——适配器 浅析Java设计模式【...

  • 工厂设计模式浅析

    概述 就像六大原则一样,每一种设计模式也都是一种思想,而不是一种特定的形式,所以要灵活求变。这次简单分析一下工厂设...

  • 设计模式-工厂模式浅析

    概述 先照搬书上工厂模式的定义,即定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延...

  • 设计模式四、抽象工厂模式

    系列传送门设计模式一、单例模式设计模式二、简单工厂模式设计模式三、工厂模式设计模式四、抽象工厂模式 抽象工厂模式 ...

  • 设计模式之工厂模式

    设计模式之工厂模式 标签(空格分隔): 设计模式 工厂模式 设计模式的感念 设计模式的应用 工厂设计模式的产生 工...

  • 设计模式三、工厂模式

    系列传送门设计模式一、单例模式设计模式二、简单工厂模式设计模式三、工厂模式设计模式四、抽象工厂模式 工厂模式 在一...

  • 工厂模式

    java设计模式-工厂模式 工厂模式: 工厂模式是java设计模式里最常用的设计模式之一。 工厂模式属于创建型模式...

  • 单件设计模式

    一、定义 设计模式 设计模式就是一种更好的编写代码方案。 常见设计模式 工厂设计模式、抽象工厂设计模式、抽象工厂设...

网友评论

      本文标题:工厂设计模式浅析

      本文链接:https://www.haomeiwen.com/subject/jogwmltx.html