美文网首页Android开发
Android数据持久化篇(五)—— 自己动手封装一个属于自己的

Android数据持久化篇(五)—— 自己动手封装一个属于自己的

作者: 乌托邦式的爱情 | 来源:发表于2021-08-09 14:15 被阅读0次

在前面的几篇文章里面,我们讲了关于文件的使用https://www.jianshu.com/p/36fc304f1ab8,SharedPreference的使用https://www.jianshu.com/p/784450ae7df9,SQLite数据库的使用https://www.jianshu.com/p/95901ccfc54c等等,这些都是属于数据持久化的系列,但是这些都是孤立的、零散的知识节点,很多时候我们需要学会将零散的知识点进行整合,然后通过各种设计模式对外暴露接口供应用层调用,那么,今天我们就来看看如何将之前的数据化内容进行整合。

在开始之前,我们需要先了解一下Java中23种设计模式之一的工厂模式,因为本篇的重点并不在这里,所以我就稍微带一下就好。

工厂模式的实现分为3种:

(1)简单工厂

(2)工厂方法

(3)抽象工厂

简单工厂
简单工厂.png

这是简单工厂的结构图,其实不难看出,sample为抽象接口,定义每一个具体实现类的规范,而Factory是用来生成sample的具体实例供外部去使用,举一个例子:

public abstract class Computer {

    public abstract String getRAM();
    public abstract String getHDD();
    public abstract String getCPU();

    @Override
    public String toString(){
        return "RAM= "+this.getRAM()+", HDD="+this.getHDD()+", CPU="+this.getCPU();
    }}

Computer 为一个抽象的电脑类,里面定义了CPU、RAM、HDD这几个参数,然后它的实现类则为:

Dell电脑类
public class DellComputer extends Computer {

    private String ram;
    private String hdd;
    private String cpu;

    public DellComputer(String ram, String hdd, String cpu){
        this.ram=ram;
        this.hdd=hdd;
        this.cpu=cpu;
    }
    @Override
    public String getRAM() {
        return this.ram;
    }

    @Override
    public String getHDD() {
        return this.hdd;
    }

    @Override
    public String getCPU() {
        return this.cpu;
    }
}
Apple电脑类
public class AppleComputer extends Computer {

    private String ram;
    private String hdd;
    private String cpu;

    public AppleComputer(String ram, String hdd, String cpu){
        this.ram=ram;
        this.hdd=hdd;
        this.cpu=cpu;
    }
    @Override
    public String getRAM() {
        return this.ram;
    }

    @Override
    public String getHDD() {
        return this.hdd;
    }

    @Override
    public String getCPU() {
        return this.cpu;
    }
}
编写工厂类供外部调用
public class ComputerFactory {

    public static Computer getComputer(String type, String ram, String hdd, String cpu) {
        if ("DELL".equalsIgnoreCase(type)) {
            return new DellComputer(ram, hdd, cpu);
        } else if ("Apple".equalsIgnoreCase(type)) {
            return new AppleComputer(ram, hdd, cpu);
        }
        return null;
    }}
最后简单测试一下
public class TestFactory {

    public static void main(String[] args) {
        Computer dell= ComputerFactory.getComputer("DELL", "2 GB", "500 GB", "2.4 GHz");
        Computer apple= ComputerFactory.getComputer("Apple", "16 GB", "1 TB", "2.9 GHz");
        System.out.println("Factory DELL Config::" + dell);
        System.out.println("Factory APPLE Config::" + apple);
    }
}

这样一个简单的简单工厂就完成了。工厂方法和抽象工厂这里就不展开讲解了,有兴趣的同学可以自己去学习学习。

开始进入正题

按照简单工厂的结构,首先我们需要定义一个抽象类去约束具体实现规则,抽象类或者接口都可以,这里我定义的是一个接口,如下所示:

/**
 * Created by zhoufan on 2018/2/24.
 * 实现对数据的存储
 */

