【设计模式】笔记

Hint

非功能需求及其含义

产品为了满足用户的业务需求而必须具备的除功能之外的特性,它与功能需求是互补的

  • 性能
  • 可扩展性/伸缩性
  • 可维护性
  • 可用性
  • 安全性
  • 业务质量(cost, schedule, staff, resources)

编程的三个层次

  • 面向过程
  • 面向对象
  • 面向事件

面向对象设计的三大原则(特性)

  1. 封装

    就是将客观事物抽象为逻辑实体,实体的属性和功能相结合,形成一个有机的整体。并对实体的属性和功能实现进行访问控制,向信任的实体开放,对不信任的实体隐藏。,通过开放的外部接口即可访问,无需知道功能如何实现。

  2. 继承

    在继承机制下形成有层级的类,使得低层级的类可以延用高层级类的特征和方法

  3. 多态

    是指一个类的同名方法,在不同情况下的实现细节不同

Design Pattern

作用

  • 可重用性
  • 容易被他人理解
  • 代码可靠性

原则

  • 开闭原则(Open Closed Principle,OCP)

    对扩展开放,对修改关闭

  • 单一职责原则(Single Responsibility Principle, SRP)

    一个类只负责一个功能领域中的相应职责

  • 依赖倒转原则(Dependency Inversion Principle,DIP)

    依赖于抽象,不能依赖于具体实现

  • 里氏代换原则(Liskov Substitution Principle,LSP)

    所有引用基类的地方必须能透明地使用其子类的对象

  • 接口隔离原则(Interface Segregation Principle,ISP)

    类之间的依赖关系应该建立在最小的接口上

  • 合成/聚合复用原则(Composite/Aggregate Reuse Principle,CARP)

    尽量使用合成/聚合,而不是通过继承达到复用的目的

  • 最少知识原则(Least Knowledge Principle,LKP)或者迪米特法则(Law of Demeter,LOD)

    一个软件实体应当尽可能少的与其他实体发生相互作用

创建型模式

关注点是如何创建对象,其核心思想是要把对象的创建和使用相分离,这样使得两者能相对独立地变换

Singleton

单例

提供访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

abstract

object Singleton {
    ...
}

implementation

object Singleton {
    fun service(): Unit {
        println("I am singleton")
        println("I offer some general service")
    }
}

fun demo() {
    Singleton.service()
}

Factory

工厂

不对外暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

Simple Factory

一个Factory返回多个Product子类,新增Product子类时需修改Factory类

abstract

interface Product

interface ProductType

interface Factory {
    fun getProduct(productType: ProductType): Product
}

implementation

enum class OrganismType: ProductType {
    AQUATIC,
    TERRESTRIAL
}

class Aquatic: Organism

class Terrestrial: Organism

//水生生物与陆生生物
object OrganismFactory: Factory {
    override fun getProduct(productType: ProductType): Organism {
        println(productType as OrganismType)
        return when (productType as OrganismType) {
            OrganismType.AQUATIC -> Aquatic()
            OrganismType.TERRESTRIAL -> Terrestrial()
        }
    }
}

fun simpleFactoryDemo() {
    val organism = OrganismFactory.getProduct(OrganismType.TERRESTRIAL)
}
Factory Method

每个Product子类均有各自对应的Factory

abstract

interface Product

interface ProductType

interface Factory {
    fun getProduct(productType: ProductType): Product
}

implementation

interface Organism: Product

interface OrganismFactories: Factory {
    override fun getProduct(productType: ProductType): Organism
}

class Aquatic: Organism

class Terrestrial: Organism

enum class OrganismType: ProductType {
    AQUATIC,
    TERRESTRIAL
}

object AquaticFactory: OrganismFactories {
    override fun getProduct(productType: ProductType): Organism {
        if (productType as OrganismType != OrganismType.AQUATIC){
            println("wrong type")
        }
        println("aquatic")
        return Aquatic()
    }
}

object TerrestrialFactory: OrganismFactories {
    override fun getProduct(productType: ProductType): Organism {
        if (productType as OrganismType != OrganismType.TERRESTRIAL){
            println("wrong type")
        }
        println("terrestrial")
        return Terrestrial()
    }
}

enum class OrganismType: ProductType {
    AQUATIC,
    TERRESTRIAL
}

fun factoryMethodDemo() {
    val aquatic = AquaticFactory.getProduct(OrganismType.AQUATIC)
    val terrestrial = AquaticFactory.getProduct(OrganismType.TERRESTRIAL)
}
Abstract Factory

抽象工厂

