simple-android-flux,深入浅出Flux
生活随笔
收集整理的這篇文章主要介紹了
simple-android-flux,深入浅出Flux
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
前言
Flux: * 非形式化框架,更多的是一個思想。 * 它是典型MVC/MVP框架的一個補充。 * 學(xué)會使用Flux,需要將思路從命令式編程轉(zhuǎn)向聲明式編程。 * 學(xué)會使用Flux,需要明確流的概念。 復(fù)制代碼簡介
Flux是Facebook用戶建立客戶端Web應(yīng)用的前端架構(gòu),它通過利用一個單向的數(shù)據(jù)流補充了React的組合視圖組件,這更是一種模式 而非正式框架,你能夠無需許多新代碼情況下立即開始使用Flux。 Flux應(yīng)用有三個主要部分:Dispatcher調(diào)度 、存儲Store和視圖View(React 組件),這些不應(yīng)該和 MVC:Model-View-Controll(模型-視圖-控制器)混淆,控制器在Flux應(yīng)用中是存在的,但是他們是controller-view(控制器-視圖), 視圖通常在一個結(jié)構(gòu)頂部,而這種結(jié)構(gòu)是用來從存儲stroe獲得數(shù)據(jù),然后將數(shù)據(jù)傳遞到自己的子結(jié)構(gòu)們,此外,Action創(chuàng)建者 -Dispatcher的幫助類的方法-用于支持一個語義API,這個API是描述應(yīng)用程序中所有變化的可能,通??蓪⑺鼈兛闯墒荈lux 更新循環(huán)的第四部分。 Flux是以單向數(shù)據(jù)流方式支持MVC,當(dāng)一個用戶和React視圖交互時,視圖會將這個動作傳播到一個中央Dispatcher,一直到各種存儲, 在那里保存著應(yīng)用的數(shù)據(jù)和業(yè)務(wù)邏輯,這個使用React的聲明式風(fēng)格的過程是非常棒的,能夠允許存儲發(fā)送更新信息,而無需指定在狀態(tài) 之間如何切換視圖。(傳統(tǒng)方式更新狀態(tài)后,會推出一個新的視圖頁面。) 復(fù)制代碼流程圖
介紹一下流程圖中的各個成員: 復(fù)制代碼- Dispatcher:整個流程中唯一樞紐,負(fù)責(zé)發(fā)送和分發(fā)事件流,以及管理各個Store之間的關(guān)系。
- Store:倉庫,對應(yīng)MVP中的P,負(fù)責(zé)獲取M并根據(jù)業(yè)務(wù)邏輯,重組M的源數(shù)據(jù),并通知V進行視圖的渲染。
- View(其實應(yīng)該叫做Control-View):對應(yīng)MVP中的V,對應(yīng)Android中的Activity和Fragment。負(fù)責(zé)夾在xml,實現(xiàn)控件事件的觸發(fā),最重要的是負(fù)責(zé)接收Store中的業(yè)務(wù)數(shù)據(jù),進行試圖渲染。
- Action:一個事件,往往有明確含義,大部分場景下,其內(nèi)容等同于Model。
- ActionCreator:產(chǎn)生Action的模塊,其意義就是將原MVP中,V層控件觸發(fā)的業(yè)務(wù)邏輯封裝起來。
- Event:子事件,往往有明確含義,用于Store與Control-View間的通信。
具體實例流程圖展示:
以服務(wù)器交互舉例,事件流的具體過程: 1.從服務(wù)器異步獲取數(shù)據(jù)(也可以是一些數(shù)據(jù)庫操作,本地文件讀取等); 2.通過ActionCreator產(chǎn)生某個有明確意義的Action; 3.將該Action發(fā)送至事件總線的分發(fā)器; 4.分發(fā)器將Action發(fā)送至聲明接收該Action的Store; 5.Store拆解收到Action后,直接發(fā)送Event或在接收若干個Action,集合所有事件后觸發(fā)發(fā)送某個Event; 6.將該Event發(fā)送至事件總線的分發(fā)器; 7.分發(fā)器將Event發(fā)送至生接收該Action的ControlView; 8.ControlView所渲染的頁面上,觸發(fā)一個用戶行為,通知ActionCreator。 復(fù)制代碼Android中的Flux實例演示
這個例子實現(xiàn)的功能是一個簡易的參加唱歌比賽的歌手信息錄入系統(tǒng)。 復(fù)制代碼Dispatcher: 負(fù)責(zé)事件的分發(fā)
private final Bus bus; private static Dispatcher instance;public static Dispatcher get(Bus bus) {if (instance == null) {instance = new Dispatcher(bus);}return instance; }Dispatcher(Bus bus) {this.bus = bus; }public void register(final Object cls) {bus.register(cls); }public void unregister(final Object cls) {bus.unregister(cls); }public void emitChange(Store.StoreChangeEvent o) {post(o); }public void dispatch(String type, Object... data) {if (isEmpty(type)) {throw new IllegalArgumentException("Type must not be empty");}if (data.length % 2 != 0) {throw new IllegalArgumentException("Data must be a valid list of key,value pairs");}Action.Builder actionBuilder = Action.type(type);int i = 0;while (i < data.length) {String key = (String) data[i++];Object value = data[i++];actionBuilder.bundle(key, value);}post(actionBuilder.build()); }private boolean isEmpty(String type) {return type == null || type.isEmpty(); }private void post(final Object event) {bus.post(event); } 復(fù)制代碼SingerStore:負(fù)責(zé)數(shù)據(jù)存儲以及數(shù)據(jù)更新后發(fā)送更新事件
private static SingerStore instance; private final List<Singer> singers;public SingerStore(Dispatcher dispatcher) {super(dispatcher);singers = new ArrayList<>(); }public static SingerStore get(Dispatcher dispatcher) {if (instance == null) {instance = new SingerStore(dispatcher);}return instance; }public List<Singer> getSingers() {return singers; }@Override @Subscribe public void onAction(Action action) {switch (action.getType()) {case SingerActions.ActionType.CREATE_ACTION:Singer singer =((Singer) action.getData().get(SingerActions.EventObjectKey.KEY_SINGER));addElement(singer);emitStoreChange();break;case SingerActions.ActionType.DELETE_ACTION:long id = ((long) action.getData().get(SingerActions.EventObjectKey.KEY_SINGER_ID));deleteElement(id);emitStoreChange();break;} }private void addElement(Singer clone) {singers.add(clone);Collections.sort(singers); }private void deleteElement(long id) {Iterator<Singer> iterator = singers.iterator();while (iterator.hasNext()) {Singer singer = iterator.next();if (singer.getId() == id) {iterator.remove();break;}} }@Override StoreChangeEvent changeEvent() {return new SingerStoreChangeEvent(); }public class SingerStoreChangeEvent implements StoreChangeEvent { } 復(fù)制代碼ActionsCreator:負(fù)責(zé)產(chǎn)生各類事件
private static ActionsCreator instance; final Dispatcher dispatcher;ActionsCreator(Dispatcher dispatcher) {this.dispatcher = dispatcher; }public static ActionsCreator get(Dispatcher dispatcher) {if (instance == null) {instance = new ActionsCreator(dispatcher);}return instance; }public void create(Singer singer) {dispatcher.dispatch(SingerActions.ActionType.CREATE_ACTION,SingerActions.EventObjectKey.KEY_SINGER,singer); }public void delete(long id) {dispatcher.dispatch(SingerActions.ActionType.DELETE_ACTION,SingerActions.EventObjectKey.KEY_SINGER_ID,id); } 復(fù)制代碼總結(jié)
1.Flux與其說是框架,不如說是一種思路。 2.繼承MVP框架模式,將M與V隔離。額外的,其通過聲明式編程,將P與V進一步解耦。 3.由于是單向的,不存在逆向調(diào)用,使整體代碼流程清晰。 4.一般通過事件總線來實現(xiàn)。 復(fù)制代碼參考文章
其他介紹文章
附:源碼地址
總結(jié)
以上是生活随笔為你收集整理的simple-android-flux,深入浅出Flux的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 离散数学及其应用 (Kenneth H·
- 下一篇: 解决计算机问题的一般步骤