<menu id="yymgu"></menu>
  • <menu id="yymgu"><menu id="yymgu"></menu></menu>
    <menu id="yymgu"></menu>
  • <xmp id="yymgu"><tt id="yymgu"></tt>
    鍍金池/ 教程/ Android/ Reactive programming
    Custom observables
    Compiled functions
    Reactive programming
    Reservoirs and parallelism
    Incrementally Agerifying legacy code
    Observables and updatables
    Compiled repositories
    Repositories

    Reactive programming

    Agera 使用著名的 觀察者模式 作為響應式編程的驅動機制。 被觀察者(observable)實現Observable接口, 并向所有注冊的觀察者們(observers)廣播事件。 觀察者(observer)實現Updatable接口, 可以注冊和注銷到Observable中,接受通知事件觸發更新操作,故此命名為Updatable。

    Observable

    public interface Observable {
    
      void addUpdatable(@NonNull Updatable updatable);
    
      void removeUpdatable(@NonNull Updatable updatable);
    }

    observer

    public interface Updatable {
    
      void update();
    }

    接下來的文檔中,將用_observable_和_updatable_來表示被觀察者和觀察者對象。

    Push event, pull data

    Agera 使用 push event, pull data 模型(推送事件,拉取數據)。 push event:被觀察者只做事件通知,不攜帶任何數據; pull data:觀察者根據自己需要從數據倉庫(Repository.get())拉取數據。

    這種 push event, pull data 模型, 觀察者就不需要提供數據了(ps:通常意義上的觀察者模式是支持攜帶數據和不攜帶數據的), 可以封裝簡單的事件, 比如 按鈕點擊事件,下拉刷新觸發事件,一個同步信號(比如:谷歌推送(GCM)消息到app)等。

        // push event
        mObservable = new OnClickObservable() {
            @Override
            public void onClick(View view) {
                dispatchUpdate();
            }
        };
    
        @Override
        public void update() {
            // pull data
            String result = mRepository.get();
            mBinding.setImageUrl(result);
        }

    然而, 被觀察者一般也提供數據。一個可以提供數據,還可以定義在提供數據發生變化時的事件的被觀察者,稱為數據倉庫(Repository)。 這并沒有改變 push event, pull data 模型: 當數據變化時,數據倉庫(Repository)通知所有觀察者更新;觀察者各自從數據倉庫(Repository)拉取數據響應事件。 這種模型的好處是:將數據和事件通知分離,數據倉庫(Repository)可以實現懶加載。

    由于 push event, pull data 模型和多線程情況下,觀察者可能看不到數據全部的更新記錄。 這是特意設計的: 因為大多數情況下(尤其更新app UI), 本來就只需要關心最新的數據。

    一個典型Agera風格的響應式Client由以下幾部分組成:

    • 向Observables注冊一個Updatable,用于事件通知;
    • 可直接調用update,來初始化或更改Client狀態;
    • 等待Observables的通知,拉取最新的數據來更新Client;
    • 當不需要事件了,需要向Observables注銷updatable,釋放資源。

    ps: 一個Repository的定義

        // 數據提供者 text color Supplier
        Supplier<Integer> supplier = new Supplier<Integer>() {
            @NonNull
            @Override
            public Integer get() {
                return MockRandomData.getRandomColor();
            }
        };
    
        mRepository = Repositories.repositoryWithInitialValue(0)
                .observe(mObservable)// 事件源
                .onUpdatesPerLoop()
                .thenGetFrom(supplier)// 數據源
                .compile();