æžãããã³ãŒãã®è¡ãå€ãã»ã©ãã³ãŒããè€è£œããé »åºŠãå°ãªããªããå®è£ ããããããžã§ã¯ããå¢ããã»ã©ãå€ããã®ãé »ç¹ã«äœ¿çšããããã«ãªããŸãããæãããŠããŠããçæã§ããã建ç¯ãœãªã¥ãŒã·ã§ã³ã«ãŸããŸãèå³ãæã¡ãŸãã
iOSéçºè ã«éåžžã«æãããŠããVIPERã¢ãŒããã¯ãã£ãã³ãã¬ãŒãã«åºäŒãã®ã¯ãAndroidã«æ¬¡ãã§ç¿æ £çã§ã¯ãªããšæããŸãããŸããAndroidã¢ããªã±ãŒã·ã§ã³ã§ãã®ãããªãã³ãã¬ãŒããäžæ¬æã«äœ¿çšãå§ããããšãçªç¶å€æãããŸã§ããã®ããšã«ã€ããŠè¿é£ã®éšçœ²ããåããŠè³ãåŸããŸããã
ããã¯ã©ãããŠèµ·ããã®ã§ããããïŒ ã¯ããéåžžã«ç°¡åã§ãã ãšã¬ã¬ã³ããªã¢ãŒããã¯ãã£ãœãªã¥ãŒã·ã§ã³ã®æ€çŽ¢ã¯Androidã¢ããªã±ãŒã·ã§ã³ã®ãã£ãšåããå§ãŸããç§ã®ãæ°ã«å ¥ãã§ããããã®ãªãã«ãŒã«ã®1ã€ã¯åžžã«-ãããžã§ã¯ããããŒã¿ããã¡ã€ã³ããã¬ãŒã³ããŒã·ã§ã³ã®3ã€ã®ççµåã¬ã€ã€ãŒã«åå²ããããšã§ããã ãããŠä»ãããäžåºŠãAndroidã¢ããªã±ãŒã·ã§ã³ã®ã¢ãŒããã¯ãã£ãã¿ãŒã³ã®æ°ãããã¬ã³ãã«ã€ããŠã€ã³ã¿ãŒãããã®åºããã調ã¹ããšãããçŽ æŽããããœãªã¥ãŒã·ã§ã³ã«åºããããŸããïŒ Android Clean Architecture ãããã§ãç§ã®è¬èãªæèŠã§ã¯ããã¹ãŠã倧äžå€«ã§ããïŒãæ°ã«å ¥ãã®ã¬ã€ã€ãŒãžã®åå²ãäŸåæ§æ³šå ¥ãå®è£ MVPãšããŠã®ãã¬ãŒã³ããŒã·ã§ã³ã¬ã€ã€ãŒã䜿ãæ £ããããŒã¿ã¬ã€ã€ãŒãªããžããªãã³ãã¬ãŒããšããŠãã䜿çšãããŸãã
ããããé·å¹ŽæãããŠãããã¶ã€ã³ã®ææ³ã«å ããŠãçºèŠã®å ŽããããŸããã InteractorïŒ1ã€ãŸãã¯è€æ°ã®ãšã³ãã£ãã£ãæäœããããã®ããžãã¹ããžãã¯ãå«ããªããžã§ã¯ãïŒã®æŠå¿µã玹ä»ããã®ã¯ãã®ãããžã§ã¯ãã§ããããªã¢ã¯ãã£ãããã°ã©ãã³ã°ã®åãæããã«ãããã®ãããã§ããã
ãªã¢ã¯ãã£ãããã°ã©ãã³ã°ãç¹ã«rxJava㯠ãéå»1幎éã§ããªã人æ°ã®ããã¬ããŒãããã³èšäºã®ãããã¯ã§ãããããã£ãŠããã®æè¡ã«ç°¡åã«æ £ããããšãã§ããŸãïŒãã¡ãããããã«ç²ŸéããŠããªãå Žåãé€ããŸãïŒãVIPERã«ã€ããŠã®è©±ãç¶ããŸãã
Android Clean Architectureã®ç¥èã¯ãæ¢åã®ãããžã§ã¯ãã®ãªãã¡ã¯ã¿ãªã³ã°ãšåæ§ã«ãæ°ãããããžã§ã¯ããrxJavaãšMVPã® 3ã€ã®ã¬ã€ã€ãŒã«åæžãããInteractorsããã¡ã€ã³ã¬ã€ã€ãŒãšããŠäœ¿çšãããããã«ãªã£ããšããäºå®ã«ã€ãªãããŸããã ç»é¢éã®é·ç§»ã®æ£ããå®è£ ã®åé¡ã¯æªè§£æ±ºã®ãŸãŸã§ãããããã§ã«ãŒã¿ãŒã®æŠå¿µã¯ãŸããŸãé »ç¹ã«èãããããã«ãªããŸããã æåã¯ãã«ãŒã¿ãŒã¯å€ç¬ã§ã¡ã€ã³ã¢ã¯ãã£ããã£ã«äœãã§ããŸããããã¢ããªã±ãŒã·ã§ã³ã«æ°ããç»é¢ã衚瀺ãããã«ãŒã¿ãŒãéåžžã«é¢åã«ãªãããã®åŸãå¥ã®ã¢ã¯ãã£ããã£ããã®ãã©ã°ã¡ã³ããšå ±ã«è¡šç€ºãããããã²ãŒã·ã§ã³ã«ã€ããŠçå£ã«èããªããã°ãªããŸããã§ããã ç»é¢éã®åãæ¿ããå«ããã¹ãŠã®åºæ¬çãªããžãã¯ã¯ãã¬ãŒã³ã¿ãŒã«å«ãŸããŠããŸãããããã£ãŠããã¬ãŒã³ã¿ãŒã¯ã«ãŒã¿ãŒã«ã€ããŠç¥ãå¿ èŠããããã«ãŒã¿ãŒã¯ç»é¢ãåãæ¿ããããã«ã¢ã¯ãã£ããã£ã«ã¢ã¯ã»ã¹ããå¿ èŠããããããã«ãŒã¿ãŒã¯ç¬èªã®ãã®ãæã¡ãåã¢ã¯ãã£ããã£ã«éä¿¡ãããå¿ èŠããããŸãäœææã®ãã¬ãŒã³ã¿ãŒã
ãããŠããäžåºŠããããžã§ã¯ããèŠããšããã¥ãŒãã€ã³ã¿ãŒã¢ã¯ã¿ãŒããã¬ãŒã³ã¿ãŒããšã³ãã£ãã£ãã«ãŒã¿ãŒãšããVIPERãããããšãããããŸããã
ãªãã¶ãŒããã«å³ã«æ°ã¥ãããšæããŸãããžã§ããæšé²ã®ãã¹ãŠã®åãé ãããŠããŸãã ããŒã¿ã¬ã€ã€ãŒã¯ãå¿ èŠãªè¡šçŸã§ãªã¢ãŒãã¹ãã¬ãŒãžãŸãã¯ããŒã«ã«ã¹ãã¬ãŒãžããããŒã¿ãååŸããã ãã§ãªããObservableã«ã©ãããããäžé£ã®ã¢ã¯ã·ã§ã³å šäœãInteractorã«æž¡ããŸããããã«ãããå®è£ ãããŠããã¿ã¹ã¯ã«åºã¥ããŠããã®ã·ãŒã±ã³ã¹ãèªç±ã«ç¶è¡ã§ããŸãã
次ã«ãAndroidã®VIPERå®è£ ã®å°ããªäŸãèŠãŠã¿ãŸãããïŒ ãœãŒã¹ ïŒïŒ
3ç§ããšã«ãããŸãæè»æ§ã®ãªãããµãŒããŒã«ã¡ãã»ãŒãžã®ãªã¹ããèŠæ±ããåéä¿¡è ã«å¯ŸããŠåŸè ã衚瀺ãããŠãŒã¶ãŒã«æ°ããã¡ãã»ãŒãžãéç¥ããã¢ããªã±ãŒã·ã§ã³ãéçºããã¿ã¹ã¯ã«çŽé¢ããŠãããšããŸãã æåŸã®ã¡ãã»ãŒãžãã¿ãããããšãéžæããéä¿¡è ã®ãã¹ãŠã®ã¡ãã»ãŒãžã®ãªã¹ãã衚瀺ãããŸãããã¡ãã»ãŒãžã¯åŒãç¶ã3ç§ããšã«ãµãŒããŒãšåæãããŸãã ãŸããã¡ã€ã³ç»é¢ããé£çµ¡å ãªã¹ãã«ã¢ã¯ã»ã¹ããŠããã®ãã¡ã®1ã€ã®ã¡ãã»ãŒãžããã¹ãŠè¡šç€ºã§ããŸãã
ããã§ã¯å§ããŸãããããã£ããïŒåé£çµ¡å ããã®æåŸã®ã¡ãã»ãŒãžïŒãç¹å®ã®é£çµ¡å ããã®ã¡ãã»ãŒãžã®ãªã¹ããé£çµ¡å ã®ãªã¹ãã®3ã€ã®ç»é¢ããããŸãã ã¯ã©ã¹å³ãæããŸãïŒ
ç»é¢ã¯ãã©ã°ã¡ã³ãã§ããããã®éã®é·ç§»ã¯ãã«ãŒã¿ãŒã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ããã¢ã¯ãã£ããã£ã«ãã£ãŠèŠå¶ãããŸãã åãã©ã°ã¡ã³ãã«ã¯ç¬èªã®ãã¬ãŒã³ã¿ãŒãããããã©ã°ã¡ã³ããšå¯Ÿè©±ããããã«å¿ èŠãªã€ã³ã¿ãŒãã§ãŒã¹ãå®è£ ããŸãã æ°ãããã¬ãŒã³ã¿ãŒãšãã©ã°ã¡ã³ãã®äœæã容æã«ããããã«ãåºæ¬çãªæœè±¡ã¯ã©ã¹BasePresenterãšBaseFragmentãäœæãããŸããã
BasePresenter-ãã¥ãŒããã³ã«ãŒã¿ãŒã€ã³ã¿ãŒãã§ã€ã¹ãžã®ãªã³ã¯ãå«ãŸãããã©ã°ã¡ã³ãã®ã©ã€ããµã€ã¯ã«ãç¹°ãè¿ã2ã€ã®æœè±¡ã¡ãœããonStartããã³onStopããããŸãã
public abstract class BasePresenter<View, Router> { private View view; private Router router; public abstract void onStart(); public abstract void onStop(); public View getView() { return view; } public void setView(View view) { this.view = view; } public Router getRouter() { return router; } public void setRouter(Router router) { this.router = router; } }
BaseFragment-BasePresenterã§äž»ãªäœæ¥ãå®è¡ããŸããåæåããŠå¯Ÿè©±ã€ã³ã¿ãŒãã§ã€ã¹ãonActivityCreatedã«æž¡ãã察å¿ããã¡ãœããã§onStartãšonStopãåŒã³åºããŸãã
Androidã¢ããªã±ãŒã·ã§ã³ã¯ãã¹ãŠActivityã§å§ãŸããŸãããã©ã°ã¡ã³ããåãæ¿ããããMainAcivityã¯1ã€ã ãã§ãã
äžèšã®ããã«ãã«ãŒã¿ãŒã¯ã¢ã¯ãã£ããã£å ã«ååšããŸããå ·äœçãªäŸã§ã¯ãMainActivityã¯ããããã®ã¢ã¯ãã£ããã£ã«å¯ŸããŠã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ããŸããããããã®ã«ãŒã¿ãŒã¯ãå éšã®ãã©ã°ã¡ã³ãéã®ããã²ãŒã·ã§ã³ãå¶åŸ¡ããŸãããããã£ãŠããã®ãããªã¢ã¯ãã£ããã£ã®åãã©ã°ã¡ã³ãã«ã¯ãåãã«ãŒã¿ãŒã䜿çšãããã¬ãŒã³ã¿ãŒãå¿ èŠã§ãïŒããããBaseMainPresenterãçãŸããæ¹æ³ã§ãããMainActivityã§äœæ¥ãããã¹ãŠã®ãã¬ãŒã³ã¿ãŒãç¶æ¿ããå¿ èŠããããŸãã
public abstract class BaseMainPresenter<View extends BaseMainView> extends BasePresenter<View, MainRouter> { }
MainActivityã§ãã©ã°ã¡ã³ããå€æŽãããšãããŒã«ããŒãšFloatingActionButtonã®ç¶æ ãå€åãããããåãã©ã°ã¡ã³ãã¯ã¢ã¯ãã£ããã£ã§å¿ èŠãªç¶æ ãã©ã¡ãŒã¿ãŒãå ±åã§ããå¿ èŠããããŸãã ãã®ãããªå¯Ÿè©±ã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ããã«ã¯ãBaseMainFragmentã䜿çšããŸãã
public abstract class BaseMainFragment extends BaseFragment implements BaseMainView { public abstract String getTitle(); // Toolbar @DrawableRes public abstract int getFabButtonIcon(); // FloatingActionButton // FloatingActionButton public abstract View.OnClickListener getFabButtonAction(); @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); MainActivity mainActivity = (MainActivity) getActivity(); // getPresenter().setRouter(mainActivity); // MainActivity Toolbar FloatingActionButton mainActivity.resolveToolbar(this); mainActivity.resolveFab(this); } @Override public void onDestroyView() { super.onDestroyView(); // getPresenter().setRouter(null); } âŠ. }
BaseMainViewã¯ãMainActivityã§ãã©ã°ã¡ã³ããäœæããããã®ãã1ã€ã®åºæ¬ãšã³ãã£ãã£ã§ã;ããã¯ãMainActivityã®ãã¹ãŠã®ãã¬ãŒã³ã¿ãŒãç¥ã£ãŠãã察話ã€ã³ã¿ãŒãã§ã€ã¹ã§ãã BaseMainViewã䜿çšãããšããšã©ãŒã¡ãã»ãŒãžã衚瀺ããŠã¢ã©ãŒãã衚瀺ã§ããŸãããã®ã€ã³ã¿ãŒãã§ã€ã¹ã¯BaseMainFragmentãå®è£ ããŸãã
... @Override public void showError(@StringRes int message) { Toast.makeText(getContext(), getString(message), Toast.LENGTH_LONG).show(); } @Override public void showNewMessagesNotification() { Snackbar.make(getView(), R.string.new_message_comming, Snackbar.LENGTH_LONG).show(); } ...
ãã®ãããªåºæ¬ã¯ã©ã¹ã®åœ¢åŒã§æºåãè¡ãããšã§ãMainActivityã®æ°ãããã©ã°ã¡ã³ããäœæããããã»ã¹ãå€§å¹ ã«å éãããŸãã
ã«ãŒã¿ãŒ
ãããŠãMainRouterã®çµæã¯æ¬¡ã®ãšããã§ãã
public interface MainRouter { void showMessages(Contact contact); void openContacts(); }
Interactractor
åãã¬ãŒã³ã¿ãŒã¯ã1ã€ä»¥äžã®ã€ã³ã¿ãŒã¢ã¯ã¿ãŒã䜿çšããŠããŒã¿ãæäœããŸãã Interactorã«ã¯ãexecuteãšunsubscribeã®2ã€ã®ãããªãã¯ã¡ãœãããããããŸãããã€ãŸããInteractorã¯ãå®è¡äžã®ããã»ã¹ããèµ·åããã³ãµãã¹ã¯ã©ã€ã解é€ã§ããŸãã
public abstract class Interactor<ResultType, ParameterType> { private final CompositeSubscription subscription = new CompositeSubscription(); protected final Scheduler jobScheduler; private final Scheduler uiScheduler; public Interactor(Scheduler jobScheduler, Scheduler uiScheduler) { this.jobScheduler = jobScheduler; this.uiScheduler = uiScheduler; } protected abstract Observable<ResultType> buildObservable(ParameterType parameter); public void execute(ParameterType parameter, Subscriber<ResultType> subscriber) { subscription.add(buildObservable(parameter) .subscribeOn(jobScheduler) .observeOn(uiScheduler) .subscribe(subscriber)); } public void unsubscribe() { subscription.clear(); } }
ãšã³ãã£ãã£
Interactorã¯ã1ã€ä»¥äžã®DataProviderã䜿çšããŠããŒã¿ã«ã¢ã¯ã»ã¹ããåŸç¶ã®å®è¡ã®ããã«rx.ObservableãçæããŸãã
ãã®äŸã®åé¡ã¹ããŒãã¡ã³ãã«ã¯ããµãŒããŒãžã®å®æçãªèŠæ±ã®å¿ èŠæ§ãå«ãŸããŠããŸãããããã¯ãRXã䜿çšããŠç°¡åã«å®è£ ã§ããŸããã
public static long PERIOD_UPDATE_IN_SECOND = 3; @Override public Observable<List<Message>> getAllMessages(Scheduler scheduler) { return Observable .interval(0, PERIOD_UPDATE_IN_SECOND, TimeUnit.SECONDS, scheduler) .flatMap(this::getMessages); }
äžèšã®ã³ãŒãäŸã¯ã3ç§ããšã«ã¡ãã»ãŒãžã®ãªã¹ããèŠæ±ãããµãã¹ã¯ã©ã€ããŒã«éç¥ãéä¿¡ããŸãã
ãããã«
ã¢ãŒããã¯ãã£ã¯ã¢ããªã±ãŒã·ã§ã³ã®éªšçµã¿ã§ããããããå¿ãããšãç°åžžãªçµæã«çµããå¯èœæ§ããããŸãã ã¬ã€ã€ãŒãšã¯ã©ã¹ã®ã¿ã€ãéã®è²¬ä»»ã®æ確ãªåå²ã«ããããµããŒãããã¹ãããããžã§ã¯ããžã®æ°ãã人ã®çŽ¹ä»ã容æã«ãªããããã°ã©ãã³ã°ã®çµ±äžã¹ã¿ã€ã«ã確ç«ãããŸãã åºæ¬ã¯ã©ã¹ã¯ã³ãŒãã®éè€ãé¿ããã®ã«åœ¹ç«ã¡ãrxã¯éåææ§ãèæ ®ããŸããã çæ³çãªã¢ãŒããã¯ãã£ãšçæ³çãªã³ãŒãã¯å®éã«ã¯éæã§ããŸãããããããã«åªåããããšã¯å°éçã«æé·ããããšãæå³ããŸãã
PSäžé£ã®èšäºãç¶ããããã®ã¢ã€ãã¢ããããå®è£ ã®èå³æ·±ãäºäŸã«ã€ããŠè©³ãã説æããŸãã
ãã¬ãŒã³ããŒã·ã§ã³å±€-ãã©ã°ã¡ã³ãã®ç¶æ ä¿åãè€åãã¥ãŒã
ãã¡ã€ã³å±€-è€æ°ã®ãµãã¹ã¯ã©ã€ããŒã®ã€ã³ã¿ã©ã¯ã¿ãŒã
ããŒã¿å±€-ãã£ãã·ã³ã°ã®çµç¹ã
èå³ãããã°ããã©ã¹èšå·ãå ¥ããŠãã ãã:)