Unidirectional Data Flow di Android

Bagi yang familiar dengan React.js pasti tau apa itu flux. Flux adalah design application architecture yang dikembangan oleh facebook yang menggunakan konsep unidirectional data flow. Yang artinya bahwa semua data dalam aplikasi mengikuti pola siklus yang sama atau satu arah, yang bertujuan agar logika dalam sebuah aplikasi lebih mudah dimengerti dan diprediksi.

Ada 3komponen penting dalam flux adalah dispatcher, store , view. dan action sebagai state manager.

Dispatcher, store dan view adalah object yang independent yang berbuhungan langsung dengan proses input dan output. sedangkan action disini berperan sebagai state manager, atau untuk menentukan tipe properti dari sebuah aksi atau task.

  1. Dispatcher adalah pengubung antara store dan view, sebagai jalur pertukaran data. di dalam project Android biasanya mengunakan perantara publisher subscriber tools, Seperti Otto atu EventBus
  2. View adalah application interface yang berhubungan langsung dengan interaksi user. Dalam hal ini adalah Activity, View atau Fragment.
  3. Store adalah object yang berfungsi untuk mengelola state dan juga task serta berfungsi untuk mempublish data ke dalam view.

Implementasi di Project androidnya adalah sebagai berikut.

Dispatcher.java

public class Dispatcher {

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) {
if(event != null)
bus.post(event);
}
}

terdapat method dispatch yang berfungsi untuk meberitahu action untuk merubah state dan untuk mengirim (broadcast) data sesuai dengan tipe tertentu yang nantinya akan disubscribe oleh store. Kemudian data akan diproses di store, kemudian hasilnya datanya akan di broadcast ke dalam view.

public class StoreTodo extends Store {

static StoreTodo instance;
static LocalRepository localRepository;

protected StoreTodo(Dispatcher dispatcher) {
super(dispatcher);
}

public void addLocalRepo(LocalRepository localRepository){
this.localRepository = localRepository;
}

public static StoreTodo get(Dispatcher dispatcher){
if(instance == null){
instance = new StoreTodo(dispatcher);
}
return instance;
}

@Override
StoreChangeEvent changeEvent() {
return new TodoStoreChangeEvent();
}

@Override
@Subscribe
public void onAction(Action action) {

switch (action.getType()){
case TodoActions.ADD_TODO:
Todo todo = (Todo) action.getData().get(TodoActions.ADD_TODO);
if(addTodo(todo)) emitStoreChange();
break;

case TodoActions.DELETE_TODO:
int id = (int) action.getData().get(TodoActions.DELETE_TODO);
deleteTodo(id);
emitStoreChange();
break;

case TodoActions.UPDATE_TODO:
Todo td = (Todo) action.getData().get(TodoActions.UPDATE_TODO);
if(updateTodo(td)) emitStoreChange();

break;
}
}
}

Ini adalah contoh store yang terdapat task untuk menambah, hapus, dan update todo list. kemudian data akan di broadcast emitStoreChange();

Kemudian View akan menerima data yang dikirim dari Store tadi dengan melakukan subscribe data.

@Subscribe
public void update(StoreTodo.TodoStoreChangeEvent event){
update();
}

void update(){
adapter.update(storeTodo.getAllTodo());
}
Untuk sample projectnya ada di link berikut