工厂方法的进一步深化,围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂

当存在多个Product族时使用,类似于简单工厂与工厂方法的结合,从Product族层面看为工厂方法,从某一Product族中的子Product层面看为简单工厂

abstract

interface Product

interface ProductType

interface ProductFamilyType

interface AbstractFactory {
    fun getProduct(productFamilyType: ProductFamilyType, productType: ProductType): Product
}

implementation

interface Substance: Product

interface Organic: Substance

interface Inorganic: Substance

interface SubstanceType: ProductType

enum class SubstanceFamilyType: ProductFamilyType {
    ORGANIC,
    INORGANIC
}

enum class OrganicType: SubstanceType {
    FAT,
    PROTEIN,
    CARBOHYDRATE
}

enum class InorganicType: SubstanceType {
    WATER,
    INORGANICSALT
}

class Water: Inorganic

class InorganicSalt: Inorganic

class Fat: Organic

class Protein: Organic

class Carbohydrate: Organic

//有机物与无机物
object InorganicFactory: AbstractFactory {
    override fun getProduct(productFamilyType: ProductFamilyType, productType: ProductType): Inorganic {
        if(productFamilyType as SubstanceFamilyType!=SubstanceFamilyType.INORGANIC) throw java.lang.Exception()
        val substance = when (productType as InorganicType) {
            InorganicType.WATER -> Water()
            InorganicType.INORGANICSALT -> InorganicSalt()
        }
        println("$productType of $productFamilyType family is produced")
        return substance
    }
}

object OrganicFactory: AbstractFactory {
    override fun getProduct(productFamilyType: ProductFamilyType, productType: ProductType): Organic {
        if(productFamilyType as SubstanceFamilyType!=SubstanceFamilyType.ORGANIC) throw java.lang.Exception()
        val substance = when (productType as OrganicType) {
            OrganicType.FAT -> Fat()
            OrganicType.CARBOHYDRATE -> Carbohydrate()
            OrganicType.PROTEIN -> Protein()
        }
        println("$productType of $productFamilyType family is produced")
        return substance
    }
}

fun abstractFactoryDemo() {
    try {
        OrganicFactory.getProduct(SubstanceFamilyType.ORGANIC,InorganicType.INORGANICSALT)
    } catch (e: Exception) {
        println("wrong productFamilyType or ProductType")
    }
}

应该不考

Builder

建造者

建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象,将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。

适用于:

1、需要生成的对象具有复杂的内部结构。

2、需要生成的对象内部属性本身相互依赖。

vs. Factory Pattern :建造者模式更加关注与零件装配的顺序。

vs. Bridge Pattern

abstract

interface Product

interface Builder {
    fun build(): Product
}

implementation

data class Intelligence(val wisdom: Int = 0) : Product

data class Courage(val courageous: Int = 0) : Product

data class Spirit(val intelligence: Intelligence = Intelligence(), val courage: Courage = Courage()) : Product

data class Skelecton(val solidity: Int = 0) : Product

data class Muscle(val strength: Int = 0) : Product

data class Flesh(val skelecton: Skelecton = Skelecton(), val muscle: Muscle = Muscle()) : Product

data class Life(val spirit: Spirit, val flesh: Flesh) : Product

class LifeBuilder: Builder {
    private var spirit: Spirit = Spirit()
    private var flesh: Flesh = Flesh()

    fun soul(wisdom: Int, courageous: Int): LifeBuilder {
        spirit = Spirit(Intelligence(wisdom), Courage(courageous))
        println("intelligence $wisdom")
        println("courageous $courageous")
        println("a beautiful soul was infused")
        return this
    }

    fun body(solidity: Int, strength: Int): LifeBuilder {
        flesh = Flesh(Skelecton(solidity), Muscle(strength))
        println("solidity $solidity")
        println("strength $strength")
        println("a strong body is formed")
        return this
    }

    override fun build(): Life {
        println("spirit is infused with flesh")
        return Life(spirit,flesh)
    }
}
Prototype

原型

用于创建重复的对象,利用已有的一个原型对象,通过复制快速地生成和原型对象一样的实例,同时又能保证性能,当直接创建对象的代价比较大时,则可采用这种模式。

abstract

interface Content {
    fun copy(): Content
}

interface Prototype {
    val content: Content
    fun clone(): Content
}

implementation

//仿生人
class Android: Content {
    override fun copy(): Content {
        println("new android had been manufactured")
        return Android()
    }
}

class AndroidPrototype(override val content: Android) : Prototype {
    override fun clone(): Content {
        return content.copy()
    }
}

