概述
就像六大原则一样,每一种设计模式也都是一种思想,而不是一种特定的形式,所以要灵活求变。这次简单分析一下工厂设计模式在实际开发当中的应用。工厂设计模式分为三大类:简单工厂、工厂方法、抽象工厂。而工厂方法又分为两种形式:单工厂形式和多工厂形式。这次将结合数据存储的三种类型,对工厂模式的各个形式来分析一下。这三种类型分别是内存存储(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
网友评论