å ¬åŒAndroidã¢ããªã±ãŒã·ã§ã³ã¢ãŒããã¯ãã£ã¬ã€ãã§ã¯ããªããžããªã¯ã©ã¹ã䜿çšããŠãã¢ããªã±ãŒã·ã§ã³ã®æ®ãã®éšåãããŒã¿ãç°¡åã«ååŸã§ããããã«ã¯ãªãŒã³ãªAPIãæäŸãããããšãæšå¥šããŠããŸãããã ããç§ã®æèŠã§ã¯ããããžã§ã¯ãã§ãã®ãã¿ãŒã³ã䜿çšãããšãåä»ãªã¹ãã²ããã£ã³ãŒãã«è¡ãè©°ãŸãããšãä¿èšŒãããŸãã
ãã®èšäºã§ã¯ãããªããžããªãã¿ãŒã³ãã«ã€ããŠèª¬æãããããå®éã«Androidã¢ããªã±ãŒã·ã§ã³ã®ã¢ã³ããã¿ãŒã³ã§ããçç±ã説æããŸãã
ãªããžããª
åè¿°ã®ã¢ããªã±ãŒã·ã§ã³ã¢ãŒããã¯ãã£ã¬ã€ãã§ã¯ããã¬ãŒã³ããŒã·ã§ã³å±€ããžãã¯ãç·šæããããã«æ¬¡ã®æ§é ãæšå¥šããŠã
ãŸãããã®æ§é ã§ã®ãªããžããªãªããžã§ã¯ãã®åœ¹å²ã¯æ¬¡ã®ãšããã§ã
ããªããžããªã¢ãžã¥ãŒã«ã¯ããŒã¿æäœãåŠçããŸãããããã¯ã¯ãªãŒã³ãªAPIãæäŸãããããã¢ããªã±ãŒã·ã§ã³ã®æ®ãã®éšåã¯ãã®ããŒã¿ãç°¡åã«ååŸã§ããŸãã圌ãã¯ãããŒã¿ãååŸããå ŽæãšãããŒã¿ãæŽæ°ããããšãã«ã©ã®APIåŒã³åºããè¡ãããç¥ã£ãŠããŸãããªããžããªã¯ãæ°žç¶ã¢ãã«ãWebãµãŒãã¹ããã£ãã·ã¥ãªã©ã®ããŸããŸãªããŒã¿ãœãŒã¹éã®ä»²ä»ãšèããããšãã§ããŸãã
åºæ¬çã«ãã¬ã€ãã§ã¯ããªããžããªã䜿çšããŠã¢ããªã±ãŒã·ã§ã³ã®ããŒã¿ãœãŒã¹ãæœè±¡åããããšãæšå¥šããŠããŸãããšãŠããªãŒãºããã«ã§äŸ¿å©ã«èãããŸããã
ãã ãããã£ããã¯ããã°ãæããïŒãã®å Žåã¯ã³ãŒããæžãïŒã®ã§ã¯ãªããUMLå³ã䜿çšããŠã¢ãŒããã¯ãã£ã®ãããã¯ãæããã«ããããšãå¿ããªãã§ãã ãããã¢ãŒããã¯ãã£ãã¿ãŒã³ã®å®éã®ãã¹ãã¯ãã³ãŒãã§ã®å®è£ ãšããã®é·æãšçæã®ç¹å®ã§ããããã§ã¯ãã¬ãã¥ãŒããæœè±¡åºŠã®äœããã®ãèŠã€ããŸãããã
Androidã¢ãŒããã¯ãã£ãã«ãŒããªã³ãv2ã®ãªããžããª
çŽ2幎åãAndroid ArchitectureBlueprintsã®ãæåã®ããŒãžã§ã³ãã確èªããŸãããçè«çã«ã¯ãã¯ãªãŒã³ãªMVPã®äŸãå®è£ ããããšã«ãªã£ãŠããŸãããå®éã«ã¯ããããã®éåçã¯ããªãæ±ãã³ãŒãããŒã¹ã«ãªããŸããããããã«ã¯Viewããã³Presenterãšããååã®ã€ã³ã¿ãŒãã§ã€ã¹ãå«ãŸããŠããŸããããã¢ãŒããã¯ãã£ã®å¢çãèšå®ããŠããªãã£ããããæ¬è³ªçã«MVPã§ã¯ãããŸããã§ãããããªãã¯ããã§äžããããã³ãŒãã¬ãã¥ãŒãèŠãããšãã§ããŸãã
ãã以æ¥ãGoogleã¯ãKotlinãViewModelãããã³ãªããžããªãå«ããã®ä»ã®ãææ°ã®ãææ³ã䜿çšããŠãã¢ãŒããã¯ãã£ã®éåçãæŽæ°ããŠããŸããããããã®æŽæ°ããããã«ãŒããªã³ãã«ã¯ãv2ãšãããã¬ãã£ãã¯ã¹ãä»ããŠããŸããv2ãã«ãŒããªã³ãã®TasksRepository
ã€ã³ã¿ãŒãã§ãŒã¹ãèŠãŠã¿ãŸãããã
interface TasksRepository {
fun observeTasks(): LiveData<Result<List<Task>>>
suspend fun getTasks(forceUpdate: Boolean = false): Result<List<Task>>
suspend fun refreshTasks()
fun observeTask(taskId: String): LiveData<Result<Task>>
suspend fun getTask(taskId: String, forceUpdate: Boolean = false): Result<Task>
suspend fun refreshTask(taskId: String)
suspend fun saveTask(task: Task)
suspend fun completeTask(task: Task)
suspend fun completeTask(taskId: String)
suspend fun activateTask(task: Task)
suspend fun activateTask(taskId: String)
suspend fun clearCompletedTasks()
suspend fun deleteAllTasks()
suspend fun deleteTask(taskId: String)
}
ã³ãŒããèªãåã§ãããã®ã€ã³ã¿ãŒãã§ã€ã¹ã®ãµã€ãºã«æ³šæãæãããšãã§ããŸããããã¯ãã§ã«ãŠã§ã€ã¯ã¢ããã³ãŒã«ã§ãã1ã€ã®ã€ã³ã¿ãŒãã§ã€ã¹ã§ãã®ãããªæ°ã®ã¡ãœããã䜿çšãããšã倧èŠæš¡ãªAndroidãããžã§ã¯ãã§ãçåãçããŸãããããã§ã¯ãã³ãŒãã2000è¡ãããªãToDoã¢ããªã±ãŒã·ã§ã³ã«ã€ããŠèª¬æããŠããŸãããªããã®ããªãäºçŽ°ãªã¢ããªã±ãŒã·ã§ã³ããã®ãããªå·šå€§ãªAPIãµãŒãã§ã¹ãæã€ã¯ã©ã¹ãå¿ èŠãšããã®ã§ããïŒ
ç¥ã®ãªããžã§ã¯ããšããŠã®ãªããžããª
åã®ã»ã¯ã·ã§ã³ã®è³ªåã«å¯Ÿããåçã¯ãTasksRepositoryã¡ãœããã®ååã§ã«ããŒãããŠããŸãããã®ã€ã³ã¿ãŒãã§ãŒã¹ã®ã¡ãœããã¯ãéè€ããªã3ã€ã®ã°ã«ãŒãã«å€§ãŸãã«åããããšãã§ããŸãã
ã°ã«ãŒã1ïŒ
fun observeTasks(): LiveData<Result<List<Task>>>
fun observeTask(taskId: String): LiveData<Result<Task>>
ã°ã«ãŒã2ïŒ
suspend fun getTasks(forceUpdate: Boolean = false): Result<List<Task>>
suspend fun refreshTasks()
suspend fun getTask(taskId: String, forceUpdate: Boolean = false): Result<Task>
suspend fun refreshTask(taskId: String)
suspend fun saveTask(task: Task)
suspend fun deleteAllTasks()
suspend fun deleteTask(taskId: String)
ã°ã«ãŒã3ïŒ
suspend fun completeTask(task: Task)
suspend fun completeTask(taskId: String)
suspend fun clearCompletedTasks()
suspend fun activateTask(task: Task)
suspend fun activateTask(taskId: String)
次ã«ãäžèšã®åã°ã«ãŒãã®è²¬ä»»ç¯å²ãå®çŸ©ããŸãããã
ã°ã«ãŒã1ã¯åºæ¬çã«ãLiveDataæ©èœã䜿çšãããªãã¶ãŒããŒãã¿ãŒã³ã®å®è£ ã§ããã°ã«ãŒã2ã¯ãããŒã¿ã¹ãã¢ãžã®ã²ãŒããŠã§ã€ã«å ããŠ
refresh
ããªã¢ãŒãããŒã¿ã¹ãã¢ããªããžããªã®èåŸã«é ããŠããããã«å¿
èŠãª2ã€ã®ã¡ãœããã§ããã°ã«ãŒã3ã«ã¯ãåºæ¬çã«ã¢ããªã±ãŒã·ã§ã³ãã¡ã€ã³ããžãã¯ã®2ã€ã®éšåïŒã¿ã¹ã¯ã®å®äºãšã¢ã¯ãã£ãåïŒãå®è£
ããæ©èœã¡ãœãããå«ãŸããŠããŸãã
ãããã£ãŠããã®1ã€ã®ã€ã³ã¿ãŒãã§ã€ã¹ã«ã¯3ã€ã®ç°ãªã責任ããããŸããããããšãŠã倧ããã®ãäžæè°ã§ã¯ãããŸããããŸããåäžã®ã€ã³ã¿ãŒãã§ã€ã¹ã®äžéšãšããŠ1çªç®ãš2çªç®ã®ã°ã«ãŒããååšããããšã¯èš±å®¹ã§ãããšäž»åŒµã§ããŸããã3çªç®ã®ã°ã«ãŒããè¿œå ããããšã¯äžåœã§ãããã®ãããžã§ã¯ããããã«éçºããå¿ èŠãããããããå®éã®Androidã¢ããªã±ãŒã·ã§ã³ã«ãªãå Žåã3çªç®ã®ã°ã«ãŒãã¯ãããžã§ã¯ãå ã®ãã¡ã€ã³ã¹ããªãŒã ã®æ°ã«æ£æ¯äŸããŠæé·ããŸããããŒãã
éåžžã«å€ãã®è²¬ä»»ãå ±æããã¯ã©ã¹ã«ã¯ãç¥èãªãªããžã§ã¯ããšããç¹å¥ãªçšèªããããŸããããã¯ãAndroidã¢ããªã±ãŒã·ã§ã³ã§åºã䜿çšãããŠããã¢ã³ããã¿ãŒã³ã§ãã ActivitieãšFragmentã¯ããã®ã³ã³ããã¹ãã§ã¯æšæºçãªå®¹çè ã§ãããä»ã®ã¯ã©ã¹ãDivineãªããžã§ã¯ãã«çž®éããå¯èœæ§ããããŸããç¹ã«ååãããããŒãžã£ãŒãã§çµãã£ãŠãããšãããïŒ
åŸ ã£ãŠãã ãã... TasksRepositoryã®ããè¯ãååãèŠã€ãããšæããŸãïŒ
interface TasksManager {
fun observeTasks(): LiveData<Result<List<Task>>>
suspend fun getTasks(forceUpdate: Boolean = false): Result<List<Task>>
suspend fun refreshTasks()
fun observeTask(taskId: String): LiveData<Result<Task>>
suspend fun getTask(taskId: String, forceUpdate: Boolean = false): Result<Task>
suspend fun refreshTask(taskId: String)
suspend fun saveTask(task: Task)
suspend fun completeTask(task: Task)
suspend fun completeTask(taskId: String)
suspend fun activateTask(task: Task)
suspend fun activateTask(taskId: String)
suspend fun clearCompletedTasks()
suspend fun deleteAllTasks()
suspend fun deleteTask(taskId: String)
}
çŸåšããã®ã€ã³ã¿ãŒãã§ãŒã¹ã®ååã¯ããã®è²¬ä»»ãã¯ããã«ããåæ ããŠããŸãã
ã¢ãããã¯ãªããžããª
ããã§ãããã¡ã€ã³ããžãã¯ããªããžããªãããã«ãããšãåé¡ã¯è§£æ±ºããŸããïŒããšè³ªåããå ŽåããããŸããããŠãGoogleããã¥ã¢ã«ã®ãã¢ãŒããã¯ãã£å³ãã«æ»ããŸãããã
ããšãã°
completeTask
ãTasksRepositoryããã¡ãœãããæœåºãããå Žåãããããã©ãã«é
眮ããŸããïŒGoogleãæšå¥šãããã¢ãŒããã¯ãã£ãã«ãããšããã®ããžãã¯ãViewModelã®1ã€ã«ç§»åããå¿
èŠããããŸãããããªã«æªã決æã§ã¯ãªãããã§ãããæ¬åœã«ããã§ãã
ããšãã°ããã®ããžãã¯ã1ã€ã®ViewModelã«é 眮ããŠãããšããŸãã次ã«ã1ãæåŸãã¢ã«ãŠã³ããããŒãžã£ãŒã¯ããŠãŒã¶ãŒãè€æ°ã®ç»é¢ããã¿ã¹ã¯ãå®äºã§ããããã«ããããšèããŠããŸãïŒããã¯ããããŸã§ã«äœ¿çšãããã¹ãŠã®ToDoãããŒãžã£ãŒã«é¢é£ããŠããŸãïŒã ViewModelå ã®ããžãã¯ã¯åå©çšã§ããªããããè€è£œããããTasksRepositoryã«è¿ãå¿ èŠããããŸããæããã«ãã©ã¡ãã®ã¢ãããŒããæªãã§ãã
ããè¯ãã¢ãããŒãã¯ããã®ãã¡ã€ã³ã¹ããªãŒã ãã«ã¹ã¿ã ãªããžã§ã¯ãã«æœåºãããããViewModelãšãªããžããªã®éã«é 眮ããããšã§ãããã®åŸãããŸããŸãªViewModelããã®ãªããžã§ã¯ããåå©çšããŠããã®ç¹å®ã®ã¹ã¬ãããå®è¡ã§ããããã«ãªããŸãããããã®ãªããžã§ã¯ãã¯ãããŠãŒã¹ã±ãŒã¹ããŸãã¯ãçžäºäœçšããšããŠç¥ãããŠããŸã..ããã ããã³ãŒãããŒã¹ã«ãŠãŒã¹ã±ãŒã¹ãè¿œå ãããšããªããžããªã¯æ¬è³ªçã«åœ¹ã«ç«ããªããã³ãã¬ãŒãã«ãªããŸãã圌ããäœãããã«ããŠããããã¯ãŠãŒã¹ã±ãŒã¹ã«ããããé©åããŸãã Gabor Varadiã¯ãã®èšäºã§ãã®ãããã¯ããã§ã«åãäžããŠããã®ã§ã詳现ã«ã¯è§ŠããŸãããç§ã¯åœŒãã貧匱ãªãªããžããªãã«ã€ããŠèšã£ãã»ãšãã©ãã¹ãŠã賌èªããŸãã
ãããããªããŠãŒã¹ã±ãŒã¹ã¯ãªããžããªãããã¯ããã«åªããŠããã®ã§ãããããçãã¯ç°¡åã§ãããŠãŒã¹ã±ãŒã¹ã¯åå¥ã®ã¹ããªãŒã ãã«ãã»ã«åããŸãããããã£ãŠãåŸã ã«Divineãªããžã§ã¯ãã«æé·ãã1ã€ã®ãªããžããªïŒãã¡ã€ã³ã³ã³ã»ããããšïŒã®ä»£ããã«ãããã€ãã®éåžžã«çŠç¹ãçµã£ããŠãŒã¹ã±ãŒã¹ã¯ã©ã¹ããããŸããã¹ããªãŒã ããããã¯ãŒã¯ãšä¿åãããŠããããŒã¿ã«äŸåããŠããå Žåã¯ãé©åãªæœè±¡åããŠãŒã¹ã±ãŒã¹ã¯ã©ã¹ã«æž¡ãããšãã§ãããããã®ãœãŒã¹éã§ã調åããããŸãã
äžè¬ã«ãäžèŠãªæœè±¡åãåé¿ããªããããªããžããªãDivineã¯ã©ã¹ã«å£åããã®ãé²ãå¯äžã®æ¹æ³ã¯ããªããžããªãåé€ããããšã§ããããã«èŠããŸãã
Android以å€ã®ãªããžããªã
ããã§ããªããžããªãGoogleã®çºæã§ãããã©ããçåã«æããããããããŸããããããããã§ã¯ãããŸããããªããžããªãã¿ãŒã³ã¯ãGoogleãã¢ãŒããã¯ãã£ã¬ã€ãã§äœ¿çšããããšã決å®ãããã£ãšåã«èª¬æãããŠããŸããã
ããšãã°ãMartin Fowlerã¯ã圌ã®èæžãPatterns of EnterpriseApplicationArchitectureãã§ãªããžããªã«ã€ããŠèª¬æããŠããŸãã圌ã®ããã°ã«ã¯ãåãæŠå¿µã説æããã²ã¹ãèšäºããããŸãã Fowlerã«ãããšããªããžããªã¯ã¹ãã¬ãŒãžå±€ã®åãªãã©ãããŒã§ãããé«ã¬ãã«ã®ã¯ãšãªã€ã³ã¿ãŒãã§ã€ã¹ãšãå Žåã«ãã£ãŠã¯ã¡ã¢ãªå ã®ãã£ãã·ã¥ãæäŸããŸãããã¡ãŠã©ãŒã®èŠ³ç¹ããã¯ããªããžããªã¯ORMã®ããã«åäœããŸãã
Eric Evansã¯ã圌ã®èæžDomain DrivenDesignã§ãªããžããªã«ã€ããŠã説æããŠããŸãã圌ãæžããŸããïŒ
, , , â . , . , , .
äžèšã®åŒçšã®ããªããžããªãããã«ãŒã ORMãã«çœ®ãæããããšãã§ããããã§ãæå³ãããããšã«æ³šæããŠãã ããããããã£ãŠããã¡ã€ã³ããªãã³ãã¶ã€ã³ã®ã³ã³ããã¹ãã§ã¯ããªããžããªã¯ORMã§ãïŒæåã§å®è£ ããããããµãŒãããŒãã£ã®ãã¬ãŒã ã¯ãŒã¯ã䜿çšããŠå®è£ ãããŸãïŒã
ã芧ã®ãšããããªããžããªã¯Androidã®äžçã§ã¯çºæãããŠããŸãããããã¯ããã¹ãŠã®ORMãã¬ãŒã ã¯ãŒã¯ãæ§ç¯ãããŠããéåžžã«å¥å šãªèšèšãã¿ãŒã³ã§ãããã ãããªããžããªãããã§ã¯ãªãããšã«æ³šæããŠãã ããããªããžããªããããã¯ãŒã¯ã¢ã¯ã»ã¹ãšããŒã¿ããŒã¹ã¢ã¯ã»ã¹ã®éããæœè±¡åããããšããã¹ãã ãšäž»åŒµãããå€å žãã¯ãããŸããã
å®éãç§ã¯åœŒãããã®ã¢ã€ãã¢ãçŽ æŽã§èªæ» çã ãšæãã ãããšç¢ºä¿¡ããŠããŸãããã®çç±ãç解ããããã«ãä»åã¯Joel SpolskyïŒStackOverflowã®åµèšè ïŒã«ããå¥ã®èšäºãèªãããšãã§ããŸãããæŒãã®ããæœè±¡åã®æ³åããç°¡åã«èšãã°ããããã¯ãŒãã³ã°ã¯ããŒã¿ããŒã¹ã¢ã¯ã»ã¹ãšã¯å€§ããç°ãªããé倧ãªãªãŒã¯ã¯ãããŸããã
Androidã§ãªããžããªãã¢ã³ããã¿ãŒã³ã«ãªã£ãçµç·¯
ããã§ãGoogleã¯ãªããžããªãã¿ãŒã³ã誀ã£ãŠè§£éãããããã¯ãŒã¯ã¢ã¯ã»ã¹ãæœè±¡åãããšããçŽ æŽãªã¢ã€ãã¢ãå°å ¥ããŸãããïŒçãããããã®GitHubãªããžããªã§ã
ãã®ã¢ã³ããã¿ãŒã³ãžã®æãå€ããªã³ã¯ãèŠã€ããŸãããããã¯ãæ®å¿µãªããéåžžã«äººæ°ã®ãããªãœãŒã¹ã§ãããã®ç¹å®ã®äœè ããã®ã¢ã³ããã¿ãŒã³ãçºæãããã©ããã¯ããããŸããããAndroidãšã³ã·ã¹ãã å ã§äžè¬çãªã¢ã€ãã¢ãåºããã®ã¯ãã®ãªããžããªã ã£ãããã§ããGoogleéçºè ã¯ãããããããããããŸãã¯2次ãœãŒã¹ã®1ã€ããå ¥æããŸããã
çµè«
ãã®ãããAndroidã®ãªããžããªã¯ã¢ã³ããã¿ãŒã³ã«ãªã£ãŠããŸããçŽã®äžã§ã¯èŠæ ããããŸãããäºçŽ°ãªã¢ããªã±ãŒã·ã§ã³ã§ãåé¡ãçºçãã倧èŠæš¡ãªãããžã§ã¯ãã§ã¯å®éã®åé¡ã«ã€ãªããå¯èœæ§ããããŸãã
ããšãã°ãå¥ã®Googleãã«ãŒããªã³ãã§ã¯ãä»åã¯ã¢ãŒããã¯ãã£ã³ã³ããŒãã³ãã«ã€ããŠããªããžããªã䜿çšãããšãæçµçã«NetworkBoundResourceãªã©ã®gemãäœæãããŸããããµã³ãã«ãã©ãŠã¶ã®GitHubã¯ãŸã å°ããªã2KLOCã¢ããªã§ããããšã«æ³šæããŠãã ããã
ç§ã®ç¥ãéããå ¬åŒããã¥ã¡ã³ãã§å®çŸ©ãããŠããããªããžããªãã¿ãŒã³ãã¯ãã¯ãªãŒã³ã§ä¿å®å¯èœãªã³ãŒããšäºææ§ããããŸããã
èªãã§ããã ãããããšãããããŸãããã€ãã®ããã«ãã³ã¡ã³ãã質åã以äžã«æ®ããŠãã ããã