fun prototypeDemo() {
    val androidPrototype = AndroidPrototype(Android())
    val nAndroid: Android = androidPrototype.clone() as Android
}

行为型模式

主要涉及算法和对象间的职责分配,描述一组对象应该如何通过使用对象组合协作来完成一个整体任务。

Observer vs. MVC(时序图)vs. Reactor(时序图)

Observer

观察者

当一个对象被修改时,自动通知依赖它的对象

vs. Reactor

abstract

interface Observer {
    fun update(observableState: ObservableState)
}

interface ObservableState

interface Observable {
    var state: ObservableState
    val observers: ArrayList<Observer>
    fun attachObserver(observer: Observer) {
        observers.add(observer)
    }
    fun updateState(state: ObservableState) {
        this.state = state
    }
    
    fun notifyObservers() {
        observers.forEach { it -> it.update(state) }
    }
}

implementation

data class LoginState(val on: Boolean = false) : ObservableState

class User(override var state: ObservableState = LoginState(), override val observers: ArrayList<Observer> = ArrayList()) : Observable

class Portrait: Observer {
    override fun update(observableState: ObservableState) {
        when( (observableState as LoginState).on ) {
            true -> println("portrait became light")
            false -> println("portrait become dark")
        }
    }
}

class Friends: Observer {
    override fun update(observableState: ObservableState) {
        when( (observableState as LoginState).on ) {
            true -> println("user is online")
            false -> println("user is offline")
        }
    }
}

fun observerDemo() {
    val user = User()
    user.attachObserver(Friends())
    user.attachObserver(Portrait())
    user.notifyObservers()
    user.updateState(LoginState(true))
}
Reactor

基于事件驱动的设计模式,拥有一个或多个并发输入源,有一个服务处理器和多个请求处理器,服务处理器会同步的将输入的请求事件以多路复用的方式分发给相应的请求处理器

abstract

interface Event

interface Reactor {
    val handlers: ArrayList<EventHandler>
    fun dispatch(event: Event)
}

interface EventHandler {
    fun handle(event: Event)
}

implementation

class ClickedEvent: Event

class EnteredEvent: Event

class ClickedEventHandler: EventHandler {
    override fun handle(event: Event) {
        println("clicked event is handled")
    }
}

class EnteredEventHandler: EventHandler {
    override fun handle(event: Event) {
        println("entered event is handled")
    }
}

class EventDispatcher(override val handlers: ArrayList<EventHandler> = ArrayList()) : Reactor {
    override fun dispatch(event: Event) {
        when (event) {
            is ClickedEvent -> ClickedEventHandler().handle(event)
            is EnteredEvent -> EnteredEventHandler().handle(event)
        }
    }
}

fun reactorDemo() {
    val eventDispatcher = EventDispatcher()
    eventDispatcher.dispatch(ClickedEvent())
    eventDispatcher.dispatch(EnteredEvent())
}
MVC
  • 模型(Model) 用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法。“ Model ”有对数据直接访问的权力,例如对数据库的访问。“Model”不依赖“View”和“Controller”,也就是说, Model 不关心它会被如何显示或是如何被操作。但是 Model 中数据的变化一般会通过一种刷新机制被公布。为了实现这种机制, View 或事先在此 Model 上注册,从而,View 可以了解在数据 Model 上发生的改变(观察者模式)或在Controller操控下更新View
  • **视图(View)**能够实现数据有目的的显示(理论上,这不是必需的)。在 View 中一般没有程序上的逻辑。为了实现 View 上的刷新功能,View 需要访问它监视的数据模型(Model),因此应该事先在被它监视的数据那里注册。
  • **控制器(Controller)**起到不同层面间的组织作用,用于控制应用程序的流程。它处理事件并作出响应。“事件”包括用户的行为和数据 Model 上的改变。

img

abstract

interface Model {
    fun update()
    fun saveToDatabase()
    fun notifyView(view: View)
}

interface Controller {
    val model: Model
    val view: View
    fun updateModel()
}

interface View {
    fun updateGUI()
}

implementation

class ViewImpl: View {
    override fun updateGUI() {
        println("gui is updated")
    }
}

class ControllerImpl(override val model: Model = ModelImpl(), override val view: View = ViewImpl()) : Controller {
    override fun updateModel() {
        println("controller react to user behavior")
        model.update()
        model.notifyView(view)
    }
}

class ModelImpl : Model {
    override fun update() {
        println("model is updated")
        saveToDatabase()
    }

    override fun saveToDatabase() {
        println("change to model is saved to database")
    }

