上一天我们提到了 Domain Layer 会包含以下三个组件:CoEditor
, ContextMenu
, NoteRepository
,今天我们将着重在介面设计。
这个“共编器”将会提供所有的核心操作逻辑,基本的公开函式与变数如下:
class CoEditor {
val allVisibleNotes: Observable<List<String>>
val selectedNote: Observable<Optional<Note>>
fun selectNote(noteId: String)
fun clearSelection()
fun addNewNote()
fun moveNote(noteId: String, positionDelta: Position)
}
我们可以发现其实很多函式的介面跟之前的 EditorViewModel
一模一样,因为 EditorViewModel
在原本的架构中就是属於 Domain 层的元件,这样的结果一点都不奇怪。至於其他原本 EditorViewModel
有的公开函式但是必较偏向於选单操作的,我们将它搬移到了 ContextMenu
,介面如下:
class ContextMenu {
val colorOptions: List<YBColor>
val selectedColor: Observable<YBColor>
fun onColorSelected(color: YBColor)
fun onDeleteClicked()
fun onEditTextClicked()
}
如此一来我们就把原本属於 EditorViewModel
的职责一分为二了!onColorSelected
, onDeleteClicked
, onEditTextClicked
这些函式放在 ContextMenu
中也让第一眼看到这个类别的人,完全知道这类别可以做哪些事情,同时还有公开变数表示了所有颜色的选项 colorOptions
以及现在正在选的颜色 selectedColor
,这两个变数是给颜色选单显示用的变数,其实这样设计并没有很 “Domain”,这些是比较零散的知识,但是如果要为它再设计另一个阶层(像是 ColorMenu 之类的),又会觉得没有这个必要,所以我觉得目前这样放是一个比较好的选项。
还有 CoEditor
与 ContextMenu
这两个元件之间的关系是组合,CoEditor
拥有 ContextMenu
,但是 ContextMenu
并不是永远都是处於可见的状态,所以我另外新增了两个状态:showContextMenu, showAdderButton。
class CoEditor {
val showContextMenu: Observable<Boolean>
val showAdderButton: Observable<Boolean>
...
val contextMenu = ContextMenu()
}
最後是 CoEditor
与 NoteRepository
之间的关系,理所当然的,也是CoEditor
拥有 NoteRepository
,不然 CoEditor
将无法拿到所有便利贴的状态:
class CoEditor(private val noteRepository: NoteRepository)
NoteRepository
的实作将会是 Firebase 并且由 Dependency Injection framework 来提供。CoEditor
最後完整的公开函式会是像这样:
class CoEditor(private val noteRepository: NoteRepository) {
val allVisibleNotes: Observable<List<String>>
val selectedNote: Observable<Optional<Note>>
val showContextMenu: Observable<Boolean>
val showAdderButton: Observable<Boolean>
val openEditTextScreen: Observable<String> // 打开编辑文字页面,上面没提到
val contextMenu = ContextMenu()
fun selectNote(noteId: String)
fun clearSelection()
fun addNewNote()
fun moveNote(noteId: String, positionDelta: Position)
}
class ContextMenu {
val colorOptions: List<YBColor>
val selectedColor: Observable<YBColor>
fun onColorSelected(color: YBColor)
fun onDeleteClicked()
fun onEditTextClicked()
}
但这边还有一个问题,RxJava 一但绑定了,就必须要处理他的生命周期,CoEditor
一定也免不了这件事情发生,这也代表了这个类别中会有一些非同步的任务,所有的非同步任务都要好好的被处理,不然会有 memory leak 的问题发生,於是这个 CoEditor
也会是一个有生命周期的元件,其生命周期的事件将由外界控制:
class CoEditor(private val noteRepository: NoteRepository) {
....
private val disposableBag = CompositeDisposable()
fun start() { ... }
fun stop() { disposableBag.clear() }
}
通常来说一个具有生命周期的元件都是要有成对的生命周期事件,有死亡(stop)就要有出生(start),所有在 start
中被观察的 Observable 要在 stop
被好好的回收掉。
<<: Day16 Android - 不同fragment切换(ButtomNavigationView)
>>: Day 16:Next 布景客制化 - 让副标题显示於标题内
MySQL or MariaDB CentOS 的 rpm 套件管理器预设没有 MySQL repo...
Menu 这个套件应用的范围很广,之前讲解过的 Select 也是用这里的 MenuItem 来替换...
在这个人手一机的时代,没接触过网路的人应该不多吧,不管是购物、查资料、追剧都会用到网路,但这个每天都...
前言 生活在网际网路以及智慧型手机普及的今天,与外国朋友聊天、出国旅行、与国外客户开商务会议,纵使不...
今天要做的是... 做一个前端网页,支援拖动图片上传, 把图片转成 base64 送给服务器,服务器...