设计模式
使用Kotlin优化Java的设计模式写法
创建型模式
工厂方法模式
interface Computer {
val cpu: String
}
class PC(override val cpu: String = "Core") : Computer
class Server(override val cpu: String = "Xeon") : Computer
enum 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: String
object 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.Server
else -> null
}
抽象工厂模式
interface Computer
class Dell : Computer
class Asus : Computer
class Acer : Computer
abstract class AbstractFactory {
abstract fun produce(): Computer
companion 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 : Computer
abstract class AbstractFactory {
abstract fun produce(): Computer
companion 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? = null
private var height: Int? = null
private var weight: Int? = null
fun setBattery(battery: String?): Builder {
this.battery = battery
return this
}
fun setHeight(height: Int): Builder {
this.height = height
return this
}
fun setWeight(weight: Int): Builder {
this.weight = weight
return 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(): Int
fun getDesc(): String
fun getProdDate(): String
}
class MacBookPro : MacBook {
override fun getCost() = 10000
override fun getDesc() = "MacBookPro"
override fun getProdDate() = "2022"
}
class ProcessorUpgradeMacbookPro(val macBook: MacBook) : MacBook by macBook {
override fun getCost() = macBook.getCost() + 2000
override 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() }
}
本站资源均来自互联网,仅供研究学习,禁止违法使用和商用,产生法律纠纷本站概不负责!如果侵犯了您的权益请与我们联系!
转载请注明出处: 免费源码网-免费的源码资源网站 » Kotlin基础——优化设计模式
发表评论 取消回复