    override fun notifyView(view: View) {
        println("notify view")
        view.updateGUI()
    }
}

fun MVCDemo() {
    val controller = ControllerImpl()
    controller.updateModel()
}

Interpreter

解释器

给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子

常被用在 SQL 解析、符号处理引擎

abstract

interface Expression {
    fun interpret(context: String): Boolean
}

implementation

class AndExpression(val exp1: Expression, val exp2: Expression): Expression {
    override fun interpret(context: String): Boolean {
        return exp1.interpret(context)&&exp2.interpret(context)
    }
}

class OrExpression(val exp1: Expression, val exp2: Expression): Expression {
    override fun interpret(context: String): Boolean {
        return exp1.interpret(context)||exp2.interpret(context)
    }
}

class NotExpression(val exp: Expression): Expression {
    override fun interpret(context: String): Boolean {
        return !exp.interpret(context)
    }
}

class MetaExpression(val data: String): Expression {
    override fun interpret(context: String): Boolean {
        return context.contains(data)
    }
}

fun interpretDemo() {
    val rick = MetaExpression("rick")
    val morty = MetaExpression("morty")
    println(NotExpression(rick).interpret("rick"))
    println(AndExpression(rick,morty).interpret("rick and morty"))
    println(AndExpression(rick,NotExpression(morty)).interpret("rick and morty"))
    // false,true,f
}

Strategy

策略

创建定义一系列的算法的各种策略对象和一个所执行算法随着策略对象改变而改变的 Context 对象,使得算法可以自由切换,且可独立于它的使用者变化

vs. State Pattern

abstract

interface Strategy {
    fun action()
}

interface StrategyChoice

interface StrategyConsumer {
    var strategy: Strategy
    fun updateStrategy(strategyChoice: StrategyChoice)
    fun action()
}

implementation

enum class Enemy: StrategyChoice{
    ATTACK,
    MOVE,
    DEFENSE
}
//三种策略
class DefenseStrategy: Strategy {
    override fun action() {
        println("enemy is attacking, take the defense strategy")
    }
}

class MoveStrategy: Strategy {
    override fun action() {
        println("enemy is defensing, take the move strategy")
    }
}

class AttackStrategy: Strategy {
    override fun action() {
        println("enemy is moving, take the attack strategy")
    }
}
//战士根据敌人的动作切换策略
class Fighter(override var strategy: Strategy = DefenseStrategy()) : StrategyContext {
    override fun action(strategyChoice: StrategyChoice) {
        strategy = when (strategyChoice as Enemy) {
            Enemy.ATTACK -> DefenseStrategy()
            Enemy.DEFENSE -> MoveStrategy()
            Enemy.MOVE -> AttackStrategy()
        }
        strategy.action()
        println()
    }
}

fun strategyDemo() {
    val fighter = Fighter()
    fighter.action(Enemy.DEFENSE)
    fighter.action(Enemy.MOVE)
    fighter.action(Enemy.ATTACK)
}

Visitor

访问者

为了访问比较复杂的数据结构,不去改变数据结构,而是把对数据的操作抽象出来,在“访问”的过程中以回调形式在访问者中处理操作逻辑。如果要新增一组操作,那么只需要增加一个新的访问者。

abstract

interface Element {
    fun accept(visitor: Visitor): Unit {
        println("universal element output")
        visitor.visit(this)
        println("")
    }
}

interface Visitor {
    fun visit(element: Element): Unit {
        println("universal visitor output")
    }
}

implementation

class Meat: Element

class Fruits: Element

class Vegetable: Element

class Vegetarian: Visitor {
    override fun visit(element: Element) {
        super.visit(element)
        println("I am a vegetarian")
        when(element){
            is Meat -> println("I hate meat")
            is Fruits -> println("I enjoy fruits")
            is Vegetable -> println("I love vegetable")
        }
    }
}

class Carnivore: Visitor {
    override fun visit(element: Element) {
        super.visit(element)
        println("I am a carnivore")
        when(element){
            is Meat -> println("I love meat")
            is Fruits -> println("Fruits is Ok")
            is Vegetable -> println("I hate vegetable")
        }
    }
}

fun demo() {
    val meat: Meat = Meat()
    val fruits: Fruits = Fruits()
    val vegetable: Vegetable = Vegetable()
    val vegetarian: Vegetarian = Vegetarian()
    val carnivore: Carnivore = Carnivore()
    meat.accept(carnivore)
    meat.accept(vegetarian)
    fruits.accept(carnivore)
    fruits.accept(vegetarian)
    vegetable.accept(carnivore)
    vegetable.accept(vegetarian)
}

