1. 程式人生 > >關於客戶端設計之數據分類和存儲 的思考

關於客戶端設計之數據分類和存儲 的思考

service his defaults def sqli href 思想 number fault

一、關於數據的分類

在Android 客戶端設計過程中,我將數據分為未知,已知(本地),臨時,三者之間根據需求相互轉化。

  • 未知主要來自用戶輸入和服務端輸入。

  • 已知主要來自sharedPerferences,SQLite等本地存儲。

  • 臨時主要是指存在於當前內存中的數據。在程序運行後,來自於前兩種方式,隨載體的生命周期開始,結束。(這裏尤其註意單例模式下的數據的特殊,使用static或者Application,各有利弊。)

二、Android下數據單例模式設計

1、Application本身就是單例模式下的類,通過在Application下持有目標的類的引用實現單例的功能,但是當功能的實現在功能類外面,我們考慮的是封裝的實現十分困難。

2、通過Java中static關鍵詞實現。

這裏存在兩個弊端:

一是Android關於進程的界限模糊,舉個例子說,在Activity中靜態變量無法再Service中使用。

二是static變量的生命周期過長,環境不會維護它的生命周期,即沒有被銷毀也沒有置null,其對象一直被保持引用。因此我們需要自己維護單例類的生命周期(這與java的思想沖突)。

三、已知數據(本地緩存)的設計

1、無疑第一反應使用封裝的sharedPreference,以key-value組織形式,同時本身底層也是通過xml文件實現。

缺陷是對事物的表述能力差,很難對復雜的邏輯描述。比如一個父親和幾個孩子的關系。這裏需要依靠SQLilte進行描述。

public class ParentCache {

    private static ParentCache parentCache;
    private SharedPreferences parentPreferences;
    private Parent parent;

    private String phone;
    private String pwd;
    private Set<String> childNameSet;
    private String currentChild;

    private static final String KEY_PHONE = "phone";
    private static final String KEY_PWD = "pwd";
    private static final String KEY_CHILD_NAME_LIST = "childNameList";
    private static final String KEY_CURRENT_CHILD = "currentChild";


    private ParentCache(Context context){
        parentPreferences = PreferenceManager.getDefaultSharedPreferences(context);
    }


    public static ParentCache getInstance(Context context) {

        if(parentCache == null) {
            parentCache = new ParentCache(context.getApplicationContext());
        }
        return parentCache;
    }

    /**
     * 考慮能夠通過對返回值處理進行健壯性完善和parent處理,使用commit() not apply()。
     * <p>使用apply()需要synchronized處理同步<p/>
     */
    public synchronized boolean clearCache() {

        boolean result = parentPreferences.edit().clear().commit();//commit()也存在對同步的處理。性能存在缺陷。

        if (result) {
            this.parent = null;
        }
        return result;
    }


    public synchronized String getPhone() {

        if (TextUtils.isEmpty(pwd)) {
            pwd = parentPreferences.getString(KEY_PHONE, null);
        }
        return pwd;
    }

    public synchronized String getPwd() {

        if (TextUtils.isEmpty(phone)) {
            phone = parentPreferences.getString(KEY_PHONE, null);
        }
        return phone;
    }

    public synchronized boolean setPhone(String phone) {

        SharedPreferences.Editor editor = parentPreferences.edit();

        boolean ret = editor.putString(KEY_PHONE, phone).commit();

        if (ret) {
            this.phone = phone;
        }
        return ret;
    }

    public synchronized boolean setPwd(String pwd) {

        SharedPreferences.Editor editor = parentPreferences.edit();

        boolean ret = editor.putString(KEY_PWD, pwd).commit();

        if (ret) {
            this.pwd = pwd;
        }
        return ret;
    }

    public synchronized Set<String> getChildNameSet() {
        if(childNameSet==null){
            childNameSet = parentPreferences.getStringSet(KEY_CHILD_NAME_LIST,null);
        }
        return childNameSet;
    }

    public synchronized boolean setChildNameSet(Set<String> childNameSet) {

        SharedPreferences.Editor editor = parentPreferences.edit();

        boolean ret = editor.putStringSet(KEY_CHILD_NAME_LIST,childNameSet).commit();

        if (ret){
            this.childNameSet = childNameSet;
        }
        return ret;
    }

    public synchronized String getCurrentChild() {
        if (TextUtils.isEmpty(currentChild)) {
            currentChild = parentPreferences.getString(KEY_CURRENT_CHILD,null);
        }
        return currentChild;
    }

    public boolean setCurrentChild(String currentChild) {
        SharedPreferences.Editor editor = parentPreferences.edit();

        boolean ret = editor.putString(KEY_CURRENT_CHILD, currentChild).commit();

        if (ret) {
            this.currentChild = currentChild;
        }
        return ret;
    }
}

2、對復雜的邏輯數據存儲。

關於客戶端設計之數據分類和存儲 的思考