设计模式之Kotlin实现(下)

本篇涉及11种行为型设计模式,分别是职责链模式、命令模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式、访问者模式和解释器模式。

职责链模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
interface Thing {}
class Apple : Thing {}
class Orange : Thing {}
abstract class Member(open var name: String) {
var next: Member? = null
fun doThing(thing: Thing) {
if (resolve(thing)) {
done(thing);
} else {
next?.doThing(thing)?: fail(thing)
}
}
abstract fun resolve(thing: Thing): Boolean
protected fun done(thing: Thing) {
println("被${this}吃掉")
}
protected fun fail(thing: Thing) {
println("不能被吃掉")
}
override fun toString(): String {
return "[${name}]"
}
}
class Child(override var name: String): Member(name) {
override fun resolve(thing: Thing): Boolean {
return false
}
}
class Mom(override var name: String) : Member(name) {
override fun resolve(thing: Thing): Boolean {
if (thing is Apple)
return true
return false
}
}
class Father(override var name: String) : Member(name) {
override fun resolve(thing: Thing): Boolean {
return true
}
}
fun main(args: Array<String>) {
var child = Child("小宝贝")
child.next = Mom("妈妈")
child.next?.next = Father("爸爸")
child.doThing(Orange())
}

构造一个链表,然后依次让链表上的元素处理事物,期间一旦某元素能处理事物则不会再让后续元素处理。

命令模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Receiver {
fun rMethod01(name: String) {
println("方法的名称是:$name")
}
fun rMethod02(name: String) {
println("方法的名称是:$name")
}
}
class Invoker {
var command: Command? = null
constructor(command: Command) {
this.command = command
}
fun invoker() {
command?.let { it.command01("command01") }
}
}
class Command() {
var receiver: Receiver? = Receiver()
var command01: ((String) -> Unit) = { name -> receiver?.rMethod01(name) }
}
fun main(args: Array<String>) {
Invoker(Command()).invoker()
}

Kotlin自称把函数当第一公民,但是表达能力是没有Scala强的,不过在这里可以使用Lambda表达式替代传统面向对象编程来对命令模式进行编写。

编写中遇到了bug,详细描述见文末参考。

迭代器模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
interface Iterator {
fun next(): Any
fun hasNext(): Boolean
}
class ImlIterator(var imlIteratorProduct: ImlIteratorProduct) : Iterator {
var index: Int = 0
override fun next(): Any {
var s = imlIteratorProduct.arr[index]
index++
return s
}
override fun hasNext(): Boolean {
if (index < imlIteratorProduct.arr.size)
return true
return false
}
}
interface IteratorProduct {
fun iterator(): Iterator
}
class ImlIteratorProduct : IteratorProduct {
var arr = arrayListOf<String>("chenchen", "guoguo", "nini", "haohao")
override fun iterator(): Iterator {
return ImlIterator(this)
}
}
fun main(args: Array<String>) {
var imlIteratorProduct = ImlIteratorProduct()
var iter = imlIteratorProduct.iterator()
while (iter.hasNext()) {
println(iter.next() as String)
}
}

迭代器模式旨在实现一个简单的迭代器。

中介者模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class AA(var name: String) {
fun doSomething(mediator: Mediator) {
mediator.aMethod()
}
}
class BB(var name: String) {
fun doSomething(mediator: Mediator) {
mediator.bMethod()
}
}
class Mediator {
var a: AA
var b: BB
constructor(a: AA, b: BB) {
this.a = a
this.b = b
}
fun aMethod() {
println("${a.name} 在前,${b.name} 在后。")
}
fun bMethod() {
println("${b.name} 在前,${a.name} 在后。")
}
}
fun main(args: Array<String>) {
var a = AA("小A")
var b = BB("小B")
var mediator = Mediator(a, b)
a.doSomething(mediator)
b.doSomething(mediator)
}

避免对象之间直接交互,彼此实现看不见对方,中介者作为平台处理对象之间的关系。

备忘录模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class Memento(var state: String?)
class Originator {
var state: String? = null
fun saveState(): Memento {
return Memento(state)
}
fun restoreState(memento: Memento) {
this.state = memento.state
}
}
class CareTaker {
private var list = ArrayList<Memento>()
fun add(memento: Memento) {
list.add(memento)
}
fun get(index: Int): Memento {
return list[index]
}
}
fun main(args: Array<String>) {
var originator = Originator()
var careTaker = CareTaker()
originator.state = "存档01"
careTaker.add(originator.saveState())
originator.state = "存档02"
println("当前存档:${originator.state}")
originator.restoreState(careTaker.get(0))
println("当前存档:${originator.state}")
}

