当前位置:   article > 正文

Kotlin入门之Kotlin中的设计模式_kotlin 设计模式

kotlin 设计模式

由四位大师提出的23种设计模式,对于程序的复用性有很大的意义,这里对于Kotlin中自己了解的几种设计模式进行介绍。

  • 设计模式的六大原则:

  • 单一职责原则:就一个类而言,应该仅有一个引起它变化的原因。
  • 开放封闭原则:类、模块、函数等应该是可以拓展的,但是不可修改。
  • 里氏替换原则:所有引用基类的地方必须能透明地使用其子类的对象。
  • 依赖倒置原则:高层模块不应该依赖底层模块,两者都应该依赖与抽象。抽象不应该依赖于细节,细节应该依赖于抽象。
  • 迪米特原则:一个软件实体应当尽可能少与其他实体发生相互作用。
  • 接口隔离原则:一个类对另一个类的依赖应该建立在最小的接口上。
  • 23种设计模式如下:

  • 创建型:单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。
  • 构造型:适配器模式、装饰模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
  • 行为型:策略模式、模板方法模式、观察者模式、迭代器模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

下面将全部介绍。(注意下面的模式都是基于Kotlin来讲解的)

  1. 单例模式
    众所周知,单例模式,在系统之中只能有一个实例。因此,想要在Java中实现它,就必须对构造方法私有化,使用static。
    而在Kotlin中我们可以利用object关键字的特性,来实现单例模式。object声明的类全局只能有一个,因此,我们可以像声明普通的类那样声明一个单例类。
object CarClass{
    var type:Int = 2
    //一些方法......
}
  • 1
  • 2
  • 3
  • 4

之后,我们在主方法之中这样调用它。发现即使我们想普通的类那样声明无论多少个它,我们都只会得到一个它的实例,这里我通过修改一个实例的值,所有的引用的结果都会更改,来证明它是一个单例。

