进入公司刚开始做项目时,android只有自己一个开发人员,自己也是第一次编程做项目,在登陆模块用户登陆成功后,需要将用户的账号和密码缓存在本地,会根据本地的缓存自动登陆;当时脑袋一过想到的就是用SharedPreferences来缓存数据;
//缓存用户名和密码
SharedPreferences userSharedPreferences = getSharedPreferences("user", Context.MODE_PRIVATE);
SharedPreferences.Editor edit = userSharedPreferences.edit();
edit.putString("username","刘德华");
edit.putString("password","123456");
edit.commit();
获取缓存数据通过下面的方式获取:
//获取缓存的用户名和密码
SharedPreferences user = getSharedPreferences("user", Context.MODE_PRIVATE);
String username = user.getString("username", "");
String password = user.getString("password", "");
这样子功能是实现了,项目中不只一个地方需要缓存数据,感觉这样子很繁琐,需要修改的时候很麻烦,在学习过程中就将这些封装成一个工具类,使用起来就方便很多了;
public class SharedPreferencesUtil {
private static volatile SharedPreferencesUtil sharedPreferencesUtil;
private String CACHE_KEY="CACHE";
private SharedPreferences sharedPreferences;
private SharedPreferences.Editor editor;
private SharedPreferencesUtil() {
}
public static SharedPreferencesUtil getInstence() {
if (sharedPreferencesUtil == null) {
synchronized (SharedPreferencesUtil.class) {
if (sharedPreferencesUtil == null) {
sharedPreferencesUtil = new SharedPreferencesUtil();
}
}
}
return sharedPreferencesUtil;
}
public SharedPreferencesUtil init(Context context){
sharedPreferences = context.getApplicationContext().getSharedPreferences(CACHE_KEY, Context.MODE_PRIVATE);
editor = sharedPreferences.edit();
return this;
}
/**
* 缓存int类型
* @param key
* @param value
* @return
*/
public SharedPreferencesUtil putInt(String key,int value){
editor.putInt(key,value);
return this;
}
/**
* 缓存String类型
* @param key
* @param value
* @return
*/
public SharedPreferencesUtil putString(String key,String value){
editor.putString(key,value);
return this;
}
/**
* 缓存Boolean类型
* @param key
* @param value
* @return
*/
public SharedPreferencesUtil putBoolean(String key,boolean value){
editor.putBoolean(key,value);
return this;
}
/**
* 缓存long类型
* @param key
* @param value
* @return
*/
public SharedPreferencesUtil putLong(String key,long value){
editor.putLong(key,value);
return this;
}
/**
* 缓存float类型
* @param key
* @param value
* @return
*/
public SharedPreferencesUtil putFloat(String key,float value){
editor.putFloat(key,value);
return this;
}
/**
* 获取String类型
* @param key
* @return
*/
public String getString(String key){
String string = sharedPreferences.getString(key, "");
return string;
}
/**
* 获取int类型
* @param key
* @return
*/
public Integer getInt(String key){
int value = sharedPreferences.getInt(key, -1);
return value;
}
/**
* 获取float类型
* @param key
* @return
*/
public float getFloat(String key){
float value = sharedPreferences.getFloat(key, 0f);
return value;
}
/**
* 获取Boolean类型
* @param key
* @return
*/
public boolean getBoolean(String key){
boolean value = sharedPreferences.getBoolean(key, false);
return value;
}
/**
* 获取long类型
* @param key
* @return
*/
public long getLong(String key){
long value = sharedPreferences.getLong(key, 0);
return value;
}
/**
* 提交
*/
public void commit(){
editor.commit();
}
}
用了下单例模式,保证了只有一个SharedPreferencesUtil对象实例,使用时调用对应的方法去缓存或者获取缓存数据;
//缓存用户名和密码
SharedPreferencesUtil
.getInstence()
.init(this)
.putString("username","张小龙")
.putString("password","aljlsjdg")
.commit();
//获取缓存的用户名和密码
String username=SharedPreferencesUtil.getInstence().getString("username");
String password=SharedPreferencesUtil.getInstence().getString("password");
随着学习和做项目的时间久了,看到有大牛还可以使用工厂模式,感觉蛮好的,后面有跟随大牛的脚步,又将其进行了更改;
新增一个工厂接口,提供缓存和获取缓存的方法:
public interface SharedPreferencesCache<T extends SharedPreferencesCache> {
//缓存方法
T putString(String key,String value);
T putInt(String key,int value);
T putFloat(String key,float value);
T putBoolean(String key,boolean value);
T putLong(String key,long value);
void commit();
//获取缓存的方法
String getString(String key);
int getInt(String key);
long getLong(String key);
boolean getBoolean(String key);
float getFloat(String key);
}
定义具体的缓存方式,实现SharedPreferencesCache接口:
public class SharedPreferencesCacheImp implements SharedPreferencesCache{
private SharedPreferencesUtil preferencesUtil;
public SharedPreferencesCacheImp(Context context){
preferencesUtil = SharedPreferencesUtil.getInstence().init(context);
}
@Override
public SharedPreferencesCacheImp putString(String key, String value) {
preferencesUtil.putString(key,value);
return this;
}
@Override
public SharedPreferencesCacheImp putInt(String key, int value) {
preferencesUtil.putInt(key,value);
return this;
}
@Override
public SharedPreferencesCacheImp putFloat(String key, float value) {
preferencesUtil.putFloat(key,value);
return this;
}
@Override
public SharedPreferencesCacheImp putBoolean(String key, boolean value) {
preferencesUtil.putBoolean(key,value);
return this;
}
@Override
public SharedPreferencesCacheImp putLong(String key, long value) {
preferencesUtil.putLong(key,value);
return this;
}
@Override
public void commit() {
preferencesUtil.commit();
}
@Override
public String getString(String key) {
String string = SharedPreferencesUtil.getInstence().getString(key);
return string;
}
@Override
public int getInt(String key) {
Integer anInt = SharedPreferencesUtil.getInstence().getInt(key);
return anInt;
}
@Override
public long getLong(String key) {
long aLong = SharedPreferencesUtil.getInstence().getLong(key);
return aLong;
}
@Override
public boolean getBoolean(String key) {
boolean aBoolean = SharedPreferencesUtil.getInstence().getBoolean(key);
return aBoolean;
}
@Override
public float getFloat(String key) {
float aFloat = SharedPreferencesUtil.getInstence().getFloat(key);
return aFloat;
}
}
定义一个简单工程方法类,根据不同的缓存方式,返回对应的实例对象:
public class CacheFactory {
public enum CacheType{
MEMORY,PREFERENCES,DISK
}
public static SharedPreferencesCache createCache(Context context,CacheType type){
switch (type){
case DISK:
return new DiskCache();
case PREFERENCES:
return new SharedPreferencesCacheImp(context);
default:
return null;
}
}
}
使用时去实例化CacheFactory就可以了:
SharedPreferencesCache cache = CacheFactory.createCache(this, CacheFactory.CacheType.PREFERENCES);
//缓存用户名和密码
cache.putString("username", "赵六六")
.putString("password", "ljsjdgkjlg")
.commit();
//获取缓存的用户名和密码
String username = cache.getString("username");
String password = cache.getString("password");
这样根据配置的缓存类型使用不同的缓存方式,代码就灵活多了,这就是简单工厂方法模式,但是每新增一种新的缓存方式都要去CacheFactory工厂类中新增新的缓存类型和实例化新的缓存实例对象,感觉还是有点美中不足;
在简单工厂方法的基础上新增IoFactory接口,提供一个创建具体工厂的方法;具体由SharedPreferencesFactory工厂类去实现;
public interface IoFactory<T extends SharedPreferencesCache> {
T createFactory();
}
public class SharedPreferencesFactory implements IoFactory<SharedPreferencesCacheImp>{
private Context context;
public SharedPreferencesFactory(Context context){
this.context=context;
}
@Override
public SharedPreferencesCacheImp createFactory() {
return new SharedPreferencesCacheImp(context);
}
}
在使用实例化对象时,就不需要想简单工厂方法那样需要传入缓存的类型,如果使用SharedPreferences方式缓存直接实例化SharedPreferencesFactory类:
SharedPreferencesCacheImp cache =new SharedPreferencesFactory(this).createFactory();
//缓存用户名和密码
cache.putString("username", "赵六六")
.putString("password", "ljsjdgkjlg")
.commit();
//获取缓存的用户名和密码
String username = cache.getString("username");
String password = cache.getString("password");
这样子虽然导致类数量的增加,但是在新增新的缓存方式时,不需要去修改之前的代码,只需要增加缓存方式对应的工厂类,比较符合开闭原则,这就是工厂方法模式;还有抽象工厂模式,这里就不去弄了,具体使用什么实现方式,可以根据项目的需要来实现。