由四位大师提出的23种设计模式,对于程序的复用性有很大的意义,这里对于Kotlin中自己了解的几种设计模式进行介绍。
-
设计模式的六大原则:
- 单一职责原则:就一个类而言,应该仅有一个引起它变化的原因。
- 开放封闭原则:类、模块、函数等应该是可以拓展的,但是不可修改。
- 里氏替换原则:所有引用基类的地方必须能透明地使用其子类的对象。
- 依赖倒置原则:高层模块不应该依赖底层模块,两者都应该依赖与抽象。抽象不应该依赖于细节,细节应该依赖于抽象。
- 迪米特原则:一个软件实体应当尽可能少与其他实体发生相互作用。
- 接口隔离原则:一个类对另一个类的依赖应该建立在最小的接口上。
-
23种设计模式如下:
- 创建型:单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。
- 构造型:适配器模式、装饰模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
- 行为型:策略模式、模板方法模式、观察者模式、迭代器模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
下面将全部介绍。(注意下面的模式都是基于Kotlin来讲解的)
- 单例模式
众所周知,单例模式,在系统之中只能有一个实例。因此,想要在Java中实现它,就必须对构造方法私有化,使用static。
而在Kotlin中我们可以利用object关键字的特性,来实现单例模式。object声明的类全局只能有一个,因此,我们可以像声明普通的类那样声明一个单例类。
object CarClass{
var type:Int = 2
//一些方法......
}
之后,我们在主方法之中这样调用它。发现即使我们想普通的类那样声明无论多少个它,我们都只会得到一个它的实例,这里我通过修改一个实例的值,所有的引用的结果都会更改,来证明它是一个单例。
fun main(args:Array<String>){
val type = CarClass
val type1 = CarClass
type.type = 3
println(type.type)
println(type1.type)
}
输出结果:
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
}
- 访问者模式
在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
}
}
我们再定义,我们具体的操作实现类,也就是具体的逻辑代码。
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
}
}
我们考虑到大量的Vistor的实例的调用,我们将实例化的它放入我们前面单例模式提到的单例中:
object CarClass{
val vistor:Vistor = Vistor()
}
在主函数中调用我们的函数。
fun main(args:Array<String>) {
println(Expr.Num(0).isZero())
输出:
true
- 工厂模式
工厂模式是我们常用的设计模式。在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
}
- 单例模式优化
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
}
- 抽象工厂模式
使用抽象工厂模式,我们可以为创建一组相关或相互依赖的对象提供一个接口,而且无需指定它们的具体类。在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
}
- 构建者模式
一个对象创建时可能具有很多的参数需要我们手动赋值,或者一些参数我们并不想在一开始就赋值,又或者一些参数之间存在约束关系。这个时候我们就需要用到我们的构建者模式了。
先看一下常规的构建者模式:
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
}
在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
}
另外,想要设定参数之间的限定关系,可以使用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: 电池型号设定好后方可设置重量
- 观察者模式
有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了
}
另外,我们还可以使用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了
// 价格不可为负数
}
- 策略模式
策略模式做的事情就是将不同的行为策略进行独立封装,与类在逻辑上解耦。然后根据不同的上下文切换选择不同的策略,然后用类对象进行调用。在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()
//输出:
//自由泳
// 仰泳
}
- 模板模式
定义一个算法中的操作框架,而将一些步骤延迟到子类中,使得子类可以不改变算法的结构即可重定义该算法的某些特定步骤。这里我们同样使用高阶函数进行实现:
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)
// 输出
// 排队
// 安全服务
// 评价
// 排队
// 申请卡
// 评价
}
- 迭代器模式
将遍历和实现分离开,在遍历的同时不需要暴露对象的内部实现。Kotlin中我们使用扩展函数实现:
data class Book(val name:String)
class Bookecase(val books: List<Book>){}
operator fun Bookecase.iterator():Iterator<Book> =
books.iterator()
- 责任链模式
避免请求的发送者和接收者之间的耦合关系,将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。在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)
}
}
}
我们编写具体的情况:
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.
}
- 状态模式
状态模式允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。
示例:
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)
// 输出
// 制冷
// 加热开始
// 制冷
// 关闭
}
- 装饰器模式
由于,我们要遵循里氏原则,在对一个类的行为进行扩展的时候,有时不得不放弃继承它的子类来扩展,这时候,我们就需要用到装饰器模式了。
定义:再不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。该模式通过创建一个包装对象,来包裹真实的对象。
在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
}
- 扩展方式示例:
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() }
}
// +++ 开始 +++
// --------
// +++ 结束 +++
// +++ 开始 +++
// - - - - -
// +++ 结束 +++
// +++ 开始 +++
// *********
// +++ 结束 +++
}
介绍完成。有帮助不妨点个赞。
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()
}
}
- 享元模式
运用共享技术来有效地支持大量细粒度对象的复用。它通过共享已经存在的对象来大幅度减少需要创建的对象数量、避免大量相似类的开销,从而提高系统资源的利用率。
创建对象存储起来,保持引用,可以重复利用。
- 桥接模式
将抽象与实现分离,使它们可以独立变化。
// 具体实现类
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()
}
}
- 适配器模式
将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。
// 目标接口
interface Target {
fun request()
}
// 类适配器类
open class Adapter {
fun specificRequest() {
println("适配者代码")
}
}
// 在这里可以直接使用已有的代码
class ClassAdapter : Adapter(), Target {
override fun request() {
specificRequest()
}
}
- 代理模式
由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。
// 目标接口
interface Subject {
fun request()
}
// 真正要访问的类
class RealSubject : Subject {
override fun request() {
println("真实方法")
}
}
// 代理类
class Proxy : Subject {
val realSubject:RealSubject = RealSubject()
override fun request() {
// 一些预操作
realSubject.request()
// 后续操作
}
}
- 简单工厂模式
就是只有一个工厂的模式。
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()
}
}
}
- 组合模式
有时又叫作整体-部分(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()
*/
- 命令模式
将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理。
// 调用者
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("接收者行为")
}
}
- 中介模式
:定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用。
// 抽象中介
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)
}
}
- 备忘录模式
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。该模式又叫快照模式. - 解释器模式
给分析对象定义一个语言,并定义该语言的文法表示,再设计一个解析器来解释语言中的句子。也就是说,用编译语言的方式来分析应用中的实例。这种模式实现了文法表达式处理的接口,该接口解释一个特定的上下文。
知道语法树的吧,就那种感觉。
- 原型模式
原型(Prototype)模式的定义如下:用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象.Java中可以通过clone()来实现。