应该不考

Command

命令模式

数据驱动

命令(Command)的形式包裹请求,并传给调用对象(Invoker)。调用对象寻找可以处理该命令的合适的对象(Receiver)来执行命令。

abstract

interface Command {
    fun execute(receiver: Receiver) {
        receiver.exec()
    }
}

interface Receiver {
    fun exec()
}

interface Invoker {
    val commands: ArrayList<Command>
    fun addCommand(command: Command) {
        commands.add(command)
    }
    fun executeCommands()
}

implementation

class Gardening: Command

class Cleaning: Command

class Cleaner: Receiver {
    override fun exec() {
        println("The house had been cleaned.")
    }
}

class Gardener: Receiver {
    override fun exec() {
        println("The garden had been taken care of.")
    }

}

class Butler(override val commands: ArrayList<Command>) : Invoker {
    private val gardener = Gardener()
    private val cleaner = Cleaner()
    override fun executeCommands() {
        commands.forEach{ command ->
            when(command) {
                is Gardening -> command.execute(gardener)
                is Cleaning -> command.execute(cleaner)
            }
            println()
        }
        commands.clear()
    }
}

fun commandDemo() {
    val butler = Butler(ArrayList())
    butler.addCommand(Gardening())
    butler.addCommand(Cleaning())
    butler.executeCommands()
}
State

将各状态对应逻辑分拆到不同的状态类中,以达到易于拓展新状态的目的。

存在各种状态State的和一个管理状态切换的 Context

abstract

interface State {
    fun action()
}

interface  Context {
    var currentState: State
    fun action() {
        currentState.action()
    }
}

implementation

class QianJiSan(override var currentState: State) : Context

class ShieldForm: State {
    override fun action() {
        println("ShieldForm")
        println("defense")
    }
}

class SwordForm: State {
    override fun action() {
        println("SwordForm")
        println("fight")
    }
}

fun stateDemo() {
    val swordForm = SwordForm()
    val shieldForm = ShieldForm()
    val qianJiSan = QianJiSan(swordForm)
    qianJiSan.action()
    qianJiSan.currentState = shieldForm
    qianJiSan.action()
}
Chain-of-responsibility

责任链

使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

责任链模式(Chain of Responsibility)是一种处理请求的模式,它让多个处理器都有机会处理该请求,直到其中某个处理成功为止。责任链模式把多个处理器串成链,然后让请求在链上传递

责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。

在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。

abstract

interface Handler {
    val nextHandler: Handler?
    val authority: Priority
    fun handle(priority: Priority)
}

interface Priority

implementation

enum class Vampire: Priority {
    Baron,
    Vicomte,
    Comte,
    Marquess,
    Duke,
    Infante
}

interface Priest: Handler {
    val name: String
    override val authority: Vampire
    override val nextHandler: Priest?
    override fun handle(priority: Priority) {
        if ((priority as Vampire)<=authority) {
            println("$priority wad purified")
        println()
        } else {
            println("request ${nextHandler?.name?:"god"} to process")
            nextHandler?.handle(priority)
        }
    }
}

//三种神职人员
class Monk(override val nextHandler: Priest, override val name: String = "monk", override val authority: Vampire = Vampire.Vicomte) : Priest {}

class Bishop(override val nextHandler: Priest, override val name: String = "bishop", override val authority: Vampire = Vampire.Marquess) : Priest {}

class Pope(override val name: String = "pope", override val authority: Vampire = Vampire.Duke, override val nextHandler: Priest? = null) : Priest {}


fun chainOfResponsibilityDemo(){
    val pope = Pope()
    val bishop = Bishop(pope)
    val monk = Monk(bishop)
    monk.handle(Vampire.Duke)
    monk.handle(Vampire.Infante)
}
Iterator

迭代器

提供一种无需对外暴露集合对象的内部表示就能就遍历集合对象元素的方法

分离了集合对象的遍历行为,把遍历元素责任交给迭代器,而不是集合对象

abstract

interface Iterator {
    fun hasNext(): Boolean
    fun next(): Any
}

interface Container {
    fun iterator(): Iterator
}

implementation

class Virtue: Container {
    val virtues: ArrayList<String> = arrayListOf("Chastity","Diligence","Charity","Humility","Patience","Temperance")
    inner class VirTueIterator: Iterator {
        var cur: Int = 0
        override fun hasNext(): Boolean {
            return cur<virtues.size
        }

        override fun next(): String {
            return virtues[cur++]
        }
    }
    override fun iterator(): Iterator {
        return VirTueIterator()
    }
}
Mediator

