zoukankan      html  css  js  c++  java
  • kotlin实现鸭子例子的设计模式(策略模式)

    package com.duck

    /**
    * 一.
    * 这样做降低了程序的耦合度,但接口不具有实现方法,实现接口无法达到代码的复用
    * 关键字:耦合度,复用
    */
    interface Flyable {
    fun fly()
    }

    interface Quackable {
    fun quack()
    }

    abstract class Duck {
    fun swim() {
    println("我会游泳!")
    }

    abstract fun display()
    }


    //野鸭子:野鸭子不是抽象类,所以必须实现父类和接口所有的非抽象方法
    class MallardDuck : Duck(), Flyable, Quackable {

    override fun display() {
    println("我的颜色是野鸭子颜色")
    }

    override fun fly() {
    println("野鸭子在飞")
    }

    override fun quack() {
    println("野鸭子在叫")
    }

    }

    class RedheadDuck : Duck(), Flyable, Quackable {

    override fun display() {
    println("红头鸭的颜色")
    }

    override fun fly() {
    println("红头鸭在飞")
    }

    override fun quack() {
    println("红头鸭在叫")
    }
    }

    class DisabledDuck : Duck(), Quackable {
    override fun display() {
    println("废鸭的颜色")
    }

    override fun quack() {
    println("废鸭在叫")
    }
    }

    /**
    * 二.
    * 1.1
    * 解决一中的问题,strategy(策略模式)
    * 设计原则:
    * (1)找出应用中的相同之处,且不容易发生改变的部分,把它们抽象出来,让子类继承
    * (2)找出可能变化的部分,把它们独立出来;不要和那些不需要变化的代码混在一起
    *
    * 为了分开”要变化和不要变化的部分“,可以建立两组类(完全远离Duck类)--<行为模式>
    */
    interface FlyBehavior {
    fun fly()
    }

    interface QuackBehavior {
    fun quack()
    }

    class FlyWithWinngs : FlyBehavior {
    override fun fly() {
    println("有翅膀的鸭子会飞")
    }
    }

    class FlyNoWay : FlyBehavior {
    override fun fly() {
    println("没翅膀的鸭子不会飞")
    }
    }

    class Quack : QuackBehavior {
    override fun quack() {
    println("鸭子呱呱叫")
    }
    }
    class Squeak :QuackBehavior{
    override fun quack() {
    println("鸭子吱吱叫")
    }
    }
    class MuteQuack :QuackBehavior{
    override fun quack() {
    println("安静的鸭子")
    }
    }
    /**二.
    * 1.1 点评
    * 这样的设计,可以让不同的飞行和叫的行为让其它的对象复用,提高了代码的复用
    * 而我们继续增加一些新的行为的时候,既不会影响到既有的行为类,也不会影响到使用”现有行为“的具体类
    */

    /**
    * 二.
    * 1.2
    * 设计Duck类,MallardDuck类

    */
    abstract class Duck二() {
    open lateinit var flyBehavior: FlyBehavior
    open lateinit var quackBehaving: QuackBehavior
    abstract fun display()
    fun swim(){
    println("所有的鸭子都会游泳")
    }

    fun performFly(){
    flyBehavior.fly()
    }
    fun performQuack() {
    quackBehaving.quack()
    }

    }

    class MallardDuck二: Duck二() {

    override var flyBehavior: FlyBehavior=FlyWithWinngs()
    override var quackBehaving: QuackBehavior=Quack()

    override fun display() {
    println("野鸭子的颜色")
    }
    }

    fun main(args: Array<String>) {
    var m = MallardDuck二()
    var f = m.performFly()
    var q = m.performQuack()
    var d = m.display()
    var s = m.swim()

    "$f,$q,$d,$s"
    }

    /**
    *二.
    * 1.2 点评
    * 动态代理。。。
    * 这样既可以飞,又可以展示自己的颜色
    * 这样的设计可以看到是把flyBehavior,quackBehavior的实例化卸载子类了。我们还可以动态决定
    *
    * 在构造方法中对属性进行赋值与用属性的setter赋值的区别:
    * 构造方法中对属性进行赋值:固定,不可变;
    * 用属性的setter赋值,可以在实例化对象后,动态的变化,比较灵活
    * **/



    相关总结:

    1.
    (1)普通类继承抽象类时,必须实现其所有抽象方法;
    (2)抽象类继承抽象类时,可以不实现所有抽象方法;
    (3)抽象类可以继承普通类;
    (4)普通类继承抽象类时,可以不实现其抽象方法。
    (5)普通类中不可以有抽象方法

    2.kotlin中A类继承B实现C,D的写法:
    class A :B(),C,D{

    // override...

    }

    3.kotlin中,普通类继承抽象类时
    (1) 如果抽象类中的fly()方法用abstarct修饰,则不可以有方法体,且继承它的类必须重写fly()方法;
    (2) 如果抽象类中的fly()方法为普通方法,但没被open修饰,则子类不可以重写fly()方法;
    (3) 如果抽象类中的fly()方法为普通方法,且被open修饰,则子类可以重写fly()方法。

    * :

    (1)将具体实体类和行为分开写,即写一个专门的行为类

    (2)共同的部分可放在父类中让所有的实体类继承使用,可能有变动的类专门写成行为类,调用使用

  • 相关阅读:
    网站搜索功能lucene
    RabbitMQ消息队列
    zookeeper
    RPC+SOA+dubbo
    石英定时任务-quartz
    通用mapper、图片上传、nginx
    通用mapper和分类实现
    后台商品管理功能实现
    构建框架
    海量数据的并发处理
  • 原文地址:https://www.cnblogs.com/tian666/p/7878393.html
Copyright © 2011-2022 走看看