这里涉及到三个角色Memento、Originator以及CareTaker,本人将Memento理解为记忆点,将Originator理解为记忆点的创造者,而把CareTaker理解为记忆点的存储者。

观察者模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
internal interface Subject {
fun registerObserver(o: Observer)
fun removeObserver(o: Observer)
fun notifyObserver()
}
// 具体被观察者
internal class ConcreteSubject : Subject {
private val cs: ArrayList<Observer> = ArrayList()
private var `when`: String? = null
private var where: String? = null
private var what: String? = null
override fun registerObserver(o: Observer) {
cs.add(o)
}
override fun removeObserver(o: Observer) {
val i = cs.indexOf(o)
if (i >= 0) {
cs.removeAt(i)
}
}
override fun notifyObserver() {
for (i in cs.indices) {
val o = cs[i]
o.update(`when`, where, what)
}
}
fun reSetData(`when`: String?, where: String?, what: String?) {
this.`when` = `when`
this.where = where
this.what = what
notifyObserver()
}
}
// 观察者
internal interface Observer {
fun update(`when`: String?, where: String?, what: String?)
}
// 具体观察者
internal class ConcreteObserver : Observer, Message {
private var `when`: String? = null
private var where: String? = null
private var what: String? = null
private var subject: Subject?
constructor(subject: Subject?) {
this.subject = subject
subject?.registerObserver(this)
}
override fun update(`when`: String?, where: String?, what: String?) {
this.`when` = `when`
this.where = where
this.what = what
message()
}
override fun message() {
println("收到订阅通知:\n时间:$`when`\n地点:$where\n事件:$what")
}
}
internal interface Message {
fun message()
}
fun main(args: Array<String>) {
var s = ConcreteSubject()
var o = ConcreteObserver(s)
s.reSetData("早上十点", "叙利亚", "停战")
}

代码的核心在于对被观察者、具体的被观察者、观察者、具体的观察者的编写。订阅的行为交给观察者,而信息的通知对于观察者来说是被动的。

状态模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
internal abstract class State {
abstract fun addContext(context: Context)
override fun toString(): String {
return this.javaClass.simpleName
}
}
internal class Context {
var state: State? = null
}
internal class StartState : State() {
override fun addContext(context: Context) {
println("打印开始状态名:")
context.state = this
}
}
internal class StopState : State() {
override fun addContext(context: Context) {
println("打印停止状态名:")
context.state = this
}
}
fun main(args: Array<String>) {
var context = Context()
StartState().addContext(context)
println(context.state)
StopState().addContext(context)
println(context.state)
}

不用方法来判断状态,而是采用类。

策略模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
interface Strategy {
fun algori(num01: Double, num02: Double): Double
}
class `加` : Strategy {
override fun algori(num01: Double, num02: Double): Double {
return num01 + num02
}
}
class `减` : Strategy {
override fun algori(num01: Double, num02: Double): Double {
return num01 - num02
}
}
class `乘` : Strategy {
override fun algori(num01: Double, num02: Double): Double {
return num01 * num02
}
}
class `除` : Strategy {
override fun algori(num01: Double, num02: Double): Double {
if (num02.equals(0.0)) {
throw IllegalArgumentException("错误的被除数输入!")
}
return num01 / num02
}
}
class StrategyContext(var strategy: Strategy) {
fun operator(num01: Double, num02: Double): Double {
return strategy.algori(num01, num02)
}
}
fun main(args: Array<String>) {
// 计算除法
var context = StrategyContext(`除`())
println(context.operator(5.0, 0.0))
}

不用if语句切换算法,而是采用类的多态。这里和观察者模式一样采用了``。

模板方法模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
abstract class AbstractClass {
abstract fun doThing01()
abstract fun doThing02()
fun display() {
doThing01()
doThing02()
}
}
class ConcreteClass : AbstractClass() {
override fun doThing01() {
println("我是doThing01!")
}
override fun doThing02() {
println("我是doThing02!")
}
}
fun main(args: Array<String>) {
var concreteClass = ConcreteClass()
concreteClass.display()
}

模版方法模式就是在父类中定义流程框架,在子类中实现具体处理。

访问者模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
abstract class Element(open var name: String) {
fun accept(visitor: Visitor) {
visitor.visit(this)
}
}
class Element01(override var name : String) : Element(name)
class Visitor {
fun visit(element: Element) {
println("被访问者的名字是:${element.name}")
}
}
fun main(args: Array<String>) {
var visitor = Visitor()
var element01 = Element01("Element01")
element01.accept(visitor)
}

公共接口为被访问者提供接受访问的方法(也就是以访问者为参数传入),在接受方法内,访问者调用访问方法访问被访问者。

解释器模式

小结

Why must class member function types be called with invoke?

Smart cast doesn’t work for nullable value of functional type