福音來了: 數(shù)據(jù)層框架 data-mediator(數(shù)據(jù)中介者)

data-mediator

data_mediator_binder_main.gif

see English document by click this.

  • 一個數(shù)據(jù)層的框架晾虑。利用編譯時注解技術(shù)灸叼, 在java和android平臺自動生成 數(shù)據(jù)實體及相關(guān)的代碼。
    方便數(shù)據(jù)層的使用。支持gson. 通過操作binder和代理 實現(xiàn)絕大部分開發(fā)屬性設置拇砰。(setText, setTextColor 等等)

    支持數(shù)據(jù)統(tǒng)計(即將上線)

導航

問題及目標

  • 現(xiàn)有問題:

    通常況下我們寫app: 需要寫很多實體,常用的就是和server交互的實體.

    在版本不斷迭代的情況下,數(shù)據(jù)模型可能會很很多次(CRUD 字段甚至直接刪除整個module).

    即使我們使用parcelable 代碼生成器,也經(jīng)常要ALT+insert去重新生成脱篙。toString那些更不用說了。

    而且如果用gson注解映射悦施, 就更不太方便了并扇。

    如果想鏈式編程....也不方便。

    ...
  • 基于此抡诞,我設計了這個數(shù)據(jù)中介者框架穷蛹。
  • 它的目標:

    由于數(shù)據(jù)層是直接和業(yè)務打交道。很可能經(jīng)常變動昼汗。為了減小這種變動肴熏。我想出了數(shù)據(jù)中介者框架(data-mediator).

    當然它還會支持很多特性. 未來還會完成更加復雜業(yè)務任務.

設計思想

  • 整個設計分3層: 模型層,代理層顷窒,調(diào)用層

  • 模型層:代表的是數(shù)據(jù)模型接口and實現(xiàn)

  • 代理層:數(shù)據(jù)實體的代理

  • 調(diào)用層:操作模型和代理的

特點

  • 自動生成數(shù)據(jù)的接口和實現(xiàn)類.可自動實現(xiàn)Serializable和 Parcelable(android)接口蛙吏。

    自動生成get/is , set , toString方法.

    自動生成代理層 以便監(jiān)聽數(shù)據(jù)變化。

  • 字段:

    • 1, 支持多種類型 , 8大基本類型(int,long,short,byte,float,double,boolean ,char)及其包裝類型鞋吉, String類型,

      和其他類型 .數(shù)組和list結(jié)構(gòu)同樣支持鸦做。(map暫不支持parcelable)
    • 2, 支持生成字段的gson注解 for 'Google-Gson'.
    • 3, 支持多域, 比如: 重置(IResetable接口), 拷貝(ICopyable接口), 共享(Shareable), 快照(ISnapable)接口谓着。toString.

      作用: 比如重置: 很多時候我們調(diào)用了數(shù)據(jù)的一些方法泼诱,改變了一些屬性。然后想重置以便重新使用赊锚。

      比如 toString. 可選擇某些字段參加或者不參加toString方法. hashCode和equals同理
  • 支持List/SparseArray屬性編輯器治筒。 (相當于對list/SparseArray的增刪改增加了便捷操作 和回調(diào))

  • 支持依賴或繼承 @Field注解的接口(代表數(shù)據(jù)實體). 繼承只能繼承一個。

    • 平常我們寫 BaseEntity(內(nèi)有代表http/https響應的code, message, data字段), 通常業(yè)務接口的數(shù)據(jù)會繼承這個BaseEntity舷蒲。

      所以這里規(guī)定 繼承@Field注解的接口(代表數(shù)據(jù)實體) 只能一個矢炼。否則error.
  • 支持鏈式調(diào)用. data-mediator-compiler 1.0.9 之后默認鏈式。

    1), 如果需要回到普通的java bean. 則需要將注解 @fields的方法 boolean enableChain()阿纤。 返回false.

    2), 需要注意的是句灌,如果模型之間有繼承關(guān)系。則需要將父module定義的enableChain 和 child的 enableChain 值相同, 否則編譯錯誤。

    3), 下面是示例:

 DataMediator<StudentModule> mediator = DataMediatorFactory.createDataMediator(StudentModule.class);
       //數(shù)據(jù)代理層
       mediator.getDataProxy()
               .setName(null)
               .setAge(0)
               .setId(0);

       //數(shù)據(jù)真正的模型實現(xiàn)
       mediator.getData().setName(null)
               .setAge(0)
               .setId(0);
  • 支持數(shù)據(jù)緩存 (使用請參考下面進階指南)
  • 支持android平臺的雙向綁定, 新增萬能的Binder. 支持綁定任意控件的屬性胰锌。(常用的已經(jīng)集成)

    綁定以后操作數(shù)據(jù)代理就是操作view. (使用請參考下面進階指南)

快速入門

1, 在項目根目錄添加apt依賴骗绕。

 classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'

2, 在使用的app module中加入。apt plugin

   apply plugin: 'com.neenbedankt.android-apt'

3, 添加dependencies

dependencies {
    //......
    compile 'com.heaven7.java.data.mediator:data-mediator:<see release>'
    compile 'com.heaven7.java.data.mediator.annotation:data-mediator-annotations:<see release>'
    apt 'com.heaven7.java.data.mediator.compiler:data-mediator-compiler:<see release>'
    apt 'com.squareup:javapoet:1.9.0'
    
    // 如果需要生成對應的gson注解资昧。請加入gson依賴酬土。比如
    compile "com.google.code.gson:gson:2.7"
    // 如果要支持android平臺的數(shù)據(jù)綁定. 請?zhí)砑右蕾?    compile 'com.heaven7.android.data.mediator:data-mediator-android:<see release>'
}