中介

用一个中介对象来处理不同类/对象之间的通信,把多方会谈变成双方会谈,以降低多个类之间的通信复杂性。

中介者使各个类不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

abstract

interface Mediator {
    val communicators: ArrayList<Communicator>
    fun deliver(message: Message)
}

interface Message

interface Communicator {
    val mediator: Mediator
    fun sendMessage(message: Message, receiver: Communicator)
    fun receiveMessage(message: Message, sender: Communicator) = {}
}

implementation

data class ChatMessage(val content: String) : Message

class ChatRoom(override val communicators: ArrayList<Communicator> = ArrayList()) : Mediator {
    override fun deliver(message: Message) {
        println((message as ChatMessage).content)
        println()
    }
}

class ChatUser(val name: String, override val mediator: ChatRoom) : Communicator {
    override fun sendMessage(message: Message, receiver: Communicator) {
        println("$name send a message to ${(receiver as ChatUser).name}")
        mediator.deliver(message)
    }
}
Memento

备忘录

在不破坏封装性的前提下,在某对象之外保存该对象的内部状态,以便在适当的时候恢复对象

abstract

interface Originator {
    var states: States
    fun save(): Memonto
    fun load(memonto: Memonto)
}

interface States {}

interface Memonto {
    val states: States
    fun load(): States {return states}
}

implementation

data class GameStates(val level: Int, val stage: Int): States

class GameArchive(override val states: States) : Memonto

class Game(override var states: States = GameStates(1,1)) : Originator {
    override fun save(): Memonto {
        println("game archive is saved")
        return GameArchive(states)
    }

    override fun load(memonto: Memonto) {
        states = memonto.states
        println("game archive is loaded")
    }
}

fun memontoDemo() {
    val game = Game()
    val archi = game.save()
    game.load(archi)
}
Template-method

模板方法

一个抽象类/接口公开定义了执行它的方法的模板“骨架”。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。

abstract

abstract class Template {
    protected abstract fun first()
    protected abstract fun second()
    protected abstract fun last()
    final fun steps() {
        first()
        second()
        last()
    }
}

implementation

class Human: Template() {
    override fun first() {
        println("birth")
    }

    override fun second() {
        println("aging")
    }

    override fun last() {
        println("death")
    }
}

fun templateDemo() {
    val human = Human()
    human.steps()
}

结构型模式

不仅仅简单地使用继承,而更多地通过组合与运行期的动态组合来实现更好、更灵活的结构与功能

Adapter

适配器

作为两个不兼容的接口之间的桥梁,将一个类的接口转换成客户希望的另外一个接口以结合了两个独立接口的功能,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

abstract

interface Destination {
    fun func1()
}

interface Source {
    fun func2()
}

interface Adapter: Destination {
    val source: Source
    fun fun1()
}

implementation

class Wizard: Source {
    override fun func2() {
        println("Attack Power")
    }
}

open class Warrior: Destination {
    override fun func1() {
        println("Attack Damage")
    }
}

class WizardWarrior(override val source: Source) : Warrior(),Adapter {
    override fun func1() {
        super.func1()
        source.func2()
    }
}

Proxy

代理

创建具有某对象的代理对象,以便代表改对象向外界提供功能接口。

abstract

public interface Original {
   void action();
}

interface Proxy: Original{
    val original: Original
    override fun action(): Unit {
        original.action()
    }
}

implementation

class HttpService: Original {
    override fun action() {
        println("HTTP Service offered")
    }
}

class EvilHttpService(override val original: HttpService) : Proxy {
    private fun check() :Boolean {
        return (1..2).random()<2
    }
    override fun action() {
        println("HTTP request is censored")
        val youAreAGoodPerson = check()
        if (youAreAGoodPerson) {
            original.action()
        }else {
            println("your access is denied!")
        }
        println()
    }
}

fun demo() {
    val httpService = EvilHttpService(HttpService())
	httpService.action()
}

Decorator

装饰器

作为现有的类的一个包装,向一个现有的对象添加新的功能,同时又不改变其结构,装饰和数据源类实现同一接口, 从而能在客户端代码中相互替换

abstract

interface Original {
    fun action(): Unit
}

interface Decorator: Original{
    val original: Original
    fun before(): Unit {}
    fun after(): Unit {}
    override fun action(): Unit {
        before()
        original.action()
        after()
        println()
    }
}

implementation

class Mage: Original {
    override fun action() {
        println("I am a mage")
    }
}