fun main(args:Array<String>){
    val type = CarClass
    val type1 = CarClass
    type.type = 3
    println(type.type)
    println(type1.type)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

输出结果:
3
3


  • 线程安全的懒汉单例模式。
class DeepCleanUpdater private constructor(){
    companion object {
        private var instance:DeepCleanUpdater? = null
        get() {
            if (field != null) {
                return field
            }
            return DeepCleanUpdater()
        }
        @Synchronized
        fun get():DeepCleanUpdater {
            return instance!!
        }
        private val TAG:String = "DeepCleanUpdater"
        private var DEBUG:Boolean = false
        private var mEnable:Boolean = true
    }
    private var mContext:Context? = null
    
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  1. 访问者模式
    在Kotlin中对于复杂的模式的匹配,需要我们使用访问者模式,来对我们的代码进行优化,否则,很容易造成逻辑炸弹,对于代码的修改和后期的维护代码很大的麻烦。对于Kotlin中的访问者模式,我们使用sealed来实现访问者模式。
    在下面的例子中,我们通过对我们的内容进行匹配的例子进行一次演示。比如:判断0是不是0?
    首先我们创建我们可以进行的操作的函数的类。
sealed class Expr{
    abstract fun isZero():Boolean //判断是否为零
    abstract fun isAddZero():Boolean //判断操作是不是加零
    abstract fun simplifyExpr():Expr //
    val v = CarClass.vistor //Visitor的实例
    class Num(val value:Int): Expr(){
        override fun isAddZero(): Boolean = v.matchAddZero(this)
        override fun isZero(): Boolean = v.matchZero(this)
        override fun simplifyExpr(): Expr = v.doSimplifyExpr(this)
    }
    class Operate(val opName:String, val left:Expr, val right:Expr):Expr(){
        override fun isAddZero(): Boolean = v.matchZero(this)
        override fun isZero(): Boolean = v.matchAddZero(this)
        override fun simplifyExpr(): Expr = this
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

我们再定义,我们具体的操作实现类,也就是具体的逻辑代码。

class Vistor{
    fun matchAddZero(expr: Expr.Num):Boolean = false
    fun matchAddZero(expr: Expr.Operate):Boolean = when (expr){
        Expr.Operate("+", expr.left, Expr.Num(0)) -> true
        Expr.Operate("+", Expr.Num(0), expr.right) -> true
        else -> false
    }
    fun matchZero(expr: Expr.Num):Boolean = expr.value == 0
    fun matchZero(expr: Expr.Operate):Boolean = false
    fun doSimplifyExpr(expr: Expr.Num): Expr = expr
    fun doSimplifyExpr(expr: Expr.Operate, v:Vistor):Expr = when{
        (expr.right is Expr.Num && v.matchAddZero(expr) && v.matchAddZero(expr.right)) &&
                (expr.right is Expr.Operate && expr.right.left is Expr.Num) &&
                v.matchZero(expr.right.left) -> expr.right.left
        else -> expr
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

我们考虑到大量的Vistor的实例的调用,我们将实例化的它放入我们前面单例模式提到的单例中:

object CarClass{
    val vistor:Vistor = Vistor()
}
  • 1
  • 2
  • 3

在主函数中调用我们的函数。

fun main(args:Array<String>) {

    println(Expr.Num(0).isZero())
  • 1
  • 2
  • 3

输出:
true

  1. 工厂模式
    工厂模式是我们常用的设计模式。在Kotlin中可以使用伴生对象或者单例模式对它进行优化。
  • 伴生对象优化
class PC(override val cpu:String = "Core"):Computer
class Server(override val cpu:String = "Xeon"):Computer
enum class ComputerType{
    PC, Server
}
interface Computer{
    val cpu:String
    //伴生对象优化
    companion object {
        operator fun invoke(type:ComputerType):Computer{
            return when(type){
                ComputerType.PC -> PC()
                ComputerType.Server -> Server()
            }
        }
    }
}
fun main(args:Array<String>) {
    println(Computer(ComputerType.PC).cpu)//输出Core
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 单例模式优化
class PC(override val cpu:String = "Core"):Computer
class Server(override val cpu:String = "Xeon"):Computer
enum class ComputerType{
    PC, Server
}
interface Computer{
    val cpu:String
}
object ComputerFactory{
//重载invoke来代替内部的方法来创建工厂
    operator fun invoke(type: ComputerType):Computer{
        return when(type){
            ComputerType.PC -> PC()
            ComputerType.Server -> Server()
        }
    }
}
fun main(args:Array<String>) {
    println(ComputerFactory(ComputerType.PC).cpu)//输出Core
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  1. 抽象工厂模式
    使用抽象工厂模式,我们可以为创建一组相关或相互依赖的对象提供一个接口,而且无需指定它们的具体类。在Kotlin中我们使用内联函数来优化它。给出一个例子:
interface Computer{
    val cpu:String
}
class Dell(override val cpu:String = "Dell"):Computer
class Asus(override val cpu:String = "Asus"):Computer
class Acer(override val cpu:String = "Acer"):Computer

abstract class AbstractFactory{
    abstract fun produce():Computer
    companion object {
    //内联优化
        inline operator fun<reified T:Computer> invoke():AbstractFactory =
                when(T::class){
                    Dell::class -> DellAbstractFactory()
                    Asus::class -> AsusAbstractFactory()
                    Acer::class -> AcerAbstractFactory()
                    else -> throw IllegalArgumentException()
                }
    }
}
class DellAbstractFactory:AbstractFactory(){
    override fun produce(): Computer = Dell()
}
class AsusAbstractFactory:AbstractFactory(){
    override fun produce(): Computer = Asus()
}
class AcerAbstractFactory:AbstractFactory(){
    override fun produce(): Computer = Acer()
}
fun main(args:Array<String>) {
    val dellFactory = AbstractFactory<Dell>()
    val dell = dellFactory.produce()
    println(dell.cpu)//输出Dell
}
  • 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
  1. 构建者模式
    一个对象创建时可能具有很多的参数需要我们手动赋值,或者一些参数我们并不想在一开始就赋值,又或者一些参数之间存在约束关系。这个时候我们就需要用到我们的构建者模式了。
    先看一下常规的构建者模式:
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)
        }
    }
}
fun main(args:Array<String>) {
    val robot = Robot.Builder(code = "001")
    val re = robot.setBattery("R1")
            .setHeight(12)
            .setWeight((13))
            .build()
    println(re.battery)//输出R1
}
  • 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

在Kotlin中我们可以直接使用如下方法来实现:

class Robot1(
        val code:String,
        val battery: String? = null, 
        val height: Int? = null,
        val weight: Int? = null
)
fun main(args:Array<String>) {
    val robot1 = Robot1(code= "002", battery = "R2", height =12 )
    println(robot1.battery)//输出R2
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

另外,想要设定参数之间的限定关系,可以使用require关键字

class Robot1(
        val code:String,
        val battery: String? = null,
        val height: Int? = null,
        val weight: Int? = null
){
    init {
    //不符合条件报错
        require(weight == null || battery != null){
            "电池型号设定好后方可设置重量"
        }
    }
}

fun main(args:Array<String>) {
    val robot1 = Robot1(code= "002", weight = 12 )
    println(robot1.battery)
 }
 //报错:java.lang.IllegalArgumentException: 电池型号设定好后方可设置重量
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  1. 观察者模式
    有Android开发经验的人,一定经常使用这个设计模式。许多设计都是基于观察者模式进行开发的,如MVC架构、rxJava类库的设计等。以及视图变化的逻辑响应。我们看看观察者模式的定义:
    观察者模式定义了一个多对一的依赖关系,让一个或多个观察者对象监听一个主题对象。这样一来,当被观察者状态发生改变时,需要通知相应的观察者,使这些观察者对象能够自动更新。
    在Kotlin中我们可以使用Observable来实现,举个例子:
interface StockUpdateListener{
    fun onRise(price: Int)
    fun onFall(price: Int)
}
class StockDisplay: StockUpdateListener{
    override fun onRise(price: Int) {
        println("升值到${price}了")
    }
    override fun onFall(price: Int) {
        println("贬值到${price}了")
    }
}
class StockUpdate{
    var listeners = mutableSetOf<StockUpdateListener>()
    var price: Int by Delegates.observable(0){ _, old, new ->
        listeners.forEach{ if(new > old ) it.onRise(price) else it.onFall(price)}
    }
}
fun main(args:Array<String>) {
    val su = StockUpdate()
    val sd = StockDisplay()
    var sd1 = StockDisplay()
    su.listeners.add(sd)
    su.listeners.add(sd1)
    su.price = 100
    su.price = 98
    //输出
    //升值到100了
//    升值到100了
//    贬值到98了
//    贬值到98了
}
  • 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

另外,我们还可以使用Vetoable来对于不符合规定的值进行驳回:

interface StockUpdateListener{
    fun onRise(price: Int)
    fun onFall(price: Int)
}
class StockDisplay: StockUpdateListener{
    override fun onRise(price: Int) {
        println("升值到${price}了")
    }
    override fun onFall(price: Int) {
        println("贬值到${price}了")
    }
}
class StockUpdate{
    //回调函数
    fun test_price(price: Int):Boolean{
    //判断条件
        if(price > 0){
            listeners.forEach { it.onRise(price) }
            return true
        }else{
            println("价格不可为负数")
            return false
        }
    }
    var listeners = mutableSetOf<StockUpdateListener>()
    var price: Int by Delegates.vetoable(0){prop, old, new ->
        test_price(new)
    }
}
fun main(args:Array<String>) {
    val su = StockUpdate()
    val sd = StockDisplay()
    var sd1 = StockDisplay()
    su.listeners.add(sd)
    su.listeners.add(sd1)
    su.price = 100
    su.price = -98//被驳回
    //输出
    // 升值到100了
//    升值到100了
//    价格不可为负数
}
  • 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
  1. 策略模式
    策略模式做的事情就是将不同的行为策略进行独立封装,与类在逻辑上解耦。然后根据不同的上下文切换选择不同的策略,然后用类对象进行调用。在Kotlin中我们使用高阶函数对它进行实现。
    举例:
fun breaststroke(){
    println("蛙泳")
}
fun backstroke(){
    println("仰泳")
}
fun freestyle(){
    println("自由泳")
}
class Swimmer(private val swimmer:()-> Unit){
    fun swim(){
        swimmer()
    }
}
fun main(args:Array<String>) {
    val swimmer = Swimmer(::freestyle)
    val swimmer1 = Swimmer(::backstroke)
    swimmer.swim()
    swimmer1.swim()
    //输出:
    //自由泳
//    仰泳
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  1. 模板模式
    定义一个算法中的操作框架,而将一些步骤延迟到子类中,使得子类可以不改变算法的结构即可重定义该算法的某些特定步骤。这里我们同样使用高阶函数进行实现:
class CivicCenterTask{
    fun execute(askForHelp:() -> Unit){
        this.lineUp()
        askForHelp()
        this.evaluate()
    }
    private fun lineUp(){
        println("排队")
    }
    private fun evaluate(){
        println("评价")
    }
}
fun pullSociaSecurity(){
    println("安全服务")
}
fun applyForCitizenCard(){
    println("申请卡")
}
fun main(args:Array<String>) {
    val task = CivicCenterTask()
    task.execute(::pullSociaSecurity)
    task.execute(::applyForCitizenCard)
//    输出
//    排队
//    安全服务
//    评价
//    排队
//    申请卡
//    评价
}
  • 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
  1. 迭代器模式
    将遍历和实现分离开,在遍历的同时不需要暴露对象的内部实现。Kotlin中我们使用扩展函数实现:
data class Book(val name:String)
class Bookecase(val books: List<Book>){}
operator fun Bookecase.iterator():Iterator<Book> = 
                          books.iterator()
  • 1
  • 2
  • 3
  • 4
  1. 责任链模式
    避免请求的发送者和接收者之间的耦合关系,将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。在Kotlin中我们使用偏函数实现。
    偏函数:数学中的概念,指的是定义域X中可能存在某些值在值域Y中没有对应的值。
    Kotlin的标准库并没有实现PartialFunction。我们自己使用开源库的类型。
//偏函数
class PartialFunction<in P1, out R>(private val definetAt:(P1) -> Boolean, private val f:(P1) -> R):(P1) -> R{
    override fun invoke(p1: P1): R {
        if(definetAt(p1)){
            return f(p1)
        }else{
            throw IllegalArgumentException("Value: ($p1) isn't supported by this function")
        }
    }
    fun isDefinedAt(p1: P1) = definetAt(p1)
}
//使用infix关键字让orElse成为一个中缀函数
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)
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

我们编写具体的情况:

data class ApplyEvent(val money:Int, val title: String)
//第一层
val groupLeader = {
    //低于200可以批准
    val definetAt: (ApplyEvent) -> Boolean = {it.money <= 200}
    val handler:(ApplyEvent) -> Unit = { println("Group Leader handled application:${it.title}.")}
    PartialFunction(definetAt, handler)
}()
//第二层
val president = {
    //低于500可以批准
    val definetAt: (ApplyEvent) -> Boolean = {it.money <= 500}
    val handler:(ApplyEvent) -> Unit = { println("President handled application:${it.title}.")}
    PartialFunction(definetAt, handler)
}()
//第三层
val college = {
    //500到1000予以批准
    val definetAt: (ApplyEvent) -> Boolean = {true}
    val handler:(ApplyEvent) -> Unit = {
        when{
            it.money > 1000 -> println("College: This application is refused.")
            else -> println("College handled application:${it.title}.")
        }
     }
    PartialFunction(definetAt, handler)
}()
fun main(args:Array<String>) {
    val applyChain = groupLeader orElse president orElse college
    applyChain(ApplyEvent(1600, "玩一哈"))
    //输出:College: This application is refused.
}
  • 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
  1. 状态模式
    状态模式允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。
    示例:
class Off(override val machine: WaterMachine): WaterMachineState(machine)
class Heating(override val machine: WaterMachine): WaterMachineState(machine)
class Cooling(override val machine: WaterMachine): WaterMachineState(machine)
class WaterMachine{
    var state: WaterMachineState
    var off = Off(this)
    val heating = Heating(this)
    val cooling = Cooling(this)

    init {
        this.state = off
    }
    fun turnHeating(){
        this.state.turnHeating()
    }
    fun turnCooling(){
        this.state.turnCooling()
    }
    fun turnOff(){
        this.state.turnOff()
    }
}
sealed class WaterMachineState(open val machine:WaterMachine){
    fun turnHeating(){
        if(this !is Heating){
            println("加热开始")
            machine.state = machine.heating
        }else{
            println("已经是制热了")
        }
    }
    fun turnCooling(){
        if(this !is Cooling){
            println("制冷")
            machine.state = machine.cooling
        }else{
            println("已经切换到制冷模式了")
        }
    }
    fun turnOff(){
        if(this !is Off){
            println("关闭")
            machine.state = machine.off
        }else{
            println("已经关闭了")
        }
    }
}
enum class Moment{
    EARLY_MORNING,//早上上班
    DRINKING_WATER,//日常饮水
    INSTANCE_NOODLES,//Shaw 吃泡面
    AFTER_WORK //下班
}
fun waterMachineOps(machine: WaterMachine, moment:Moment){
    when(moment){
        Moment.EARLY_MORNING,
        Moment.DRINKING_WATER -> when(machine.state){
            !is Cooling -> machine.turnCooling()
        }
        Moment.INSTANCE_NOODLES -> when(machine.state){
            !is Heating -> machine.turnHeating()
        }
        Moment.AFTER_WORK -> when(machine.state){
            !is Off -> machine.turnOff()
        }
        else -> Unit
    }
}
fun main(args:Array<String>) {
   val machine = WaterMachine()
    waterMachineOps(machine, Moment.DRINKING_WATER)
    waterMachineOps(machine, Moment.INSTANCE_NOODLES)
    waterMachineOps(machine, Moment.DRINKING_WATER)
    waterMachineOps(machine, Moment.AFTER_WORK)
//    输出
//    制冷
//    加热开始
//    制冷
//    关闭
}
  • 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
  • 78
  • 79
  • 80
  • 81
  1. 装饰器模式
    由于,我们要遵循里氏原则,在对一个类的行为进行扩展的时候,有时不得不放弃继承它的子类来扩展,这时候,我们就需要用到装饰器模式了。
    定义:再不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。该模式通过创建一个包装对象,来包裹真实的对象。
    在Kotlin中我们可以通过两种方式来实现:类委托、扩展函数
  • 委托示例:
interface MacBook{
    fun getCost(): Int
    fun getDesc(): String
    fun getProdDate():String
}
class MacBookPro: MacBook{
    override fun getCost(): Int  = 10000
    override fun getDesc(): String = "Mackbook Pro"
    override fun getProdDate(): String  = "Late 2011"
}
class ProcessorUpgradeMacbookPro(val macbook:MacBook): MacBook by macbook{
    override fun getCost(): Int  = macbook.getCost() + 777
    override fun getDesc(): String = macbook.getDesc().plus("  ,1G内存")
    override fun getProdDate(): String  = macbook.getProdDate()
}
fun main(args:Array<String>) {
   val macBookPro = MacBookPro()
    val processorUpgradeMacbookPro = ProcessorUpgradeMacbookPro(macBookPro)
    println(processorUpgradeMacbookPro.getCost())
    println(processorUpgradeMacbookPro.getDesc())
    println(processorUpgradeMacbookPro.getProdDate())
    //    输出
//    10777
//    Mackbook Pro  ,1G内存
//    Late 2011
}
  • 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
  • 扩展方式示例:
class MacBookPro: MacBook{
    fun drawLine(){
        println("--------")
    }
    fun drawDottedLine(){
        println("- - - - -")
    }
    fun drawStars(){
        println("*********")
    }
}
fun MacBookPro.startDraw(decorated: MacBookPro.() -> Unit){
    println("+++ 开始 +++")
    this.decorated()
    println("+++ 结束 +++")
}
fun main(args:Array<String>) {
   MacBookPro().run {
       startDraw { drawLine() }
       startDraw { drawDottedLine() }
       startDraw { drawStars() }
   }
//    +++ 开始 +++
//    --------
//    +++ 结束 +++
//    +++ 开始 +++
//    - - - - -
//    +++ 结束 +++
//    +++ 开始 +++
//    *********
//    +++ 结束 +++
}
  • 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

介绍完成。有帮助不妨点个赞。
13. 外观模式

一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。

// 结婚
class Action1 {
    fun action1(){}
}
// 生子
class Action2 {
    fun action2(){}
}
// 火葬场
class Action3 {
    fun action3(){}
}
// 张三的一生,一个接口搞定
class ZhangSan {
    companion object {
        val ac1:Action1 = Action1()
        val ac2:Action2 = Action2()
        val ac3:Action3 = Action3()
    }
    fun action() {
        ac1.action1()
        ac2.action2()
        ac3.action3()
    }
}
  • 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
  1. 享元模式
    运用共享技术来有效地支持大量细粒度对象的复用。它通过共享已经存在的对象来大幅度减少需要创建的对象数量、避免大量相似类的开销,从而提高系统资源的利用率。
创建对象存储起来,保持引用,可以重复利用。
  • 1
  1. 桥接模式
    将抽象与实现分离,使它们可以独立变化。
// 具体实现类
interface Impletor {
    fun request()
}
// 实现类
class ImpletorA:Impletor{
    override fun request() {
        println("具体实现类")
    }
}
// 抽象角色
abstract class Abstractor(imple:Impletor) {
    protected val imple = imple
    protected abstract fun absRequest()
}
// 扩展抽象化角色
class AbstractorA(imple: Impletor):Abstractor(imple) {
    override fun absRequest() {
        imple.request()
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  1. 适配器模式
    将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。
// 目标接口
interface Target {
    fun request()
}
// 类适配器类
open class Adapter {
    fun specificRequest() {
        println("适配者代码")
    }
}
// 在这里可以直接使用已有的代码
class ClassAdapter : Adapter(), Target {
    override fun request() {
        specificRequest()
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  1. 代理模式
    由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。
// 目标接口
interface Subject {
    fun request()
}
// 真正要访问的类
class RealSubject : Subject {
    override fun request() {
        println("真实方法")
    }
}
// 代理类
class Proxy : Subject {
    val realSubject:RealSubject = RealSubject()
    override fun request() {
        // 一些预操作
        realSubject.request()
        // 后续操作
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  1. 简单工厂模式
    就是只有一个工厂的模式。
import java.lang.IllegalArgumentException

// 接口
interface Product 
// 两个产品
class Product1 : Product
class Product2: Product
// 工厂
class Factory  {
    fun produce(p:Int): Product {
        return when(p) {
            1 -> Product1()
            2 -> Product2()
            else -> throw IllegalArgumentException()
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  1. 组合模式
    有时又叫作整体-部分(Part-Whole)模式,它是一种将对象组合成树状的层次结构的模式,用来表示“整体-部分”的关系,使用户对单个对象和组合对象具有一致的访问性,属于结构型设计模式。
// 接口
interface Product {
    fun op()
}
// 两个产品
class Product1 : Product{
    override fun op() {
        println("操作1")
    }
}
class Product2: Product{
    override fun op() {
        println("操作2")
    }
}

/*使用
val a:Product = Product1()
val b:Product = Product2()
a.op()
b.op()
*/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  1. 命令模式
    将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理。
// 调用者
data class Invoker(private val command:Command) {
    fun call() {
        command.exe()
    }
}
// 命令
interface Command {
    fun exe()
}
// 不止这一种
class SpecificCommand : Command {
    private val receiver:Receiver = Receiver()
    override fun exe() {
        receiver.action()
    }
    
}
// 接收者
class Receiver {
    fun action() {
        println("接收者行为")
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  1. 中介模式
    :定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用。
// 抽象中介
abstract class Mediator {
    abstract fun register(colleague:Colleague)
    abstract fun relay(colleague:Colleague)
}
// 具体中介
class ConcreateMidator : Mediator() {
    private val colleagues:MutableList<Colleague> = mutableListOf()
    // 维护联系的同事们
    override fun register(colleague: Colleague) {
        if (!colleagues.contains(colleague)) {
            colleagues.add(colleague)
            colleague.setMedium(this)
        }
    }
    // 干群发的活
    override fun relay(colleague: Colleague) {
        colleagues.forEach { if (it != colleague) it.receive()}
    }
}
// 同事类
abstract class Colleague {
    protected var media:Mediator? = null

    fun setMedium(media:Mediator) {
        this.media = media
    }
    abstract fun receive()
    abstract fun send()
}
// 具体同事1
class ConcreateColleague1 :Colleague() {
    override fun receive() {
        println("同事1收消息")
    }

    override fun send() { // 发消息触发群发
        println("同事1发消息")
        media?.relay(this)
    }
}
// 具体同事2
class ConcreateColleague2 :Colleague() {
    override fun receive() {
        println("同事2收消息")
    }

    override fun send() {
        println("同事2发消息")
        media?.relay(this)
    }
}
  • 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
  1. 备忘录模式
    在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。该模式又叫快照模式.
  2. 解释器模式
    给分析对象定义一个语言,并定义该语言的文法表示,再设计一个解析器来解释语言中的句子。也就是说,用编译语言的方式来分析应用中的实例。这种模式实现了文法表达式处理的接口,该接口解释一个特定的上下文。
知道语法树的吧,就那种感觉。
  • 1
  1. 原型模式
    原型(Prototype)模式的定义如下:用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象.Java中可以通过clone()来实现。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/喵喵爱编程/article/detail/752249
推荐阅读
相关标签
  

闽ICP备14008679号