前言
工厂设计模式系列文章
工厂设计模式(一)- 简介
工厂设计模式(二) - 简单工厂模式
工厂设计模式(三) - 工厂方法模式
工厂设计模式(四) - 抽象工厂模式
工厂设计模式(五) - 使用场景
1. 概述
这一节通过实例代码来演示,简单工厂模式的写法、优点及不足之处。
2. 简单工厂模式UML关系图如下
3. 简单工厂模式代码如下
1>:定义一个接口IOHandler,用于数据存储的一些规范
/**
* Email: 2185134304@qq.com
* Created by Novate 2018/5/6 19:06
* Version 1.0
* Params:
* Description: 数据存储的一些规范
*/
public interface IOHandler {
/*************save data start***************/
void save(String key,String value);
void save(String key,double value);
void save(String key,int value);
void save(String key,long value);
void save(String key,boolean value);
void save(String key,Object value);
/*************end data start***************/
/*************get data start***************/
String getString(String key);
double getDouble(String key,double defaultValue);
int getInt(String key,int defaultValue);
long getLong(String key,long defaultValue);
boolean getBoolean(String key,boolean defaultValue);
Object getObject(String key);
/*************get data end***************/
}
2>:定义一个简单工厂设计模式IOHandlerFactory,用于创建数据存储
/**
* Email: 2185134304@qq.com
* Created by Novate 2018/5/6 19:04
* Version 1.0
* Params:
* Description: 工厂设计模式 - 简单工厂设计模式
* 用于创建数据存储
*/
public class IOHandlerFactory {
public enum IOType{
MEMORY , PREFERENCES , DISK
}
public static IOHandler createIOHandler(IOType ioType){
switch (ioType){
case MEMORY:
// 在这里只是返回一个对象,有时候我们需要一系列的初始化参数
// 这里边直接返回一个对象,做到了解耦,比如你不想用MemoryIOHandler,想用 MemoryIOHandler,可以直接把MemoryIOHandler 写好,
// 然后直接返回 MemoryIOHandler对象即可
return new MemoryIOHandler() ;
case PREFERENCES:
return new PreferencesIOHandler() ;
case DISK: // 新增case语句,新增磁盘 DISK存储
return new DiskIOHandler() ;
default:
return null ;
}
}
}
3>:定义3个缓存策略,分别是内存缓存、磁盘缓存、本地SP缓存,都是让这3个类实现 IOHandler;
- a:内存缓存MemoryIOHandler,实现 IOHandler接口,代码如下:
/**
* Email: 2185134304@qq.com
* Created by Novate 2018/5/6 19:08
* Version 1.0
* Params:
* Description: 内存缓存
*/
public class MemoryIOHandler implements IOHandler {
// 存在 运行内存中,LruCache原理其实就是 HashMap集合 ,存储图片或者其他类型都是可以的
private static LruCache<String , Object> mCache = new LruCache<>(10*1024*1024) ; // 运行内存一般为app大小的 1/8
@Override
public void save(String key, String value) {
mCache.put(key , value) ;
}
@Override
public void save(String key, double value) {
}
@Override
public void save(String key, int value) {
}
@Override
public void save(String key, long value) {
}
@Override
public void save(String key, boolean value) {
}
@Override
public void save(String key, Object value) {
}
@Override
public String getString(String key) {
return (String) mCache.get(key);
}
@Override
public double getDouble(String key, double defaultValue) {
return 0;
}
@Override
public int getInt(String key, int defaultValue) {
return 0;
}
@Override
public long getLong(String key, long defaultValue) {
return 0;
}
@Override
public boolean getBoolean(String key, boolean defaultValue) {
return false;
}
@Override
public Object getObject(String key) {
return null;
}
}
- b:磁盘缓存DiskIOHandler,实现 IOHandler接口,代码如下:
/**
* Email: 2185134304@qq.com
* Created by Novate 2018/5/12 8:57
* Version 1.0
* Params:
* Description: 磁盘缓存
*/
public class DiskIOHandler implements IOHandler{
@Override
public void save(String key, String value) {
}
@Override
public void save(String key, double value) {
}
@Override
public void save(String key, int value) {
}
@Override
public void save(String key, long value) {
}
@Override
public void save(String key, boolean value) {
}
@Override
public void save(String key, Object value) {
}
@Override
public String getString(String key) {
return null;
}
@Override
public double getDouble(String key, double defaultValue) {
return 0;
}
@Override
public int getInt(String key, int defaultValue) {
return 0;
}
@Override
public long getLong(String key, long defaultValue) {
return 0;
}
@Override
public boolean getBoolean(String key, boolean defaultValue) {
return false;
}
@Override
public Object getObject(String key) {
return null;
}
}
- c:本地SP缓存 PreferenceIOHandler,实现 IOHandler接口,代码如下:
本地SP缓存
*/
public class PreferencesIOHandler implements IOHandler {
@Override
public void save(String key, String value) {
PreferencesUtils.getInstance().saveString(key , value) ;
}
@Override
public void save(String key, double value) {
}
@Override
public void save(String key, int value) {
}
@Override
public void save(String key, long value) {
}
@Override
public void save(String key, boolean value) {
}
@Override
public void save(String key, Object value) {
}
@Override
public String getString(String key) {
return PreferencesUtils.getInstance().getString(key);
}
@Override
public double getDouble(String key, double defaultValue) {
return 0;
}
@Override
public int getInt(String key, int defaultValue) {
return 0;
}
@Override
public long getLong(String key, long defaultValue) {
return 0;
}
@Override
public boolean getBoolean(String key, boolean defaultValue) {
return false;
}
@Override
public Object getObject(String key) {
return null;
}
}
4>:最后在MainActivity中测试,直接通过 工厂 IOHandlerFactory,传入对应的缓存方式名称,就可以切换对应缓存方式,代码如下:
/**
* Email: 2185134304@qq.com
* Created by Novate 2018/5/12 9:23
* Version 1.0
* Params:
* Description: 简单工厂测试
*/
public class MainActivity extends AppCompatActivity {
private TextView mTextView;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.test_tv);
// 通过IOHandlerFactory工厂,传如对应缓存的名称,比如MEMORY、PREFERENCES、DISK,就可以切换对应的缓存方式
IOHandler ioHandler = IOHandlerFactory.createIOHandler(IOHandlerFactory.IOType.MEMORY);
ioHandler.save("userName" , "北京 - Novate");
ioHandler.save("userAge" , "920925");
}
public void click(View view){
IOHandler ioHandler = IOHandlerFactory.createIOHandler(IOHandlerFactory.IOType.MEMORY);
String userName = ioHandler.getString("userName") ;
String userAge = ioHandler.getString("userAge") ;
mTextView.setText("userName = " + userName + " , userAge = " + userAge) ;
}
}
4. 测试效果如下图所示
5. 简单工厂模式特点
1>:简单工厂模式优点:
- a:解耦:如果需要哪种缓存方式,可以在MainActivity中直接通过 IOHandlerFactory根据传递的MEMORY、PREFERENCES、DISK不同参数,达到切换对应的缓存方式。
比如我现在正在用的是MEMORY缓存方式,下一次我想用DISK缓存方式,就可以直接去切换对应参数即可,过一段时间如果我又想用MEMORY缓存方式的话,我又可以切换回来,这样就不用修改原来的代码,直接切换对应缓存方式,就起到了解耦作用; - b:最少知识原则:
最少知识原则就是:你只需要告诉我把数据缓存到哪里:
比如缓存到MEMORY,那么我就在MainActivty中切换到IOHandlerFactory.IOType.MEMORY就行,其他的我不管;
比如缓存到PREFERENCES,那么我就在MainActivty中切换到IOHandlerFactory.IOType.PREFERENCES就行,其他的我不管;
比如缓存到DISK,那么我就在MainActivty中切换到IOHandlerFactory.IOType.DISK就行,其他的我不管;
2>:简单工厂模式缺点:
如果我新增了一种存储方式,比如我新增了 DiskIOHandler,就需要在IOHandlerFactory中新增加 case语句,说白了,就是需要修改我们之前的代码,这样做并不是特别好;
6. 写代码原则
我们写代码的原则就是:在日后需求修改、功能变动、新增网络请求、缓存处理等等这些东西,遵循的原则就是尽量的不去动原来的代码,那么如何做到这一点,那么我会在下一节给大家来讲解下如何做到新增缓存方式,并且不去修改原来的代码;