Android 中使用工厂模式来管理数据缓存及存储

我们在实际开发中, 会有很多地方都需要缓存数据, 一些常用的需要缓存到内存中, 不常用的需要缓存到数据库或者 SD 卡中.

这些需要缓存的数据对我们来说, 内部的结构差异并不是很大, 都是存取数据. 如果说为每一种存储都单独写一个工具类来供我们调用, 也是可以的. 但是入口不统一, 后期维护起来, 可能会造成一部分的麻烦, 很有可能会到处去修改. 这个例子就是使用工厂模式让我们优雅的管理数据的缓存和存储, 会更方便后期的维护.

开始正文.
平时我们使用 SharedPreferences 存储的时候, 是不是就是直接创建一个工具类呢? 像下面这样

public class PreferencesUtils {

    private static volatile PreferencesUtils mInstance;
    private SharedPreferences mSharedPreferences;
    private SharedPreferences.Editor mEditor;

    private PreferencesUtils() {
    }

    public void init(Context context) {
        mSharedPreferences = context.getApplicationContext().getSharedPreferences(
                CacheKey.SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
        mEditor = mSharedPreferences.edit();
    }

    public static PreferencesUtils getInstance() {
        if (mInstance == null) {
            synchronized (PreferencesUtils.class) {
                if (mInstance == null) {
                    mInstance = new PreferencesUtils();
                }
            }
        }
        return mInstance;
    }

    public PreferencesUtils putString(String key, String value) {
        mEditor.putString(key, value);
        return this;
    }

    public String getString(String key) {
        return mSharedPreferences.getString(key, "");
    }
    ...
    ...
    ...
    public void commit() {
        mEditor.commit();
    }
}

然后在我们自己的 BaseApplication 中初始化这个工具类

public class BaseApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        PreferencesUtils.getInstance().init(this);
    }
}

其实这样写是完全没有问题的. 可是后面如果新增了别的存储方式, 例如内存的, 数据库的, 又要怎么办呢?
现在我们对它来改造一下.

  1. 先创建一个产品类接口. 里面包含了所有存储数据所需的基本功能
/**
 * 定义数据存储的基本方法
 */
public interface ICache {
    ICache putObjectCache(String cacheKey, Object value);
    ICache putBooleanCache(String cacheKey, boolean value);
    ICache putStringCache(String cacheKey, String value);
    ICache putLongCache(String cacheKey, long value);
    ICache putDoubleCache(String cacheKey, double value);
    ICache putIntCache(String cacheKey, int value);
    void putCommit();
    //--------------------------------------------------------------------
    Object getObjectCache(String cacheKey);
    boolean getBooleanCache(String cacheKey, boolean defaultValue);
    String getStringCache(String cacheKey);
    long getLongCache(String cacheKey, long defaultValue);
    double getDoubleCache(String cacheKey, double defaultValue);
    int getIntCache(String cacheKey, int defaultValue);
}
  1. 接着创建实体产品 PreferencesCache, MemoryCache, DiskCache 分别实现抽象产品
public class PreferencesCache implements ICache {

    private SharedPreferences mSharedPreferences;
    private SharedPreferences.Editor mEditor;

    private PreferencesCache(Context context){
        mSharedPreferences = context.getApplicationContext().getSharedPreferences(
                CacheKey.SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
        mEditor = mSharedPreferences.edit();
    }

    @Override
    public ICache putStringCache(String cacheKey, String value) {
        //PreferencesUtils.getInstance().putString(cacheKey, value);
        mEditor.putString(cacheKey, value);
        return this;
    }

    @Override
    public String getStringCache(String cacheKey) {
        //return PreferencesUtils.getInstance().getString(cacheKey);
        return mSharedPreferences.getString(cacheKey, "");
    }

    @Override
    public void putCommit() {
        //PreferencesUtils.getInstance().commit();
        mEditor.commit();
    }

    ...
    ...
}
  1. 最后创建工厂类
public class CacheFactory {

    private static volatile CacheFactory mInstance;
    private ICache mMemoryCache, mDiskCache, mPreCache;
    private Context mContext;

    private CacheFactory() {
    }

    public static CacheFactory getInstance() {
        if (mInstance == null) {
            synchronized (CacheFactory.class) {
                if (mInstance == null) {
                    mInstance = new CacheFactory();
                }
            }
        }
        return mInstance;
    }

    public void init(Context context){
        this.mContext = context;
    }

    private ICache createCache(Class<? extends ICache> clazz) {
        ICache cache = null;
        try {
            if(clazz.getCanonicalName().equals(PreferencesCache.class.getCanonicalName())){
                Constructor constructor = clazz.getDeclaredConstructor(Context.class);
                cache = (ICache) constructor.newInstance(mContext);

            }else {
                cache = clazz.newInstance();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return cache;
    }

    public ICache getMemoryCache() {
        if (mMemoryCache == null) {
            return createCache(MemoryCache.class);
        }
        return mMemoryCache;
    }

    public ICache getPreferencesCache() {
        if (mPreCache == null) {
            return createCache(PreferencesCache.class);
        }
        return mPreCache;
    }

    public ICache getDiskCache() {
        if (mDiskCache == null) {
            return createCache(DiskCache.class);
        }
        return mDiskCache;
    }

    public ICache getDefaultCache() {
        if (mPreCache == null) {
            return createCache(PreferencesCache.class);
        }
        return mPreCache;
    }
}

当然, 也可以不使用这种方式, 在每个方法内, 也可以不调用 createCache, 而是使用直接创建对象的方式. 这个就看个人怎么选择了.
当然, 别忘记了在 Application 中初始化我们的工厂

public class BaseApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        //PreferencesUtils.getInstance().init(this);
        CacheFactory.getInstance().init(this);
    }
}
  1. 使用
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView tv = findViewById(R.id.tv);
        String userName = CacheFactory.getInstance().getPreferencesCache().getStringCache(CacheKey.KEY_USER_NAME);
        if (TextUtils.isEmpty(userName)) {
            CacheFactory.getInstance().getPreferencesCache()
                    .putStringCache(CacheKey.KEY_USER_NAME, "张三")
                    .putCommit();
            //CacheFactory.getInstance().getMemoryCache().putStringCache(CacheKey.KEY_USER_NAME, "李四");
            //CacheFactory.getInstance().getDiskCache().putStringCache(CacheKey.KEY_USER_NAME, "李四");
        } else {
            tv.setText(userName);
        }
    }
}

这样就改造完成了, 后面有修改, 比如我们不需要用到 SharedPreferences 来存储了, 那么直接新建一个实体产品类, 然后在工厂里替换一下 PreferencesCache 即可.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章