在Android实际的开发过程中,会遇到数据储存的问题,最开始我们将数据储存在SP中,当突然有一天leader说能不能将数据储存在硬盘或者是内存中,简单工厂模式很好的提供了这一需求的解决方法。
简单工厂模式:
一个抽象产品类,可以派生出多个具体产品类。一个具体工厂类,通过往此工厂的static方法中传入不同参数,产出不同的具体产品类实例。
先定义个数据储存的接口IOHandler
/**
* Created by zhangl on 2019/1/4.
*/
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);
/**************** save data end **************************/
/*************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***************/
}
接下来写SP,内存,硬盘缓存的具体实现方法
/**
* Created by hcDarren on 2017/9/24.
*/
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) {
PreferencesUtils.getInstance().saveDouble (key,value);
}
@Override
public void save(String key, int value) {
PreferencesUtils.getInstance().saveInt(key,value);
}
@Override
public void save(String key, long value) {
PreferencesUtils.getInstance().saveLong(key,value);
}
@Override
public void save(String key, boolean value) {
PreferencesUtils.getInstance().saveBoolean(key,value);
}
@Override
public void save(String key, Object value) {
PreferencesUtils.getInstance().saveObject(key,value);
}
@Override
public String getString(String key) {
return PreferencesUtils.getInstance().getString(key);
}
@Override
public double getDouble(String key, double defaultValue) {
return PreferencesUtils.getInstance().getDouble(key);
}
@Override
public int getInt(String key, int defaultValue) {
return PreferencesUtils.getInstance().getInt(key);
}
@Override
public long getLong(String key, long defaultValue) {
return PreferencesUtils.getInstance().getLong(key);
}
@Override
public boolean getBoolean(String key, boolean defaultValue) {
return PreferencesUtils.getInstance().getBoolean(key);
}
@Override
public Object getObject(String key) {
return PreferencesUtils.getInstance().getObject(key);
}
}
同理 内存储存和硬盘储存的代码不贴了,下面来看IOHandlerFactory工厂类的实现方法
/**
* Created by zhangl on 2019/1/4.
*
* 工厂设计模式 - 简单工厂
*
*/
public class IOHandlerFactory {
public enum IOType{
MEMORY,PREFERENCES,DISK
}
public static IOHandler createIOHandler(IOType ioType){
switch (ioType){
case DISK:
return new DiskIOHandler();
case MEMORY:
return new MemoryIOHandler();
case PREFERENCES:
return new PreferencesIOHandler();
default:
return null;
}
}
}
在相关的业务逻辑代码中的体现为:
IOHandler ioHandler = IOHandlerFactory.createIOHandler(IOHandlerFactory.IOType.DISK); //硬盘
IOHandler ioHandler = IOHandlerFactory.createIOHandler(IOHandlerFactory.IOType.PREFERENCES); //SP
IOHandler ioHandler = IOHandlerFactory.createIOHandler(IOHandlerFactory.IOType.MEMORY); //内存
ioHandler.save("user","zhangl"); //存数据
ioHandler.getString("user"); //取数据
由以上可以看到,IOHandlerFactory 使用了简单工厂模式,可以很方便的实现数据存储方式的改变,大幅度的简化了代码。
工厂方法模式
简单的说 就是 一个工厂一般生产相对应的产品,一个 IOFactory -> 一个 IOHandler
一个抽象产品类,可以派生出多个具体产品类。一个抽象工厂类,可以派生出多个具体工厂类。每个具体工厂类只能创建一个具体产品类的实例。
以MemoryIOFactory为例:
public class MemoryIOFactory implements IOFactory {
@Override
public IOHandler createIOHandler() {
return new MemoryIOHandler();
}
}
public interface IOFactory {
IOHandler createIOHandler();
}
在相关逻辑代码中的使用如下
IOFactory ioFactory = new MemoryIOFactory();
IOHandler ioHandler = ioFactory.createIOHandler();
ioHandler.save("user","zhangl");
ioHandler.save("age","25");
String userName = ioHandler.getString("user");
工厂方法模式存在的问题:当伴随功能的扩展,IOFactory类会不断增加,而且逻辑基本一样,在一定程度代码冗余度高。
抽象工厂模式
为创建一组相关或者相互依赖的对象提供一个接口,而无需指定它们的具体类。通俗的说是通过特定的方法返回单一的对象。
以IOHandlerFactory 为例写一个抽象工厂类,
/**
* Created by zhangl on 2019/1/4.
*
*
* 抽象工厂类
*/
public class IOHandlerFactory {
public static IOHandler createIOHandler(Class extends IOHandler> ioHandlerClass ){
try {
return ioHandlerClass.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return new PreferencesIOHandler();
}
/**
* 获取 运行内存 存储
* @return
*/
public static IOHandler getMemoryIOHandler(){
return createIOHandler(MemoryIOHandler.class);
}
/**
* 获取 磁盘 存储
* @return
*/
public static IOHandler getDiskIOHandler(){
return createIOHandler(DiskIOHandler.class);
}
/**
* 获取 SP 存储
* @return
*/
public static IOHandler getPreferencesIOHandler(){
return createIOHandler(PreferencesIOHandler.class);
}
/**
* 获取 默认 存储
* 为什么搞个默认的,有时候代码写完了,但是网上有很多高效的,
* 又或者是本来就是用了别人的,但是某些人出了更好的,这样方便切换
* @return
*/
public static IOHandler getDefaultIOHandler(){
return getPreferencesIOHandler();
}
}
在业务逻辑代码中的使用方式为:
IOHandler ioHandler = IOHandlerFactory.getPreferencesIOHandler();
ioHandler.save("user","zhangl");
String userName = ioHandler.getString("user");
抽象工厂在使用的过程中,实现了代码的解耦,创建实例与使用实例的工作分开,使用不必关心类对象如何创建。