class FireMage(override val original: Original): Decorator{
    override fun after() {
        println("A FireMage to be exact")
        println("Incendio")
    }
}

class IceMage(override val original: Original): Decorator{
    override fun after() {
        println("A IceMage to be exact")
        println("freezing charm")
    }
}

fun demo() {
    val fireMage = FireMage(Mage())
    val iceMage = IceMage(Mage())
    fireMage.action()
    iceMage.action()
}

代理模式,注重对对象某一功能的流程把控和辅助。 它可以控制对象做某些事,重心是为了借用对象的功能完成某一流程,而非对象功能如何。

装饰模式,注重对对象功能的扩展,它不关心外界如何调用,只注重对对象功能的加强,装饰后还是对象本身。

应该不考

Bridge

桥接

又称为柄体(Handle and Body)模式或接口(Interfce)模式

将抽象接口作为抽象化和实现化之间的桥接结构,把抽象化与实现化解耦,使得实体类的功能独立于接口实现类,使得二者可以独立变化。避免有多种可能会变化的情况下直接继承带来的子类爆炸问题,提高扩展的灵活性。

abstract

interface Bridge {
    fun func()
}

interface Entity {
    val bridge: Bridge
    fun func()
}

implementation

abstract class Mecha(override val bridge: EnergyCore) : Entity {
    internal abstract fun statement()
    override fun func() {
        statement()
        bridge.func()
        println()
    }
}

//不同机甲型号可搭配不同能源核心,使得二者均易于拓展
class MechaI(core: EnergyCore): Mecha(bridge = core) {
    override fun statement() {
        println("MechaI")
    }
}

class MechaV(core: EnergyCore): Mecha(bridge = core) {
    override fun statement() {
        println("MechaV")
    }
}

class MechaX(core: EnergyCore): Mecha(bridge = core) {
    override fun statement() {
        println("MechaX")
    }
}

interface EnergyCore: Bridge

class SolarEnergyCore: EnergyCore {
    override fun func() {
        println("solar energy is transforming into power")
    }
}

class WindEnergyCore: EnergyCore {
    override fun func() {
        println("wind energy is transforming into power")
    }
}

fun bridgeDemo() {
    MechaI(WindEnergyCore()).func()
    MechaI(SolarEnergyCore()).func()
    MechaV(WindEnergyCore()).func()
    MechaV(SolarEnergyCore()).func()
    MechaX(WindEnergyCore()).func()
    MechaX(SolarEnergyCore()).func()
}
Composite

组合

又称为部分整体模式,依据树形结构来组合对象,创建了一个包含自己对象组的类,把一组相似的对象当作一个单一的对象处理。使得用户对单个对象和组合对象的使用具有一致性

abstract

interface Composite {
    val composites: ArrayList<Composite>
}

implementation

interface HTMLElement: Composite {
    val content: String
    fun toHTML() {
        composites.forEach { it ->
            (it as HTMLElement).toHTML()
        }
    }
}

class HTML(override val content: String = "",override val composites: ArrayList<Composite> = ArrayList()) : HTMLElement {
    override fun toHTML() {
        println("<html>")
        super.toHTML()
        println("</html>")
    }
}

class Body(override val content: String = "",override val composites: ArrayList<Composite> = ArrayList()) : HTMLElement {
    override fun toHTML() {
        println("<body>")
        super.toHTML()
        println("</body>")
    }
}

class H1(override val content: String = "",override val composites: ArrayList<Composite> = ArrayList()) : HTMLElement {
    override fun toHTML() {
        println("<h1> $content </h1>")
    }
}

class P(override val content: String = "",override val composites: ArrayList<Composite> = ArrayList()) : HTMLElement {
    override fun toHTML() {
        println("<p> $content </p>")
    }
}

fun compositeDemo() {
    val html = HTML()
    val body = Body()
    body.composites.add(H1("header"))
    body.composites.add(P("a paragraph"))
    body.composites.add(P("another paragraph"))
    html.composites.add(body)
    html.toHTML()
}
Facade

外观

对外隐藏具有诸多子系统的系统的复杂性,只提供一个可以访问系统的接口

abstract

interface Facade {
    val subsystems: ArrayList<Subsystem>
    fun react()
}

interface Subsystem{
    fun react()
}

implementation

class ForeignAffairsMinistry: Subsystem{
    override fun react() {
        println("The Ministry of Foreign Affairs intervened")
    }
}

class NationalDefenseMinistry: Subsystem{
    override fun react() {
        println("The Ministry of Defense conducts military mobilization")
    }
}