public interface IOHandler {
    // 保存String类型 
    IOHandler saveString(String key, String value);
    // 保存Float类型
    IOHandler saveFloat(String key, float value);
    // 保存Int类型
    IOHandler saveInt(String key, int value);
    // 保存Boolean类型
    IOHandler saveBoolean(String key, boolean value);
    // 保存Long类型
    IOHandler saveLong(String key, long value);
    // 获取String类型的值
    String getString(String key);
    // 获取Float类型的值
    float getFloat(String key, float defaultValue);
    // 获取Int类型的值
    int getInt(String key, int defaultValue);
    // 获取Boolean类型的值
    boolean getBoolean(String key, boolean defaultValue);
    // 获取Long类型的值
    long getLong(String key, long defaultValue);
    // 执行删除操作
    void delete(String key);
    // 更新文件的名称
    void updateFileName(String fileName);
}

然后去实现具体的子类。

实现File文件类的存储
/**
 * author: zhoufan
 * data: 2021/8/9 10:21
 * content: 对文件的操作进行进一步的封装
 */
public class FileUtil implements IOHandler {

    // 使用单例生成唯一实例
    private static volatile FileUtil mInstance;
    private String mFileName;

    public static FileUtil getInstance() {
        if (mInstance == null) {
            synchronized (IOFactoryUtil.class) {
                if (mInstance == null) {
                    mInstance = new FileUtil();
                }
            }
        }
        return mInstance;
    }

    private FileUtil() {
        mFileName = "fileCache";
    }


    @Override
    public IOHandler saveString(String key, String value) {
        BufferedWriter bufferedWriter = null;
        try {
            boolean isResult = FileTool.createFolderAndFileItemDir(mFileName, key);
            if (isResult) {
                FileWriter fileWriter = new FileWriter(key);
                bufferedWriter = new BufferedWriter(fileWriter);
                bufferedWriter.write(value);
                bufferedWriter.flush();
            } else {
                MyToast.showCenterSortToast(IApplication.getContext(), IApplication.getContext().getString(R.string.create_error));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (bufferedWriter != null) {
                    bufferedWriter.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return this;
    }

    @Override
    public IOHandler saveFloat(String key, float value) {
        MyToast.showCenterSortToast(IApplication.getContext(), IApplication.getContext().getString(R.string.file_type_error));
        return this;
    }

    @Override
    public IOHandler saveInt(String key, int value) {
        MyToast.showCenterSortToast(IApplication.getContext(), IApplication.getContext().getString(R.string.file_type_error));
        return this;
    }

    @Override
    public IOHandler saveBoolean(String key, boolean value) {
        MyToast.showCenterSortToast(IApplication.getContext(), IApplication.getContext().getString(R.string.file_type_error));
        return this;
    }

    @Override
    public IOHandler saveLong(String key, long value) {
        MyToast.showCenterSortToast(IApplication.getContext(), IApplication.getContext().getString(R.string.file_type_error));
        return this;
    }

    @Override
    public String getString(String key) {
        BufferedReader bufferedReader = null;
        StringBuilder builder = new StringBuilder();
        try {
            String path = FileTool.getItemDirPath() + key;
            File file = new File(path);
            if (file.exists()) {
                FileReader fileReader = new FileReader(file);
                bufferedReader = new BufferedReader(fileReader, 512);
                String readBuff = null;
                while ((readBuff = bufferedReader.readLine()) != null) {
                    builder.append(readBuff);
                }
            } else {
                MyToast.showCenterSortToast(IApplication.getContext(), IApplication.getContext().getString(R.string.file_no_exists));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (bufferedReader != null) {
                    bufferedReader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return builder.toString();
    }

    @Override
    public float getFloat(String key, float defaultValue) {
        MyToast.showCenterSortToast(IApplication.getContext(), IApplication.getContext().getString(R.string.file_type_error));
        return 0;
    }

    @Override
    public int getInt(String key, int defaultValue) {
        MyToast.showCenterSortToast(IApplication.getContext(), IApplication.getContext().getString(R.string.file_type_error));
        return 0;
    }

    @Override
    public boolean getBoolean(String key, boolean defaultValue) {
        MyToast.showCenterSortToast(IApplication.getContext(), IApplication.getContext().getString(R.string.file_type_error));
        return false;
    }

    @Override
    public long getLong(String key, long defaultValue) {
        MyToast.showCenterSortToast(IApplication.getContext(), IApplication.getContext().getString(R.string.file_type_error));
        return 0;
    }

    @Override
    public void delete(String key) {
        FileTool.deleteFile(key);
    }

    @Override
    public void updateFileName(String fileName) {
        this.mFileName = fileName;
    }
}
实现MMKV的存储
/**
 * author: zhoufan
 * data: 2021/8/8 9:29
 * content: 数据持久化过程中使用MMKV进行存储
 */
public class MMKVUtil implements IOHandler {

    // 使用单例生成唯一实例
    private static volatile MMKVUtil mInstance;
    private MMKV mMMKV;

    public static MMKVUtil getInstance() {
        if (mInstance == null) {
            synchronized (IOFactoryUtil.class) {
                if (mInstance == null) {
                    mInstance = new MMKVUtil();
                }
            }
        }
        return mInstance;
    }

    private MMKVUtil() {
        mMMKV = MMKV.defaultMMKV();
    }


    @Override
    public IOHandler saveString(String key, String value) {
        if (key == null || value == null) {
            return this;
        }
        mMMKV.encode(key, value);
        return this;
    }

    @Override
    public IOHandler saveFloat(String key, float value) {
        if (key == null) {
            return this;
        }
        mMMKV.encode(key, value);
        return this;
    }

    @Override
    public IOHandler saveInt(String key, int value) {
        if (key == null) {
            return this;
        }
        mMMKV.encode(key, value);
        return this;
    }

    @Override
    public IOHandler saveBoolean(String key, boolean value) {
        if (key == null) {
            return this;
        }
        mMMKV.encode(key, value);
        return this;
    }

    @Override
    public IOHandler saveLong(String key, long value) {
        if (key == null) {
            return this;
        }
        mMMKV.encode(key, value);
        return this;
    }

    @Override
    public String getString(String key) {
        if (key == null) {
            return null;
        }
        return mMMKV.decodeString(key);
    }

    @Override
    public float getFloat(String key, float defaultValue) {
        if (key == null) {
            return defaultValue;
        }
        return mMMKV.decodeFloat(key);
    }

    @Override
    public int getInt(String key, int defaultValue) {
        if (key == null) {
            return defaultValue;
        }
        return mMMKV.decodeInt(key);
    }

    @Override
    public boolean getBoolean(String key, boolean defaultValue) {
        if (key == null) {
            return defaultValue;
        }
        return mMMKV.decodeBool(key);
    }

    @Override
    public long getLong(String key, long defaultValue) {
        if (key == null) {
            return defaultValue;
        }
        return mMMKV.decodeLong(key);
    }

    @Override
    public void delete(String key) {
        mMMKV.removeValueForKey(key);
    }

    @Override
    public void updateFileName(String fileName) {
        mMMKV = MMKV.mmkvWithID(fileName);
    }
}
实现SharedPreference的存储
public class SharePreferencesUtil implements IOHandler {

    // 使用单例生成唯一实例
    private static volatile SharePreferencesUtil mInstance;
    private String mFileName;

    public static SharePreferencesUtil getInstance() {
        if (mInstance == null) {
            synchronized (IOFactoryUtil.class) {
                if (mInstance == null) {
                    mInstance = new SharePreferencesUtil();
                }
            }
        }
        return mInstance;
    }

    private SharePreferencesUtil() {
        mFileName = "sharedPreferenceCache";
    }

    @Override
    public SharePreferencesUtil saveString(String key, String value) {
        SharedPreferences sharedPreferences = IApplication.getContext().getSharedPreferences(mFileName, 0);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString(key, value);
        editor.apply();
        return this;
    }

    @Override
    public SharePreferencesUtil saveFloat(String key, float value) {
        SharedPreferences sharedPreferences = IApplication.getContext().getSharedPreferences(mFileName, 0);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putFloat(key, value);
        editor.apply();
        return this;
    }

    @Override
    public SharePreferencesUtil saveInt(String key, int value) {
        SharedPreferences sharedPreferences = IApplication.getContext().getSharedPreferences(mFileName, 0);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putInt(key, value);
        editor.apply();
        return this;
    }

    @Override
    public SharePreferencesUtil saveBoolean(String key, boolean value) {
        SharedPreferences sharedPreferences = IApplication.getContext().getSharedPreferences(mFileName, 0);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putBoolean(key, value);
        editor.apply();
        return this;
    }

    @Override
    public SharePreferencesUtil saveLong(String key, long value) {
        SharedPreferences sharedPreferences = IApplication.getContext().getSharedPreferences(mFileName, 0);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putLong(key, value);
        editor.apply();
        return this;
    }


    @Override
    public String getString(String key) {
        SharedPreferences sharedPreferences = IApplication.getContext().getSharedPreferences(mFileName, 0);
        return sharedPreferences.getString(key, null);
    }

    @Override
    public float getFloat(String key, float defaultValue) {
        SharedPreferences sharedPreferences = IApplication.getContext().getSharedPreferences(mFileName, 0);
        return sharedPreferences.getFloat(key, defaultValue);
    }

    @Override
    public int getInt(String key, int defaultValue) {
        SharedPreferences sharedPreferences = IApplication.getContext().getSharedPreferences(mFileName, 0);
        return sharedPreferences.getInt(key, defaultValue);
    }

    @Override
    public boolean getBoolean(String key, boolean defaultValue) {
        SharedPreferences sharedPreferences = IApplication.getContext().getSharedPreferences(mFileName, 0);
        return sharedPreferences.getBoolean(key, defaultValue);
    }

    @Override
    public long getLong(String key, long defaultValue) {
        SharedPreferences sharedPreferences = IApplication.getContext().getSharedPreferences(mFileName, 0);
        return sharedPreferences.getLong(key, defaultValue);
    }

    // 执行删除操作
    @Override
    public void delete(String key) {
        try {
            SharedPreferences sharedPreferences = IApplication.getContext().getSharedPreferences(mFileName, 0);
            SharedPreferences.Editor editor = sharedPreferences.edit();
            if (sharedPreferences.contains(key)) {
                editor.remove(key);
                editor.apply();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void updateFileName(String fileName) {
        this.mFileName = fileName;
    }
}

也就是说,FileUtil(文件存储)、MMKVUtil(MMKV存储)、SharedPreferenceUtil(SharedPreference存储)就是IOHandler的具体实现类,类似于上面图中的sampleA、sampleB等等。接下来要操作的就是我们的Factory了。

首先定义工厂的抽象类

public interface IOFactory {

    IOHandler create(String type);

}
然后去实现我们的工厂,在这里提供对外的实现类
/**
 * Created by zhoufan on 2018/2/24.
 * 使用抽象工厂方法实现对缓存的处理
 */

public class IOFactoryUtil implements IOFactory {

    // 使用单例生成唯一实例
    private static volatile IOFactoryUtil ioFactoryUtil;
    public static final String MMKV_HANDLER = "1";
    public static final String SHAREDPREFERENCE_HANDLER = "2";
    public static final String FILE_HANDLER = "3";
    private IOHandler mIOHandler;

    public static IOFactoryUtil getIOFactoryUtil() {
        if (ioFactoryUtil == null) {
            synchronized (IOFactoryUtil.class) {
                if (ioFactoryUtil == null) {
                    ioFactoryUtil = new IOFactoryUtil();
                }
            }
        }
        return ioFactoryUtil;
    }

    @Override
    public IOHandler create(String type) {
        switch (type) {
            case SHAREDPREFERENCE_HANDLER:
                mIOHandler = getSharePreferencesHandler();
            case FILE_HANDLER:
                mIOHandler = getFileHandler();
            default:
                mIOHandler = getMMKVHandler();
        }
        return mIOHandler;
    }

    // SharePreferences存储
    private IOHandler getSharePreferencesHandler() {
        return SharePreferencesUtil.getInstance();
    }

    // MMKV存储
    private IOHandler getMMKVHandler() {
        return MMKVUtil.getInstance();
    }

    // 文件存储
    private IOHandler getFileHandler() {
        return FileUtil.getInstance();
    }

    // 默认的存储方式
    public IOHandler getUserHandler() {
        return create(MMKV_HANDLER);
    }
}

代码写的很详细,就不做过多讲解了,到这里,通过一个简单工厂就实现了对数据持久化实现的简单封装,最后来看下实现

// 使用默认的数据存储方式(默认为MMKV)
IOFactoryUtil.getIOFactoryUtil().userHandler.saveString("key","value")
// 切换引擎进行数据存储
IOFactoryUtil.getIOFactoryUtil().create(IOFactoryUtil.SHAREDPREFERENCE_HANDLER).saveString("key","value")

这样,一个简单又好用的数据持久化就完成啦

相关文章

网友评论

    本文标题:Android数据持久化篇(五)—— 自己动手封装一个属于自己的

    本文链接:https://www.haomeiwen.com/subject/bpezvltx.html