原始模型
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 comp = ComputerFactory().produce(ComputerType.PC)
>>> println(comp.cpu)
Core
使用单例代替工厂类
object ComputerFactory {
fun produce(type: ComputerType): Computer {
return when(type) {
ComputerType.PC -> PC()
ComputerType.Server -> Server()
}
}
}
>>> val comp = computerFactory.produce(ComputerType.PC)
>>> println(comp)
Core
invoke运算符重载
object ComputerFactory {
operator fun invoke(type: ComputerType): Computer {
return when(type) {
ComputerType.PC -> PC()
ComputerType.Server -> Server()
}
}
}
>>> val comp = computerFactory(ComputerType.PC)
>>> println(comp)
Core
伴生对象创建静态工厂方法
interface Computer {
val cpu: String
companion object {
operator fun invoke(type: ComputerType): Computer {
return when(type) {
ComputerType.PC -> PC()
ComputerType.Server -> Server()
}
}
}
}
>>> val comp = Computer(ComputerType.PC)
>>> println(comp)
Core
具名伴生对象
interface Computer {
val cpu: String
companion object Factory {
operator fun invoke(type: ComputerType): Computer {
return whenn(type) {
ComputerType.PC -> PC()
ComputerType.Server -> Server()
}
}
}
}
>>> val comp = Computer.Factory(ComputerType.PC)
>>> println(comp)
Core
扩展伴生对象方法
fun Computer.Companion.fromCPU(cpu: String): ComputerType? = when(cpu) {
"Core" -> ComputerType.PC
"Xeon" -> ComputerType.Server
}
fun Computer.Companion.Factory.fromCPU(cpu: String): ComputerType? = when(cpu) {
"Core" -> ComputerType.PC
"Xeon" -> ComputerType.Server
}
>>> val pc = Computer.fromCPU("Core")
>>> val server = Computer.Factory.fromCPU("Xeon")
抽象工厂模式
为创建一组相关或相互依赖的对象提供一个接口, 而且无需指定他们的具体类.
interface Computer
class Dell: Computer
class Asus: Computer
class Acer: Computer
class DellFactory: AbstrctFactory() {
override fun produce() = Dell()
}
class AsusFactory: AbstractFactory() {
override fun produce() = Asus()
}
class AcerFatory: AbstractFactory() {
override fun produce() = Acer()
}
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 -> AcerFatory()
else -> throw IllegalArgumentException()
}
}
}
fun main(args: Array<String>) {
val dellFactory = AbstractFactory<Dell>()
val dell = dellFactory.produce()
println(dell)
}
用具名可选参数而不是构建者模式
本质上builder模式模拟类具名的可选参数,就像Ada和Python中的一样.
class Robot(
val code: String,
val battery: String? = null
val height: Int? = null,
val weight: Int? = null
) {
init {
require(weight == null || battery != null) {
"Batter should be determined when setting weight."
}
}
}
>>> val robot1 = Robot(code = "007")
>>> val robot2 = Robot(code = "007", battery = "R6")
>>> val robot3 = Robot(code = "007", weight = 100)
java.lang.IllegalArgumentException: Batter should be determined when setting weight.
从java.util.Observable说起
import java.util.*
class StackUpdate: Observable() {
val observers = mutableSetOf<Observer>();
fun setStockChanged(price: Int) {
this.Observers.forEach { it.update(this, price)}
}
}
class StockDisplay: Observer {
override fun update(o: Observable, price: Any) {
jif (o is StockUpdate) {
println("The latest stock price is ${price}.")
}
}
}
fun main(args: Array<String>) {
val su = StockUpdate()
val sd = StockDisplay()
su.observers.add(sd)
su.setStackChanged(100)
}
// 运行结果
The latest stock price is 100.
Observable
import kotlin.properties.Delegates
interface StockUpdateListener {
fun onRise(price: Int)
fun onFall(price: Int)
}
class StockDisplay: StockUpdateListener {
override fun onRise(price: Int) {
println("The latest stock price has risen to ${price}.")
}
override fun onFall(price: Int) {
println("The latest stock price has fell to ${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 = StockDiaplay()
su.listeners.add(sd)
su.price = 100
su.price = 98
}
// 运行结果
The latest stock price has risen to 100.
The latest stock price has fell to 98.
Vetoable
import kotlin.properties.Delegates
var value: Int by Delegates.vetoable(0) { prop, old, new ->
new > 0
}
>>> value = 1
>>> println(value)
1
>>> value = -1
>>> println(value)
1
原始策略模式
interface SwimStrategy {
fun swim()
}
class Breaststroke: SwimStrategy {
override fun swim() {
println("I am breaststroking...")
}
}
class Backstroke: SwimStrategy {
override fun swim() {
println("I am backstroke...")
}
}
class Freestyle: SwimStrategy {
override fun swim() {
println("I am freestyling...")
}
}
class Swimmer(val strategy: SwimStrategy) {
fun swim() {
strategy.swim()
}
}
fun main(args: Array<String>) {
val weekendShaw = Swimmer(Freestyle())
weekendsShaw.swim()
val weekdayShaw = Swimmer(Breaststroke())
weekdayShaw.swim()
}
// 运行结果
I am freestyling...
I am breaststroking...
高阶函数抽象
fun breakstroke() {println("I am breaststroking...")}
fun backstroke() {println("I am backstroke...")}
fun freestyle() {println("I am freestyle...")}
class Swimmer(val swimming: () -> Unit) {
fun swim() {
swimming()
}
}
fun main(args: Array<String>) {
val weekendShaw = Swimmer(::freestyle)
weekendShaw.swim()
val weekdaysShaw = Swimmer(::breaststroke)
weekdayShaw.swim()
}
模板方法模式:高阶函数代替继承
原始模板方法
abstract class CivicCenterTask {
fun execute() {
this.lineUp()
this.askForHelp()
this.evaluate()
}
private fun lineUp() {
println("line up to take a number")
}
privaate fun evaluate() {
println("evaluaten service attiude")
}
abstract fun askForHelp()
}
class PullSocialSecurity: CivicCenterTask {
override fun askForHelp() {
println("ask for pulling the social security")
}
}
class ApplyForCitizenCard: CiviCenterTask {
override fun askForHelp() {
println("apply for a citizen card")
}
}
val pss = PullSocialSecurity()
>>> pss.execute()
line up to take a number
ask for pulling the social security
evaluaten service attitude
val afcc = ApplyForCitizenCard()
>>> afcc.execute()
line up to take a number
apply for a citizen card
evaluaten service attitude
高阶函数改造.
class CiviCenterTask {
fun execute(askForHelp: () -> Unit) {
this.lineUp()
askForHelp()
this.evaluate()
}
private lineUp() {
println("line up to take a number")
}
private fun evalute() {
println("evaluaten service attitude")
}
}
fun pullSocialSecurity() {
println("ask for pulling the social security")
}
fun applyForCitizenCard() {
println("apply for citizen card")
}
var task1 = CivicCenterTask()
>>> task1.execute(::pullSocialSecurity)
line up to take a number
ask for pulling the social security
evaluaten service attitude
val task2 = CivicCenterTask()
>>> task2.execute(::applyForCityzenCard)
line up to take a number
apply for a citizen card
evaluaten service attitude
迭代器模式
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()
}
fun main(args: Array<String>) {
val bookcase = Bookcase(
listOf(Book("Dive into Kotlin"), Book("Thinking in Java"))
)
while(bookcase.hasNext()) {
println("The book name is ${bookcase.next().name}")
}
for (book in bookcase) {
println("The book name is ${book.name}")
}
}
// 运行结果
The book name is Dive into Kotlin
The book name is Thinging in Java
The book name is Dive into Kotlin
The book name is Thinging in Java
data class Book(val name: String)
class Bookcase(val books: List<Book>) {
operator fun iterator(): Iterator<Book> = this.books.iterator()
}
fun main(args: Array<String>) {
for (book in bookcase) {
println("The book name is ${book.name}")
}
}
// 运行结果
The book name is Dive into Kotlin
The book name is Thinging in Java
data class Book(val name: String)
class Bookcase(val books: List<Book>){}
operator fun Bookcase.iterator(): Iterator<Book> = books.iterator()
// operator fun Bookcase.iterator(): Iterator<Book> = object: Iterator<Book> {
// val iterator = books.iterator()
// override fun hasNext() = iterator.hasNext()
// override fun next() = iterator.next()
// }
fun main(args: Array<String>) {
for (book in bookcase) {
println("The book name is ${book.name}")
}
}
// 运行结果
The book name is Dive into Kotlin
The book name is Thinging in Java
用偏函数实现责任链模式
责任链模式的目的就是避免请求的发送者和接受者之间的耦合关系,将这个对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
data class ApplyEvent(val money: Int, val title: String)
interface ApplyHandler {
val successor: ApplyHandler?
fun handleEvent(event: AppleEvent)
}
class GroupLeader(override val successor: ApplyHandler?): ApplyHandler {
override fun handleEvent(event: ApplyEvent) {
when {
event.money <= 100 -> println("Group Leader handled application: ${event.title}")
else -> when(successor) {
is ApplyHandler -> successor.handleEvent(event)
else -> println("Group Leader: This application cannot be handdle.")
}
}
}
}
class President(override val successor: ApplyHandler?): ApplyHandler {
override fun handleEvent(event: ApplyEvent) {
when {
event.money <= 500 -> println("President handled application: ${event.title}")
else -> when(successor) {
is ApplyHandler -> successor.handleEvent(event)
else -> println("Prisident: This application cannot be handdle")
}
}
}
}
class College(override val successor: ApplyHnadler?): ApplyHandler {
override fun handleEvent(event: ApplyEvent) {
when {
event.money > 1000 -> println("College: This application is refused.")
else -> println("College handled application: ${event.title}")
}
}
}
fun main(args: Array<String>) {
val college = College(null)
val president = Predsident(college)
val groupLeader = GroupLeader(president)
groupLeader.handleEvent(ApplyEvent(10, "buy a pen"))
groupLeader.handleEvent(ApplyEvent(200, "team building"))
groupLeader.handleEvent(ApplyEvent(600, "hold a debate match"))
groupLeader.handleEvent(ApplyEvent(1200, "annual meeting of the college"))
}
// 运行结果
Group Leader handled application: buy a pen.
President handled application: team building.
College handled application: hold a debate match.
College: This application is refused.
使用偏函数
偏函数是个数学中的概念,指的是定义域X中可能存在某些值在值域Y中没有对应的值。
开源库funKTionale实现了PartialFunction.
class PartialFunction<in P1, out R>(private val definedAt: (P1) -> Boolean, private val f: (P1) -> R) :(P1) -> R {
override fun invoke(p1: P1): R {
if (definedAt(P1)) {
return f(p1)
} else {
throw IllegalArgumentException("Value: $(p1) isn't supported by this function")
}
}
fun isDefinedAt(p1: P1) = definedAt(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)
}
}
}
data class ApplyEvent(val money: Int, val title: String)
val groupLeader = {
val definedAt: (ApplyEvent) -> Boolean = { it.money <= 200 }
val handler: (ApplyEvent) -> Unit = { println("Group Leader handled application: ${it.title}.")}
PartialFunction(definedAt, handler)
}()
val president = {
val definedAt: (ApplyEvent) -> Boolean = { it.money <= 500}
val handler: (ApplyEvent) -> Unit = { println("President handled application: ${it.title}.")}
PartialFunction(definedAt, handler)
}()
val college = {
val definedAt: (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(definedAt, handler)
}()
val applyChain = groupLeader orElse president orElse college
>>> applyChain(ApplyEvent(600, "hold a debate match"))
College handled application: hold a debate match.
ADT 实现状态模式
状态模式允许一个对象在其内部状态改变时改变它的行为, 对象看起来似乎修改了它的类。
sealed class WaterMachineState(open val machine: WaterMachine) {
fun turnHeating() {
if (this !is Heating) {
println("turn heating")
machine.state = machine.heating
} else {
println("The state is already heating mode.")
}
}
fun turnCooling() {
if (this !is Cooling) {
println("turn cooling")
machine.state = machine.cooling
} else {
println("The state is already cooling mode.")
}
}
fun turnOff() {
if (this !is Off) {
println("turn off")
machine.state = machine.off
} else {
println("The state is already off.")
}
}
}
class Off(override val machine: WatterMachine): WatterMachineState(machine)
class Heating(override val machine: WatterMachine): WatterMachineState(machine)
class Cooling(override val machine: WatterMachine):
WatterMachineState(machine)
class WaterMachine {
var state: WaterMachineState
val 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()
}
}
enum class Moment {
EARLY_MORNING,
DRINKING_WATER,
INSTANCE_NOODLES,
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)
}
// 执行结果
turn cooling
turn heating
turn cooling
turn off
装饰模式: 使用委托减少样板代码
装饰模式就是在不必改变原类文件和使用继承的情况下, 动态地扩展一个对象的功能。该模式通过创建一个包装对象,来包裹真实的对象。
interface Macbook {
fun getCost(): Int
fun getDesc(): String
fun getProdDate(): String
}
class MacBookPro: MacBook {
override fun getCost() = 10000
override fun getDesc() = "Macbook Pro"
override fun getProdDate() = "Late 2011"
}
// 装饰类
class ProcessorUpgradeMacbookPro(val macbook: MacBook): MacBook by macbook {
override fun getCost() = macbook.getCost() + 219
override fun getDesc() = macbook.getDesc() + ", +1G Memory"
}
fun main(args: Array<String>) {
val macBookPro = MacBookPro()
val processorUpgradeMacbookPro = ProcessorUpgradeMacbookPro(macBookPro)
println(processorUpgradeMacbookPro.getCost())
println(processorUpgradeMacbookPro.getDesc())
}
// 运行结果
10219
Macbook Pro, +1G Memory
通过扩展代替装饰者
class Printer {
fun drawline() {
println("————————————————")
}
fun drawDottedLine() {
println("----------------")
}
func drawStars() {
println("****************")
}
}
fun Printer.startDraw(decorated: Printer.() -> Unit) {
println("+++ start drawing +++")
this.decorated()
println("+++ end drawing +++")
}
fun main(args: Array<String>) {
Printer().run {
startDraw {
drawLine()
}
startDraw {
drawDottedLine()
}
startDraw {
drawStars()
}
}
}
// 运行结果
+++ start drawing +++
————————————————
+++ end drawing +++
+++ start drawing +++
----------------
+++ end drawing +++
+++ start drawing +++
****************
+++ end drawing +++