4, 開始定義你的數(shù)據(jù)實體。比如我要定義關(guān)于學生的數(shù)據(jù)模型, 需要實現(xiàn)Serializable, Parcelable.
假如學生有格带。年齡撤缴,名稱, id屬性。
那么簡單的數(shù)據(jù)定義為:


@Fields({
        @Field(propName = "age" , type = int.class, flags = FLAGS_ALL_SCOPES),
        @Field(propName = "name" , type = String.class, flags = FLAGS_ALL_SCOPES),
        @Field(propName = "id" , type = long.class, flags = FLAGS_ALL_SCOPES),
})
public interface Student extends Serializable, Parcelable{
}

5, 點擊android studio 工具欄上的圖標

as_make_project.png

即可自動生成代碼(數(shù)據(jù)定義沒變化叽唱,不會重新生成)屈呕。

會自動生成 xxxModule 模型接口, xxxxModule_Impl 模型實現(xiàn) 。

6, 調(diào)用示例 (來自data-mediator-demo下的TestPropertyChangeActivity

/**
 * 屬性改變demo
 * Created by heaven7 on 2017/9/18 0018.
 */
public class TestPropertyChangeActivity extends BaseActivity {

    @BindView(R.id.tv_desc)
    TextView mTv_desc;

    @BindView(R.id.bt_set_text_on_TextView)
    Button mBt_changeProperty;
    @BindView(R.id.bt_set_text_on_mediator)
    Button mBt_temp;

    DataMediator<StudentModule> mMediator;


    @Override
    protected int getLayoutId() {
        return R.layout.ac_test_double_bind;
    }

    @Override
    protected void onInit(Context context, Bundle savedInstanceState) {
        mBt_changeProperty.setText("click this to change property");
        mBt_temp.setVisibility(View.GONE);

        //為數(shù)據(jù)模型創(chuàng)建  中介者棺亭。
        mMediator = DataMediatorFactory.createDataMediator(StudentModule.class);
        //添加屬性callback
        mMediator.addDataMediatorCallback(new DataMediatorCallback<StudentModule>() {
            @Override
            public void onPropertyValueChanged(StudentModule data, Property prop, Object oldValue, Object newValue) {
                Logger.w("TestPropertyChangeActivity","onPropertyValueChanged","prop = "
                        + prop.getName() + " ,oldValue = " + oldValue + " ,newValue = " + newValue);
                mTv_desc.setText(String.valueOf(newValue));
            }
        });
        mMediator.getDataProxy().setName("heaven7");
    }

    @OnClick(R.id.bt_set_text_on_TextView)
    public void onClickSetTextOnTextView(View v){
        mMediator.getDataProxy().setName("time: " + System.currentTimeMillis());
    }
}

進階指南

混淆配置

-keepclasseswithmembers public class * implements com.heaven7.java.data.mediator.DataPools$Poolable{
   *;
}
-keepclasseswithmembers public interface * extends com.heaven7.java.data.mediator.DataPools$Poolable{
   *;
}
-keep class * extends com.heaven7.java.data.mediator.BaseMediator{
   *;
}
-keep class com.heaven7.java.data.mediator.BaseMediator
-keep public class com.heaven7.android.data.mediator.BinderSupplierImpl
# 1.1.3 新增
-keep public class com.heaven7.android.data.mediator.DataMediatorDelegateImpl

github 項目地址:github.com/LightSun/da…
歡迎大家star. 提issue 或者contribute .

Thanks for read !!!

ps: 如果技術(shù)上或者框架有任何問題虎眨。我都會快速解決的。
author:heaven7

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末镶摘,一起剝皮案震驚了整個濱河市嗽桩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌凄敢,老刑警劉巖碌冶,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異涝缝,居然都是意外死亡种樱,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門俊卤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人害幅,你說我怎么就攤上這事消恍。” “怎么了以现?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵狠怨,是天一觀的道長。 經(jīng)常有香客問我邑遏,道長佣赖,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任记盒,我火速辦了婚禮憎蛤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己俩檬,他們只是感情好萎胰,可當我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著棚辽,像睡著了一般技竟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上屈藐,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天榔组,我揣著相機與錄音,去河邊找鬼联逻。 笑死搓扯,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的遣妥。 我是一名探鬼主播擅编,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼箫踩!你這毒婦竟也來了爱态?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤境钟,失蹤者是張志新(化名)和其女友劉穎锦担,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體慨削,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡洞渔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了缚态。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片磁椒。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖玫芦,靈堂內(nèi)的尸體忽然破棺而出浆熔,到底是詐尸還是另有隱情,我是刑警寧澤桥帆,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布医增,位于F島的核電站,受9級特大地震影響老虫,放射性物質(zhì)發(fā)生泄漏叶骨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一祈匙、第九天 我趴在偏房一處隱蔽的房頂上張望忽刽。 院中可真熱鬧,春花似錦、人聲如沸缔恳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽歉甚。三九已至万细,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間纸泄,已是汗流浹背赖钞。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留聘裁,地道東北人雪营。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像衡便,于是被迫代替她去往敵國和親献起。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內(nèi)容