Android 中使用工厂模式来管理数据缓存及存储
2020-09-29 本文已影响0人
__Y_Q
我们在实际开发中, 会有很多地方都需要缓存数据, 一些常用的需要缓存到内存中, 不常用的需要缓存到数据库或者 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);
}
}
其实这样写是完全没有问题的. 可是后面如果新增了别的存储方式, 例如内存的, 数据库的, 又要怎么办呢?
现在我们对它来改造一下.
- 先创建一个产品类接口. 里面包含了所有存储数据所需的基本功能
/**
* 定义数据存储的基本方法
*/
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);
}
- 接着创建实体产品
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();
}
...
...
}
- 最后创建工厂类
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);
}
}
- 使用
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
即可.