创建型模式
单例模式
某个类的实例对象只有一个,适用于对象需要频繁实例化的场景。
饿汉式
在类初始化的时候就已经在内存中创建了对象,不存在线程安全问题。
object Singleton {
}
object 的单例在类加载时立即创建,而如果单例的初始化成本高,或者程序可能不会使用该单例,这会导致资源浪费。
懒汉式
在方法被调用时才创建对象,存在线程安全问题。
class Singleton private constructor() {
companion object {
private var instance: Singleton? = null
get() {
if (field == null) {
field = Singleton()
}
return field
}
fun get() = instance!!
}
}
可以通过加锁来保证线程安全
class Singleton private constructor() {
companion object {
private var instance: Singleton? = null
get() {
if (field == null) {
field = Singleton()
}
return field
}
@Synchronized
fun get() = instance!!
}
}
静态内部类
外部类加载时并不需要立即加载内部类,内部类不被加载则不去初始化 instance,故不占内存,不存在线程安全问题。
class SingleTon private constructor() {
companion object {
fun getInstance() = SingleHolder.instance
}
private object SingleHolder {
val instance = SingleTon()
}
}
双重校验锁式
这里运用到 Kotlin 的延迟属性 lazy,Lazy 接收一个 lambda 并返回一个 Lazy 实例的函数,返回的实例可以作为实现延迟属性的委托,第一次调用 get() 会执行已传递给 lazy 的 lambda 表达式并记录结果, 后续再调用 get() 只是返回记录的结果,无线程安全问题。
class SingleTon private constructor() {
companion object {
val instance by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { SingleTon() }
}
}
工厂模式
帮助我们创建对象,隐藏对象创建过程的复杂度。
简单工厂模式
interface MobilePhone {
fun produce()
}
class AndroidMobilePhone : MobilePhone {
override fun produce() {
print("produce AndroidMobilePhone")
}
}
class IOSMobilePhone : MobilePhone {
override fun produce() {
print("produce IOSMobilePhone")
}
}
enum class SystemType {
ANDROID, IOS
}
class MobilePhoneFactory {
companion object {
fun createMobilePhone(type: SystemType) = when (type) {
SystemType.ANDROID -> AndroidMobilePhone()
SystemType.IOS -> IOSMobilePhone()
}
}
}
工厂方法模式
interface MobilePhone {
fun produce()
}
class AndroidMobilePhone : MobilePhone {
override fun produce() {
print("produce AndroidMobilePhone")
}
}
class IOSMobilePhone : MobilePhone {
override fun produce() {
print("produce IOSMobilePhone")
}
}
abstract class MobilePhoneFactory {
abstract fun createMobilePhone(): MobilePhone
}
class AndroidMobilePhoneFactory : MobilePhoneFactory() {
override fun createMobilePhone(): MobilePhone {
return AndroidMobilePhone()
}
}
class IOSMobilePhoneFactory : MobilePhoneFactory() {
override fun createMobilePhone(): MobilePhone {
return IOSMobilePhone()
}
}
抽象工厂模式
interface MobilePhone {
fun produce()
}
class AndroidMobilePhone : MobilePhone {
override fun produce() {
print("produce AndroidMobilePhone")
}
}
class IOSMobilePhone : MobilePhone {
override fun produce() {
print("produce IOSMobilePhone")
}
}
interface Watch {
fun produce()
}
class AndroidWatch : Watch {
override fun produce() {
print("produce AndroidWatch")
}
}
class IOSWatch : Watch {
override fun produce() {
print("produce IOSWatch")
}
}
//生产多个产品
abstract class Factory {
abstract fun createMobilePhone(): MobilePhone
abstract fun createWatch(): Watch
}
class AndroidFactory : Factory() {
override fun createMobilePhone(): MobilePhone {
return AndroidMobilePhone()
}
override fun createWatch(): Watch {
return AndroidWatch()
}
}
class IOSFactory : Factory() {
override fun createMobilePhone(): MobilePhone {
return IOSMobilePhone()
}
override fun createWatch(): Watch {
return IOSWatch()
}
}
建造者模式
将一个对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。
data class MobilePhone(
var screen: String = "",
var battery: String = "",
var camera: String = ""
)
abstract class Builder {
abstract fun buildScreen(screen: String): Builder
abstract fun buildBattery(battery: String): Builder
abstract fun buildCamera(camera: String): Builder
abstract fun build(): MobilePhone
}
class MiBuilder : Builder() {
private var mobilePhone = MobilePhone()
override fun buildScreen(screen: String): Builder {
mobilePhone.screen = screen
return this
}
override fun buildBattery(battery: String): Builder {
mobilePhone.battery = battery
return this
}
override fun buildCamera(camera: String): Builder {
mobilePhone.camera = camera
return this
}
override fun build(): MobilePhone {
return mobilePhone
}
}
这是传统的建造者模式的实现方式,但对于 kotlin 来说,我们有更优雅的方式。
data class MobilePhone(
var screen: String = "",
var battery: String = "",
var camera: String = ""
)
fun buildMobilePhone(action: MobilePhone.() -> Unit) = MobilePhone().apply(action)
val mobilePhone = buildMobilePhone {
screen = "screen"
battery = "battery"
camera = "camera"
}
结构型模式
代理模式
通过代理对象访问目标对象
静态代理
interface MobilePhoneSale {
fun sell()
}
class MobilePhoneSaleReal : MobilePhoneSale {
override fun sell() {
print("MainMobilePhoneSale sell")
}
}
class MobilePhoneSaleProxy : MobilePhoneSale {
private val mobilePhoneSaleReal = MobilePhoneSaleReal()
override fun sell() {
print("MobilePhoneSaleProxy sell")
mobilePhoneSaleReal.sell()
}
}
动态代理
interface MobilePhoneSale {
fun sell()
}
class MobilePhoneSaleReal : MobilePhoneSale {
override fun sell() {
print("MainMobilePhoneSale sell")
}
}
class MobilePhoneSaleProxy {
private val real = MobilePhoneSaleReal()
//在数组对象前加 * 号可以将数组展开,以方便传值
fun getProxyInstance() = Proxy.newProxyInstance(
real.javaClass.classLoader,
real.javaClass.interfaces
) { _, p1, p2 -> p1.invoke(real, *p2.orEmpty()) } as MobilePhoneSale
}
装饰者模式
在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。其本质就是通过创建一个包装对象,来包裹真实的对象。
interface MobilePhone {
fun fluency(): Float
fun clarity(): Float
fun produceDate(): String
}
class AppleMobilePhone : MobilePhone {
override fun fluency() = 100f
override fun clarity() = 90f
override fun produceDate() = "2022-09-08"
}
abstract class MobilePhoneParts(val mobilePhone: MobilePhone) : MobilePhone
class PhoneSystem(mobilePhone: MobilePhone) : MobilePhoneParts(mobilePhone) {
override fun fluency() = mobilePhone.fluency() + 1
override fun clarity() = mobilePhone.clarity()
override fun produceDate() = mobilePhone.produceDate()
}
class HDScreen(mobilePhone: MobilePhone) : MobilePhoneParts(mobilePhone) {
override fun fluency() = mobilePhone.fluency()
override fun clarity() = mobilePhone.clarity() + 1
override fun produceDate() = mobilePhone.produceDate()
}
val phone = PhoneSystem(HDScreen(AppleMobilePhone()))
这是传统的装饰者模式实现方式,事实上,这种实现还是比较啰嗦的,比如 PhoneSystem 只装饰 fluency,却要把所有方法都重写一遍,不够优雅。我们可以借助 kotlin 的类委托特性,利用 by 关键字,将装饰类的所有方法委托给一个被装饰的类对象,然后只需覆写装饰的方法即可。
interface MobilePhone {
fun fluency(): Float
fun clarity(): Float
fun produceDate(): String
}
class AppleMobilePhone : MobilePhone {
override fun fluency() = 100f
override fun clarity() = 90f
override fun produceDate() = "2022-09-08"
}
abstract class MobilePhoneParts(val mobilePhone: MobilePhone) : MobilePhone by mobilePhone
class PhoneSystem(mobilePhone: MobilePhone) : MobilePhoneParts(mobilePhone) {
override fun fluency() = mobilePhone.fluency() + 1
}
class HDScreen(mobilePhone: MobilePhone) : MobilePhoneParts(mobilePhone) {
override fun clarity() = mobilePhone.clarity() + 1
}
行为型模式
观察者模式
定义了一对多的依赖关系,让一个或多个观察者对象监听一个主体对象。当被观察者状态发生改变时,需要通知相应的观察者,使这些观察者对象能够自动更新。
interface MobilePhonePriceListener {
fun onRise(price: Int)
fun onFall(price: Int)
}
//被观察者,使用委托属性监听值变化后通知
class PriceSubject {
private val listeners = mutableSetOf<MobilePhonePriceListener>()
var price: Int by Delegates.observable(0) { property, oldValue, newValue ->
val isRise = newValue > oldValue
listeners.forEach {
if (isRise) {
it.onRise(price)
} else {
it.onFall(price)
}
}
}
fun subscribe(observer: MobilePhonePriceListener) {
listeners.add(observer)
}
fun unsubscribe(observer: MobilePhonePriceListener) {
listeners.remove(observer)
}
}
//观察者
class PhoneConsumer : MobilePhonePriceListener {
override fun onRise(price: Int) {
print("The price has risen. Don't buy it")
}
override fun onFall(price: Int) {
print("The price has dropped, buy it")
}
}
val priceSubject = PriceSubject()
priceSubject.subscribe(PhoneConsumer())
priceSubject.price = 10000
策略模式
当同一个操作,可能有不同表现的时候,可以将这个操作抽象出来,然后将具体的表现分别封装起来,并且都实现抽象的操作,这样在执行这个操作的时候,可以根据不同的表现类型,来执行不同表现。
interface Payment {
fun pay()
}
class AliPayment : Payment {
override fun pay() {
print("Ali Pay")
}
}
class WechatPayment : Payment {
override fun pay() {
print("Wechat pay")
}
}
class PaymentContainer(private val payment: Payment) {
fun pay() {
payment.pay()
}
}
val aliPay = PaymentContainer(AliPayment())
aliPay.pay()
val wechatPayment = PaymentContainer(WechatPayment())
wechatPayment.pay()