class Government(override val subsystems: ArrayList<Subsystem> = ArrayList()) : Facade {
    private val foreignAffairsMinistry: ForeignAffairsMinistry = ForeignAffairsMinistry()
    private val nationalDefenseMinistry: NationalDefenseMinistry = NationalDefenseMinistry()

    override fun react() {
        if((1..2).random()<2){
            foreignAffairsMinistry.react()
        }else nationalDefenseMinistry.react()
    }
}
Flyweight

通过工厂方法尝试重用现有的同类对象以减少创建对象的数量,以减少内存占用和提高性能,如果未找到匹配的对象,则创建新对象

在实际应用中,享元模式主要应用于缓存

vs. Singleton

单例模式是类级别的,一个类只能有一个对象实例;

享元模式是对象级别的,可以有多个对象实例,并允许多个变量引用同一个对象实例;

abstract

interface FlyWeight

interface FlyWeightEnum

interface FlyWeightFactory {
    val map: Map<FlyWeightEnum,FlyWeight>
    fun getFlyWeight(flyWeightEnum: FlyWeightEnum): FlyWeight
}

implementation

enum class FaithOfTheSeven: FlyWeightEnum {
    Father,
    Mother,
    Warrior,
    Smith,
    Maiden,
    Crone,
    Stranger
}

class Deity(private val priesthood: FaithOfTheSeven = FaithOfTheSeven.Father): FlyWeight {
    fun answerPrayer() {
        println("$priesthood answered the prayer")
        println()
    }
}

class Church(override val map: HashMap<FlyWeightEnum, Deity> = HashMap()) : FlyWeightFactory {
    override fun getFlyWeight(flyWeightEnum: FlyWeightEnum): Deity {
        if (!map.containsKey(flyWeightEnum)) {
            map[flyWeightEnum] = Deity(flyWeightEnum as FaithOfTheSeven)
            println("$flyWeightEnum was awakened")
        }
        return map.getOrDefault(flyWeightEnum, Deity())
    }

    fun pray(flyWeightEnum: FlyWeightEnum) {
        println("The believers prayed")
        getFlyWeight(flyWeightEnum).answerPrayer()
    }
}

Design Pattern in Power Point

  • duck 1004 strategy
  • coffee 1025 decorator

Software architecture

管道过滤器风格

pipes and filters

  • Filter

    Component

  • Pipe

    Connector

image-20221126105636724

image-20221126110332719

主程序/子程序风格

Main program and subroutine

  • Hierarchical decomposition: Based on definition-use relations
    • Definition-call
    • Call-return
  • Single thread of control Supported directly by programming languages

面向对象风格

Object-Oriented Organization

  • Each object contains data and operations on these data.

  • Data within an object can only be accessed by methods of its inclosing object.

  • Object is probably instantiated from a template (Class)

  • feature

    • Encapsulation

      Restrict access to certain information

    • Polymorphism

      Choose the method at run-time

    • Inheritance

      take over (or inherit) attributes and behavior of the pre-existing classes

分层的风格

Call and return systems

  • Main program and subroutine
  • OO Systems
  • Hierarchical layer

基于共享数据的事件风格

  • Individual components announce event to communicate with others (Publish)
  • Other components may register an interest in the kind of events (subscribe). They are invoked when the event appear

image-20221126112413531

image-20221126112433663

PowerPoint

  • 软件体系结构=(元素,形态,基本理论)

  • 软件体系结构层次的设计主要包括以下方面:

    • 组成系统的构件描述
    • 构件之间的交互
    • 指导构件交互的模式
    • 施加在模式上的约束
  • 一个软件系统的体系结构定义了组成系统的

    • 构件(components)

      构件用于实施计算和保存状态

    • 连接件(connectors)

      连接件用于表达构件之间的关系

    • 和它们之间的匹配

      构件和连接件之间的匹 配表示了系统的拓扑结构

    • Components:

      define the locus of computation

      Examples: filters, databases, objects, clients/servers

    • Connectors:

      mediate component interactions

      Examples: procedure call, pipes, event broadcast

  • Batch Sequential Systems

    • Processing steps are independent programs
    • Each step runs to completion before next step starts
    • Data transmitted as a whole between steps
    • Typical applications:
      • classical data processing
      • program development
  • data flow System

    • A data flow system is one in which
      • the availability of data controls the computation
      • the structure of the design is dominated by orderly motion of data from process to process
      • the pattern of data flow is explicit
    • In a pure data flow system, there is no other interaction between processes
Licensed under CC BY-NC-SA 4.0
Last updated on Jun 06, 2023 00:00 UTC
comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy