设计模式
使用Kotlin优化Java的设计模式写法
创建型模式
工厂方法模式
interface Computer {val cpu: String
}class PC(override val cpu: String = "Core") : Computer
class Server(override val cpu: String = "Xeon") : Computerenum class ComputerType {PC, Server
}class ComputerFactory {fun produce(type: ComputerType): Computer {return when (type) {ComputerType.PC -> PC()ComputerType.Server -> Server()}}
}
普通的工厂模式如上,调用时需要创建实例
val computer = ComputerFactory().produce(ComputerType.PC)
优化1:使用单例代替工厂类,使用object修饰
object ComputerFactory {fun produce(type: ComputerType): Computer {return when (type) {ComputerType.PC -> PC()ComputerType.Server -> Server()}}
}
这样就能省去创建过程,object会自动创建实例并调用
val computer = ComputerFactory.produce(ComputerType.PC)
优化2:使用operator重载invoke代替工厂方法名称
object ComputerFactory {operator fun invoke(type: ComputerType): Computer {return when (type) {ComputerType.PC -> PC()ComputerType.Server -> Server()}}
}
这样就能进一步省去创建过程,通过类名创建实例并调用
val computer = ComputerFactory(ComputerType.PC)
优化3:使用静态方法代替构造方法,将ComputerFactory移动到Computer接口里面
interface Computer {val cpu: Stringobject Factory {operator fun invoke(type: ComputerType): Computer {return when (type) {ComputerType.PC -> PC()ComputerType.Server -> Server()}}}
}
这样就不是通过创建实例调用,而是通过静态方法调用
val computer = Computer.Factory(ComputerType.PC)
于此同时,如果我们是Computer接口的使用者,我们不必通过继承实现新方法,可以通过扩展函数
fun Computer.Factory.fromCPU(cpu: String): ComputerType? = when (cpu) {"Core" -> ComputerType.PC"Xeon" -> ComputerType.Serverelse -> null
}
抽象工厂模式
interface Computer
class Dell : Computer
class Asus : Computer
class Acer : Computerabstract class AbstractFactory {abstract fun produce(): Computercompanion object {operator fun invoke(factory: AbstractFactory): AbstractFactory {return factory}}
}class DellFactory : AbstractFactory() {override fun produce() = Dell()
}
class AsusFactory : AbstractFactory() {override fun produce() = Asus()
}
class AcerFactory : AbstractFactory() {override fun produce() = Acer()
}
对于如上抽象工厂,调用时
val dellFactory = AbstractFactory(DellFactory())
val dell = dellFactory.produce()
优化1:使用内联函数代替抽象工厂创建过程
interface Computer
class Dell : Computer
class Asus : Computer
class Acer : Computerabstract class AbstractFactory {abstract fun produce(): Computercompanion object {inline operator fun <reified T : Computer> invoke(): AbstractFactory =when (T::class) {Dell::class -> DellFactory()Asus::class -> AsusFactory()Acer::class -> AcerFactory()else -> throw IllegalArgumentException()}}
}class DellFactory : AbstractFactory() {override fun produce() = Dell()
}
class AsusFactory : AbstractFactory() {override fun produce() = Asus()
}
class AcerFactory : AbstractFactory() {override fun produce() = Acer()
}
在使用时,可通过类型参数确认工厂类型类型
val dellFactory = AbstractFactory<Dell>()val dell = dellFactory.produce()
构建者模式
class Robot private constructor(val code: String,val battery: String?,val height: Int?,val weight: Int?
) {class Builder(val code: String) {private var battery: String? = nullprivate var height: Int? = nullprivate var weight: Int? = nullfun setBattery(battery: String?): Builder {this.battery = batteryreturn this}fun setHeight(height: Int): Builder {this.height = heightreturn this}fun setWeight(weight: Int): Builder {this.weight = weightreturn this}fun build(): Robot {return Robot(code, battery, height, weight)}}
}
对于上面的Robot类存在三个可选属性,通过如下创建
val robot = Robot.Builder("001").setBattery("A").setHeight(100).setWeight(80).build()
优化1:通过默认参数代替可选参数
class Robot(val code: String,val battery: String? = null,val height: Int? = null,val weight: Int? = null
)
在创建时可省略后面的可选参数或者指定某个可选参数
val robot1 = Robot("001")
val robot2 = Robot("001", battery = "A")
val robot3 = Robot("001", height = 100, weight = 80)
若builder中对参数有约束调节,如机器人的重量需要根据电池决定,未传入就会抛出错误
fun build(): Robot {if (weight != null && battery == null) {throw IllegalArgumentException("When setting weight, the battery cannot be empty")}else{return Robot(code, battery, height, weight)}
}
可以同样在init中增加约束,其通过require实现(未达到条件则抛出异常,判断条件和上面相反)
class Robot(val code: String,val battery: String? = null,val height: Int? = null,val weight: Int? = null
) {init {require(weight == null || battery != null) {"When setting weight, the battery cannot be empty"}}
}
行为型模式
观察者模式
class StockUpdate : Observable() {val observers = mutableSetOf<Observer>()fun setStockChanged(price: Int) {observers.forEach {it.update(this, price)}}
}
class StockDisplay : Observer {override fun update(o: Observable?, price: Any?) {if (o is StockUpdate) {println("The lastest stock price is ${price}")}}}
上面是Java标准库里面自带的观察者模式,调用如下
val su = StockUpdate()
val sd = StockDisplay()
su.observers.add(sd)
su.setStockChanged(100)
Observer 只有一个update方法,若有多个业务,则需要进行区分
优化1:通过委托代替观察者,参数为元数据KProperty、旧值、新值
interface StockUpdateListener {fun onRise(price: Int)fun onFall(price: Int)
}class StockDisplay : StockUpdateListener {override fun onRise(price: Int) {println("The lastest stock price has rise to ${price}")}override fun onFall(price: Int) {println("The lastest stock price has fall to ${price}")}
}class StockUpdate {var listeners = mutableListOf<StockUpdateListener>()var price: Int by Delegates.observable(0) { _, old, new ->listeners.forEach {if (new > old) it.onRise(price) else it.onFall(price)}}
}
当值发送改变会自动通知到观察者
val su = StockUpdate()
val sd = StockDisplay()
su.listeners.add(sd)
su.price = 100
su.price = 98
优化2:使用Vecoable对新值进行截获,初始值为0,只有正数时才能修改
var value: Int by Delegates.vetoable(0) { property, oldValue, newValue ->newValue > 0
}
value = 1
println(value)
value = -1
println(value)
策略模式
interface SwimStrategy {fun swim()
}
class Breaststroke : SwimStrategy {override fun swim() {println("Breaststroke")}
}
class Backstroke : SwimStrategy {override fun swim() {println("Backstroke")}
}
class Freestyle : SwimStrategy {override fun swim() {println("Freestyle")}
}class Swimmer(val strategy: SwimStrategy) {fun swim() {strategy.swim()}
}
如上对于游泳,有不同的策略,在使用时指定算法
val weekendShaw = Swimmer(Freestyle())
weekendShaw.swim()
val weekdaysShaw = Swimmer(Breaststroke())
weekdaysShaw.swim()
优化1:使用高阶函数代替继承
fun breaststroke() {println("breaststroke")
}
fun backstroke() {println("backstroke")
}
fun freestyle() {println("freestyle")
}
class Swimmer(val swimming: () -> Unit) {fun swim() {swimming()}
}
使用时可通过方法引用,也可使用变量存储Lambda函数传入
val weekendShaw = Swimmer(::freestyle)
weekendShaw.swim()
val weekdaysShaw = Swimmer(::breaststroke)
weekdaysShaw.swim()
模板方法模式
abstract class CivicCenterTask {fun execute() {this.lineUp()this.askForHelp()this.evaluate()}private fun lineUp() {println("line up")}private fun evaluate() {println("evaluate")}abstract fun askForHelp()
}class PullSocialSecurity : CivicCenterTask() {override fun askForHelp() {println("PullSocialSecurity")}
}class ApplyForCitizenCard : CivicCenterTask() {override fun askForHelp() {println("ApplyForCitizenCard")}
}
如上,各个子类有不同的askForHelp()方法,调用时会根据方法实现各自的需求
val pss = PullSocialSecurity()
pss.execute()
val afcc = ApplyForCitizenCard()
afcc.execute()
优化1:使用高阶函数代替继承
class CivicCenterTask {fun execute(askForHelp: () -> Unit) {this.lineUp()askForHelp()this.evaluate()}private fun lineUp() {println("line up")}private fun evaluate() {println("evaluate")}
}
private fun pullSocialSecurity() {println("pullSocialSecurity")
}
private fun applyForCitizenCard() {println("ApplyForCitizenCard")
}
使用时传入方法引用
val task1 = CivicCenterTask()
task1.execute(::pullSocialSecurity)
val task2 = CivicCenterTask()
task1.execute(::applyForCitizenCard)
迭代器模式
通常实现迭代器模式可以通过实现Iterator接口
data class Book(val name: String)class Bookcase(val books: List<Book>) : Iterator<Book> {private val iterator: Iterator<Book>init {this.iterator = books.iterator()}override fun hasNext() = this.iterator.hasNext()override fun next() = this.iterator.next()
}
遍历时
val bookcase = Bookcase(listOf(Book("A"), Book("B"))
)
for (book in bookcase) {println()
}
优化1:通过重载iterator()代替继承
class Bookcase(val books: List<Book>) {operator fun iterator(): Iterator<Book> = this.books.iterator()
}
优化2:通过扩展函数iterator()代替继承,适用于不能修改源码的情况
data class Book(val name: String)
class Bookcase(val books: List<Book>) {
}
operator fun Bookcase.iterator(): Iterator<Book> = this.books.iterator()
还可以通过object表达式来实现
operator fun Bookcase.iterator(): Iterator<Book> = object :Iterator<Book>{val iterator = books.iterator()override fun hasNext() = iterator.hasNext()override fun next() = iterator.next()
}
责任链模式
data class ApplyEvent(val money: Int)interface ApplyHandler {val successor: ApplyHandler?fun handleEvent(event: ApplyEvent)
}class GroupLeader(override val successor: ApplyHandler?) : ApplyHandler {override fun handleEvent(event: ApplyEvent) {when {event.money <= 100 -> println("GroupLeader yes")else -> when (successor) {is ApplyHandler -> successor.handleEvent(event)else -> throw IllegalStateException()}}}
}class President(override val successor: ApplyHandler?) : ApplyHandler {override fun handleEvent(event: ApplyEvent) {when {event.money <= 500 -> println("President yes")else -> when (successor) {is ApplyHandler -> successor.handleEvent(event)else -> throw IllegalStateException()}}}
}class College(override val successor: ApplyHandler?) : ApplyHandler {override fun handleEvent(event: ApplyEvent) {when {event.money <= 1000 -> println("College yes")else -> throw IllegalStateException()}}
}
上面是常见的责任链模式,通过判断传递事件
val college = College(null)
val president = President(college)
val groupLeader = GroupLeader(president)
groupLeader.handleEvent(ApplyEvent(10))
groupLeader.handleEvent(ApplyEvent(200))
优化1:通过偏函数简化责任链,定义如下,defineAt()和isDefinedAt()判断是否符合条件,f()处理事件,orElse()传递责任链
class PartialFunction<in P1, out R>(private val defineAt: (P1) -> Boolean,private val f: (P1) -> R
) {operator fun invoke(p1: P1): R {if (defineAt(p1)) {return f(p1)} else {throw IllegalArgumentException()}}fun isDefinedAt(p1: P1) = defineAt(p1)
}infix fun <P1, R> PartialFunction<P1, R>.orElse(that: PartialFunction<P1, R>): PartialFunction<P1, R> {return PartialFunction({ this.isDefinedAt(it) || that.isDefinedAt(it) }) {when {this.isDefinedAt(it) -> this(it)else -> that(it)}}
}
责任链定义如下,每一个责任链都是PartialFunction,传入判断条件和处理过程
data class ApplyEvent(val money: Int)val groupLeader = {val defineAt: (ApplyEvent) -> Boolean = { it.money <= 100 }val handler: (ApplyEvent) -> Unit = { println("groupLeader yes") }PartialFunction(defineAt, handler)
}()val president = {val defineAt: (ApplyEvent) -> Boolean = { it.money <= 500 }val handler: (ApplyEvent) -> Unit = { println("president yes") }PartialFunction(defineAt, handler)
}()val college = {val defineAt: (ApplyEvent) -> Boolean = { true }val handler: (ApplyEvent) -> Unit = {when {it.money < 1000 -> println("college yes")else -> println("college no")}}PartialFunction(defineAt, handler)
}()
调用过程如下,通过orElse()传递责任链
val applyChain = groupLeader orElse president orElse college
applyChain(ApplyEvent(600))
状态模式
优化1:采用密封类来约束状态
结构型模式
装饰器模式
优化1:使用委托简化装饰过程
interface MacBook {fun getCost(): Intfun getDesc(): Stringfun getProdDate(): String
}class MacBookPro : MacBook {override fun getCost() = 10000override fun getDesc() = "MacBookPro"override fun getProdDate() = "2022"
}class ProcessorUpgradeMacbookPro(val macBook: MacBook) : MacBook by macBook {override fun getCost() = macBook.getCost() + 2000override fun getDesc() = macBook.getDesc() + ",+1G Memory"
}
如上,ProcessorUpgradeMacbookPro只需要复写需要的方法,其他方法调用时会自动委托给macBook变量
val macbookPro = MacBookPro()
val processorUpgradeMacbookPro = ProcessorUpgradeMacbookPro(macbookPro)
println(processorUpgradeMacbookPro.getCost())
println(processorUpgradeMacbookPro.getDesc())
优化2:通过扩展代替装饰者
class Printer{fun drawLine(){println("————————————")}fun drawDottedLine(){println("------------")}fun drawStars(){println("************")}
}
如对上面的类,利用扩展函数装饰方法,调用前后输出字符串
fun Printer.startDraw(decorated: Printer.() -> Unit){println("start drawing")decorated()println("end drawing")
}
调用过程如下
Printer().run {startDraw { drawLine() }startDraw { drawDottedLine() }startDraw { drawStars() }
}