Android开发-设计模式kotlin版

  • 单例模式(Singleton)

    kotlin中提供了语法糖实现单例模式,使用object关键字可以轻松实现线程安全懒加载的单例模式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    object Singleton {
    fun doSomething() {
    println("")
    }
    }
    //kotlin类中的调用方式
    Singleton.doSomething()
    //如果在java和kotlin混用的项目中,java中的调用方式为
    Singleton.INSTANCE.doSomething()

    kotlin 中的 object 单例会在首次使用时初始化,而不是在程序启动时就创建

    或者想要自己写可以这样:

    1
    2
    3
    4
    5
    6
    7
    class Singleton private constructor() {
    companion object {
    val instance: Singleton by lazy {
    Singleton()
    }
    }
    }

    使用 by lazy 使单例在首次使用时才会被初始化,这也是线程安全的一种实现单例的方式。

    双重检查锁的方式实现单例模式:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class Singleton private constructor() {
    companion object {
    @Volatile
    private var instance: Singleton? = null

    fun getInstance(): Singleton {
    return instance ?: synchronized(this) {
    instance ?: Singleton().also { instance = it }
    }
    }
    }
    }

    使用同步锁避免了对象的重复创建,但是因为使用了锁会有额外的开销,java中使用静态内部类的方式实现单例,避免了同步锁带来的额外开销,实现懒加载,同时,Java 的类加载机制保证了 静态内部类只会被加载一次,也就是说,是线程安全的,可以说是java中最优雅的实现方式。但是在kotlin中前面两种已经非常优雅了,没必要再照搬java的写法,这边列举使用双重检查锁,也只是情怀,拿来对比一下。

  • 工厂模式(Factory Method)

    工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它提供了一个创建对象的接口,让子类 决定实例化哪一个类。工厂方法模式将对象的实例化延迟到子类去实现,因此,客户端代码无需关心具体如 何创建对象,只需要依赖于抽象的工厂方法即可。

    例如我们配合RecyclerView实现多个viewholder的实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    interface ViewHolderFactory {
    fun createViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder
    }

    //文字类型
    class TextViewHolderFactory : ViewHolderFactory {
    override fun createViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
    val itemView = LayoutInflater.from(parent.context).inflate(R.layout.item_text, parent, false)
    return TextViewHolder(itemView)
    }
    }

    //图片类型
    class ImageViewHolderFactory : ViewHolderFactory {
    override fun createViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
    val itemView = LayoutInflater.from(parent.context).inflate(R.layout.item_image, parent, false)
    return ImageViewHolder(itemView)
    }
    }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    class MyAdapter(private val items: List<Item>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    private val viewHolderFactories: Map<Int, ViewHolderFactory> = mapOf(
    ItemType.TEXT to TextViewHolderFactory(),
    ItemType.IMAGE to ImageViewHolderFactory()
    )

    override fun getItemViewType(position: Int): Int {
    return items[position].type
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
    val factory = viewHolderFactories[viewType]
    return factory?.createViewHolder(parent, viewType) ?: throw IllegalArgumentException("Invalid view type")
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
    val item = items[position]
    when (holder) {
    is TextViewHolder -> holder.bind(item.text)
    is ImageViewHolder -> holder.bind(item.imageUrl)
    }
    }

    override fun getItemCount(): Int {
    return items.size
    }
    }

    在im相关的功能开发中,这种方式很常见,用来区分各种不同的聊天消息,文本、图片、视频、红包等等,把每种消息类型都分开处理,定义相同的接口,可以更加方便代码的管理,代码清晰并且有更好的拓展性。

    类似的使用场景还有很多,比如自定义图表,折线图、饼状图;比如日历模块的周试图、月视图等等。

  • 建造者模式(Builder)

    建造者模式(Builder Pattern) 是一种创建型设计模式,它允许通过多个步骤来构建一个复杂的对象。与直接通过构造函数或工厂方法创建对象不同,建造者模式将对象的构建过程与表示分离,使得同样的构建过程可以创建不同的表示。

    在与后端的交互中,经常需要提交body类型的数据,提交的参数个数位置,简单封装了一个,实现多个动态文本参数的构建,最后统一构建返回RequestBody,上传给服务端

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96

    import com.android.base.utils.JsonUtil.Companion.moderToJsonObject
    import com.android.base.utils.JsonUtil.Companion.stringToJson
    import com.google.gson.JsonArray
    import com.google.gson.JsonObject
    import okhttp3.MediaType.Companion.toMediaTypeOrNull
    import okhttp3.RequestBody
    import okhttp3.RequestBody.Companion.toRequestBody

    class BodyBuilder private constructor() {
    val jsonObject: JsonObject = JsonObject()
    private val methodName: String? = null

    fun addParam(key: String, value: Int): BodyBuilder {
    jsonObject.addProperty(key, value)
    return this
    }

    fun addParam(key: String, value: Long?): BodyBuilder {
    jsonObject.addProperty(key, value)
    return this
    }

    fun addParam(key: String, value: String?): BodyBuilder {
    jsonObject.addProperty(key, value)
    return this
    }

    fun addParam(key: String, value: JsonObject?): BodyBuilder {
    jsonObject.add(key, value)
    return this
    }

    fun addParam(key: String, value: JsonArray?): BodyBuilder {
    jsonObject.add(key, value)
    return this
    }

    fun addJsonParam(json: JsonObject): BodyBuilder {
    val keys = json.keySet()
    val var3: Iterator<*> = keys.iterator()

    while (var3.hasNext()) {
    val key = var3.next() as String
    jsonObject.add(key, json[key])
    }

    return this
    }

    fun addJsonParam(str: String?): BodyBuilder {
    val `object` = stringToJson(str)
    val keys = `object`.keySet()
    val var4: Iterator<*> = keys.iterator()

    while (var4.hasNext()) {
    val key = var4.next() as String
    jsonObject.add(key, `object`[key])
    }

    return this
    }

    fun addModelParam(model: Any?): BodyBuilder {
    val `object` = moderToJsonObject(model)
    val keys = `object`.keySet()
    val var4: Iterator<*> = keys.iterator()

    while (var4.hasNext()) {
    val key = var4.next() as String
    jsonObject.add(key, `object`[key])
    }

    return this
    }

    fun build(): RequestBody {
    return jsonObject.toString().toRequestBody("application/json;charset=utf-8".toMediaTypeOrNull())
    }

    fun buildText(text: String): RequestBody {
    return text.toRequestBody("application/json;charset=utf-8".toMediaTypeOrNull())
    }

    fun page(currentPage: Int, pageSize: Int): BodyBuilder {
    jsonObject.addProperty("currentPage", currentPage)
    jsonObject.addProperty("pageSize", pageSize)
    return this
    }

    companion object {
    fun newBuilder(): BodyBuilder {
    return BodyBuilder()
    }
    }
    }
  • 原型模式(Prototype)

    是一种创建型设计模式,目的是通过复制现有的对象来创建新的对象,而不是通过重新实例化。原型模式通过复制现有实例的方式,可以避免大量重复的构造过程,尤其适用于创建多个具有相似属性的对象。

    在 Kotlin 中,你可以使用 copy() 方法来实现数据类的浅拷贝

    原型模式主要用于创建对象的场景,特别是在对象构建比较复杂时,可以通过原型模式有效简化创建过程。对于需要频繁生成类似对象的系统,原型模式能够提高效率、减少冗余代码。

    1. Prototype(原型)接口
      • 定义一个接口,声明一个克隆方法,通常是 clone()
    2. ConcretePrototype(具体原型)
      • 实现 Prototype 接口,提供具体的 clone() 方法,返回一个当前对象的克隆。
    3. Client(客户端)
      • 通过调用 clone() 方法来创建新的对象,而不是通过构造函数。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    interface Prototype {
    fun clone(): Prototype
    }

    class Character(
    val name: String,
    val health: Int,
    val attack: Int
    ) : Prototype {
    override fun clone(): Character {
    // 返回当前对象的副本
    return Character(name, health, attack)
    }

    override fun toString(): String {
    return "Character(name='$name', health=$health, attack=$attack)"
    }
    }

    fun main() {
    // 创建一个原始角色
    val originalCharacter = Character("Warrior", 100, 20)
    println("Original character: $originalCharacter")

    // 通过克隆来创建新的角色对象
    val clonedCharacter = originalCharacter.clone()
    println("Cloned character: $clonedCharacter")

    // 修改克隆对象的属性
    val modifiedCharacter = clonedCharacter.apply {
    // 改变名字
    name = "Knight"
    }
    println("Modified cloned character: $modifiedCharacter")
    }

    优点

    1. 性能优越:通过复制现有对象来创建新的对象,而不是通过构造过程,性能较高。
    2. 灵活性:可以动态地改变对象的属性,同时避免了构造函数过于复杂的情况。
    3. 避免重复代码:在需要创建大量相似对象时,避免了重复的初始化代码。
    4. 适合复杂对象的创建:对于一些复杂的对象,原型模式可以简化创建过程,避免重复初始化。

    缺点

    1. 克隆复杂对象时可能存在问题:如果对象内部包含复杂的引用类型,可能需要进行深克隆,而不是浅克隆。浅克隆只是复制对象的引用,深克隆则需要复制对象的所有属性。
    2. 维护克隆机制的复杂性:如果对象的结构或字段较为复杂,克隆方法可能变得很复杂,尤其是深拷贝时需要处理的细节较多。
    3. 克隆的对象是否可以正常工作:某些对象可能依赖于外部状态(例如数据库连接、文件句柄等),复制这些对象时可能会导致错误。
  • 适配器模式(Adapter)

    适配器模式(Adapter Pattern)是一种结构型设计模式,它允许将一个类的接口转换成客户端期望的另一种接口,从而使原本由于接口不兼容而不能一起工作的类可以协同工作。

    假设我们有一个旧的系统,它提供的接口无法直接与新系统兼容,我们可以使用适配器模式来桥接这两个系统。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    // 目标接口
    interface Target {
    fun request(): String
    }

    // 源接口
    class Adaptee {
    fun specificRequest(): String {
    return "Specific request"
    }
    }

    // 适配器类,继承自目标接口
    class Adapter(private val adaptee: Adaptee) : Target {
    override fun request(): String {
    // 转换适配源接口的方法
    return adaptee.specificRequest()
    }
    }

    fun main() {
    val adaptee = Adaptee()
    val adapter = Adapter(adaptee)

    println(adapter.request()) // 输出: Specific request
    }

  • 桥接模式(Bridge)

    桥接模式(Bridge Pattern)是一种结构型设计模式,它旨在将抽象部分与实现部分分离,使它们可以独立地变化。通过使用桥接模式,可以避免多重继承和复杂的类层次结构,提高系统的可扩展性和灵活性。

    桥接模式通过创建一个桥接接口,将抽象部分和实现部分分开,从而使得它们可以独立变化,减少了它们之间的耦合关系。桥接模式有助于避免继承的层次结构过于复杂,提供更灵活的扩展性。

    假设我们有一个绘图程序,它支持多种形状和多种颜色,我们希望能够轻松地扩展新的形状和颜色,而不增加复杂的类继承关系。我们可以使用桥接模式来实现。

    定义颜色接口:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    // 实现接口
    interface Color {
    fun applyColor(): String
    }

    // 具体实现类:红色
    class RedColor : Color {
    override fun applyColor(): String {
    return "Red"
    }
    }

    // 具体实现类:蓝色
    class BlueColor : Color {
    override fun applyColor(): String {
    return "Blue"
    }
    }

    定义形状抽象类:

    1
    2
    3
    4
    5
    6
    7
    8
    // 抽象类
    abstract class Shape(private val color: Color) {
    abstract fun draw(): String
    fun applyColor(): String {
    return "Applying color: ${color.applyColor()}"
    }
    }

    拓展抽象类:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // 具体形状:圆形
    class Circle(color: Color) : Shape(color) {
    override fun draw(): String {
    return "Drawing Circle"
    }
    }

    // 具体形状:方形
    class Square(color: Color) : Shape(color) {
    override fun draw(): String {
    return "Drawing Square"
    }
    }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    //使用桥接模式

    fun main() {
    // 创建具体的颜色
    val red = RedColor()
    val blue = BlueColor()

    // 创建具体的形状
    val redCircle = Circle(red)
    val blueSquare = Square(blue)

    // 使用桥接模式
    println("${redCircle.draw()} and ${redCircle.applyColor()}") // Drawing Circle and Applying color: Red
    println("${blueSquare.draw()} and ${blueSquare.applyColor()}") // Drawing Square and Applying color: Blue
    }

  • 过滤器模式(Filter)

    过滤器模式(Filter Pattern),也称为标准化模式(Criteria Pattern),是一种结构型设计模式,它允许通过一系列的过滤条件来处理数据,并最终得到符合要求的结果。该模式通常用于对数据集合进行一系列过滤,简化过滤逻辑,使得过滤操作可以相互独立并进行组合。

    过滤器模式通过组合多个过滤条件来从一组数据中筛选出符合要求的元素。每个过滤器只负责过滤满足某个条件的数据。多个过滤器可以链式组合,从而形成更复杂的过滤条件。

    1. 过滤器接口(Filter):定义过滤方法,通常是一个抽象的 filter() 方法,用于过滤数据。
    2. 具体过滤器(ConcreteFilter):实现过滤器接口,提供具体的过滤逻辑。
    3. 组合过滤器(CompositeFilter):通常将多个过滤器结合起来,形成更复杂的过滤条件。
    4. 目标对象(Target):被过滤的数据集合或对象,通常是一个包含元素的列表或集合。

    定义过滤器接口:

    1
    2
    3
    4
    interface Filter {
    fun filter(persons: List<Person>): List<Person>
    }

    具体过滤器:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // 过滤器:根据年龄过滤
    class AgeFilter(private val age: Int) : Filter {
    override fun filter(persons: List<Person>): List<Person> {
    return persons.filter { it.age >= age }
    }
    }

    // 过滤器:根据性别过滤
    class GenderFilter(private val gender: String) : Filter {
    override fun filter(persons: List<Person>): List<Person> {
    return persons.filter { it.gender == gender }
    }
    }

    使用过滤器:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    data class Person(val name: String, val age: Int, val gender: String)

    fun main() {
    // 创建一组数据
    val persons = listOf(
    Person("Alice", 25, "Female"),
    Person("Bob", 30, "Male"),
    Person("Charlie", 35, "Male"),
    Person("Diana", 28, "Female")
    )

    // 创建过滤器
    val ageFilter = AgeFilter(30)
    val genderFilter = GenderFilter("Female")

    // 使用单个过滤器
    println("People with age >= 30: ${ageFilter.filter(persons)}")
    // 使用多个过滤器
    val combinedFilter = genderFilter.and(ageFilter)
    println("Female people with age >= 30: ${combinedFilter.filter(persons)}")
    }

    使用组合过滤器:

    1
    2
    3
    4
    5
    6
    7
    8
    // 扩展 Filter 接口,提供组合功能
    fun Filter.and(other: Filter): Filter {
    return object : Filter {
    override fun filter(persons: List<Person>): List<Person> {
    return this@and.filter(other.filter(persons))
    }
    }
    }

  • 组合模式(Composite)

    组合模式(Composite Pattern)是一种结构型设计模式,旨在将对象组合成树形结构以表示“部分-整体”层次结构。组合模式使得客户端可以统一对待单个对象和对象集合。它常用于需要处理树形结构的数据或需要将多个对象作为整体进行操作的场景。

    组合模式通过将对象组成树形结构来表示部分和整体的关系。组合模式可以让客户端以一致的方式对待单个对象和对象集合。也就是说,客户端无需区分单个对象和组合对象,它们都可以作为统一的对象来处理。

    假设我们要设计一个图形绘制应用,其中可以绘制单个图形(如圆形、方形),也可以将多个图形组合成一个复合图形进行绘制。我们使用组合模式来组织图形对象。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    //定义组件接口

    interface Graphic {
    fun draw()
    }

    //定义叶子对象(单一图形)
    class Circle : Graphic {
    override fun draw() {
    println("Drawing a Circle")
    }
    }

    class Rectangle : Graphic {
    override fun draw() {
    println("Drawing a Rectangle")
    }
    }
    //定义容器对象(复合图形)
    class CompositeGraphic : Graphic {
    private val graphics = mutableListOf<Graphic>()

    fun add(graphic: Graphic) {
    graphics.add(graphic)
    }

    fun remove(graphic: Graphic) {
    graphics.remove(graphic)
    }

    override fun draw() {
    println("Drawing Composite Graphic:")
    for (graphic in graphics) {
    graphic.draw()
    }
    }
    }
    //使用组合模式
    fun main() {
    // 创建单个图形
    val circle = Circle()
    val rectangle = Rectangle()

    // 创建复合图形
    val compositeGraphic = CompositeGraphic()
    compositeGraphic.add(circle)
    compositeGraphic.add(rectangle)

    // 画出复合图形
    compositeGraphic.draw()

    // 删除一个图形并重新画出复合图形
    compositeGraphic.remove(circle)
    compositeGraphic.draw()
    }



  • 装饰器模式(Decorator)

    装饰器模式(Decorator Pattern)是一种结构型设计模式,旨在通过动态地给对象添加额外的功能,而不改变其结构。它是一种对象行为增强的方式,允许在不修改原始对象代码的情况下,增强或改变对象的功能。

    假设我们要设计一个饮料订单系统,其中有基本的饮料(例如,咖啡)以及可以在其上添加不同配料(例如,牛奶、糖、巧克力等)。我们使用装饰器模式来动态地为饮料添加配料。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    //定义组件接口
    interface Beverage {
    fun cost(): Double
    fun description(): String
    }


    //定义具体组件(基本饮料)
    class Coffee : Beverage {
    override fun cost(): Double {
    return 5.0 // 基本咖啡的价格
    }

    override fun description(): String {
    return "Coffee"
    }
    }

    class Tea : Beverage {
    override fun cost(): Double {
    return 3.0 // 基本茶的价格
    }

    override fun description(): String {
    return "Tea"
    }
    }


    //定义装饰器
    abstract class CondimentDecorator(private val beverage: Beverage) : Beverage {
    override fun description(): String {
    return beverage.description() // 委托给被装饰的对象
    }
    }


    //定义具体装饰器(牛奶、糖、巧克力等)
    class Milk(beverage: Beverage) : CondimentDecorator(beverage) {
    override fun cost(): Double {
    return beverage.cost() + 1.0 // 加牛奶的额外费用
    }

    override fun description(): String {
    return "${beverage.description()} with Milk"
    }
    }

    class Sugar(beverage: Beverage) : CondimentDecorator(beverage) {
    override fun cost(): Double {
    return beverage.cost() + 0.5 // 加糖的额外费用
    }

    override fun description(): String {
    return "${beverage.description()} with Sugar"
    }
    }

    class Chocolate(beverage: Beverage) : CondimentDecorator(beverage) {
    override fun cost(): Double {
    return beverage.cost() + 2.0 // 加巧克力的额外费用
    }

    override fun description(): String {
    return "${beverage.description()} with Chocolate"
    }
    }

    //使用
    fun main() {
    var beverage: Beverage = Coffee() // 创建一杯基本的咖啡
    println("${beverage.description()} costs ${beverage.cost()}")

    // 为咖啡添加牛奶
    beverage = Milk(beverage)
    println("${beverage.description()} costs ${beverage.cost()}")

    // 为咖啡添加糖
    beverage = Sugar(beverage)
    println("${beverage.description()} costs ${beverage.cost()}")

    // 为咖啡添加巧克力
    beverage = Chocolate(beverage)
    println("${beverage.description()} costs ${beverage.cost()}")
    }


  • 外观模式(Facade)

    外观模式(Facade Pattern)是一种结构型设计模式,旨在为复杂的子系统提供一个统一的接口,以便客户端能够更加简单、方便地使用子系统的功能。外观模式通过将多个复杂的操作封装在一个单独的接口或类中,降低了系统的复杂性,并提高了可维护性。

    外观模式通过创建一个外观类,它封装了子系统的复杂操作,向客户端提供一个简化的接口。客户端可以通过外观类与多个子系统进行交互,而无需了解各个子系统内部的实现细节。

    假设我们正在构建一个家庭影院系统,系统由多个组件组成,例如音响、投影仪、灯光控制、DVD播放器等。通过外观模式,我们可以创建一个简化的接口来控制整个家庭影院,而无需暴露每个组件的复杂操作。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    //定义子系统
    class Light {
    fun on() {
    println("Turning on the lights")
    }

    fun off() {
    println("Turning off the lights")
    }
    }

    class Projector {
    fun on() {
    println("Turning on the projector")
    }

    fun off() {
    println("Turning off the projector")
    }

    fun setInput(input: String) {
    println("Setting projector input to: $input")
    }
    }

    class SoundSystem {
    fun on() {
    println("Turning on the sound system")
    }

    fun off() {
    println("Turning off the sound system")
    }

    fun setVolume(volume: Int) {
    println("Setting volume to: $volume")
    }
    }

    class DVDPlayer {
    fun on() {
    println("Turning on the DVD player")
    }

    fun off() {
    println("Turning off the DVD player")
    }

    fun play(movie: String) {
    println("Playing movie: $movie")
    }
    }


    //创建外观类
    class HomeTheaterFacade(
    private val light: Light,
    private val projector: Projector,
    private val soundSystem: SoundSystem,
    private val dvdPlayer: DVDPlayer
    ) {

    fun watchMovie(movie: String) {
    println("Get ready to watch a movie...")
    light.off()
    projector.on()
    projector.setInput("DVD")
    soundSystem.on()
    soundSystem.setVolume(10)
    dvdPlayer.on()
    dvdPlayer.play(movie)
    }

    fun endMovie() {
    println("Shutting down the movie...")
    dvdPlayer.off()
    soundSystem.off()
    projector.off()
    light.on()
    }
    }


    //客户端使用外观类
    fun main() {
    val light = Light()
    val projector = Projector()
    val soundSystem = SoundSystem()
    val dvdPlayer = DVDPlayer()

    val homeTheater = HomeTheaterFacade(light, projector, soundSystem, dvdPlayer)

    // 客户端通过外观类来观看电影
    homeTheater.watchMovie("Inception")

    // 客户端通过外观类结束电影
    homeTheater.endMovie()
    }


    在 Android 应用程序中,可能需要初始化多个组件或模块(例如,推送通知、第三方 SDK、数据库等)。使用外观模式可以将这些初始化操作封装在一个类中,使得客户端代码更加简洁。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    class AppInitializer(private val context: Context) {

    // 初始化第三方库和服务
    fun initialize() {
    initializePushNotifications()
    initializeDatabase()
    initializeAnalytics()
    }

    private fun initializePushNotifications() {
    // 初始化推送通知
    println("Push Notifications Initialized")
    }

    private fun initializeDatabase() {
    // 初始化数据库
    println("Database Initialized")
    }

    private fun initializeAnalytics() {
    // 初始化分析工具
    println("Analytics Initialized")
    }
    }


    // 创建 AppInitializer 实例并进行初始化
    val appInitializer = AppInitializer(context)
    appInitializer.initialize()
  • 享元模式(Flyweight)

    享元模式(Flyweight Pattern)是一种结构型设计模式,它通过共享对象来减少内存消耗,从而提高系统性能。享元模式的核心思想是:当对象的数量非常庞大时,通过共享对象来减少内存占用,提高性能。享元模式的核心是共享对象

  • 代理模式(Proxy)

    代理模式是一种结构型设计模式,它为某个对象提供一个代理对象,以控制对该对象的访问。代理模式可以增加对目标对象的功能,同时对外保持接口的一致性。代理对象可以在访问真实对象之前或之后添加一些额外的操作。

    静态代理
    代理类在编译时生成,代理类和真实类实现相同的接口。

    动态代理
    代理类在运行时动态生成,通过反射机制调用目标对象。

    静态代理实现,代理一个网络请求服务:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    // 抽象主题
    interface NetworkService {
    fun fetchData()
    }

    // 真实主题
    class RealNetworkService : NetworkService {
    override fun fetchData() {
    println("Fetching data from the network...")
    }
    }

    // 代理类
    class NetworkServiceProxy(private val realService: NetworkService) : NetworkService {
    override fun fetchData() {
    println("Proxy: Checking permissions...")
    realService.fetchData()
    println("Proxy: Logging the request...")
    }
    }

    // 客户端
    fun main() {
    val realService = RealNetworkService()
    val proxyService = NetworkServiceProxy(realService)
    proxyService.fetchData()
    }

    动态生成代理对象,可以减少重复代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    import java.lang.reflect.InvocationHandler
    import java.lang.reflect.Method
    import java.lang.reflect.Proxy

    // 抽象主题
    interface DatabaseService {
    fun queryData()
    }

    // 真实主题
    class RealDatabaseService : DatabaseService {
    override fun queryData() {
    println("Querying data from the database...")
    }
    }

    // 动态代理处理器
    class DynamicProxyHandler(private val target: Any) : InvocationHandler {
    override fun invoke(proxy: Any?, method: Method, args: Array<out Any>?): Any? {
    println("Proxy: Pre-processing before method call...")
    val result = method.invoke(target, *(args ?: arrayOfNulls<Any>(0)))
    println("Proxy: Post-processing after method call...")
    return result
    }
    }

    // 客户端
    fun main() {
    val realService = RealDatabaseService()

    // 创建动态代理
    val proxyInstance = Proxy.newProxyInstance(
    realService::class.java.classLoader,
    arrayOf(DatabaseService::class.java),
    DynamicProxyHandler(realService)
    ) as DatabaseService

    proxyInstance.queryData()
    }

    在android中 retrofit使用的就是动态代理

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // 定义网络接口
    interface ApiService {
    @GET("users")
    suspend fun getUsers(): List<User>
    }

    // 创建 Retrofit 实例
    val retrofit = Retrofit.Builder()
    .baseUrl("https://api.example.com/")
    .addConverterFactory(GsonConverterFactory.create())
    .build()

    // 动态生成接口实现
    val apiService = retrofit.create(ApiService::class.java)

  • 模版方法模式(Template Method)

    模板方法模式是一种行为型设计模式,定义了一个操作中的算法骨架,而将某些步骤的具体实现延迟到子类中。通过这种方式,模板方法使得子类可以在不改变算法结构的前提下重新定义算法的某些特定步骤。

    假设我们有一个制作饮料的过程:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    // 抽象类
    abstract class Beverage {
    // 模板方法
    fun prepare() {
    boilWater()
    addMainIngredient()
    pourIntoCup()
    addCondiments()
    }

    private fun boilWater() {
    println("Boiling water...")
    }

    protected abstract fun addMainIngredient()

    private fun pourIntoCup() {
    println("Pouring into cup...")
    }

    protected abstract fun addCondiments()
    }

    // 具体类:制作茶
    class Tea : Beverage() {
    override fun addMainIngredient() {
    println("Adding tea leaves...")
    }

    override fun addCondiments() {
    println("Adding lemon...")
    }
    }

    // 具体类:制作咖啡
    class Coffee : Beverage() {
    override fun addMainIngredient() {
    println("Adding coffee powder...")
    }

    override fun addCondiments() {
    println("Adding sugar and milk...")
    }
    }

    // 客户端
    fun main() {
    val tea = Tea()
    tea.prepare()

    println()

    val coffee = Coffee()
    coffee.prepare()
    }

    android中RecyclerView.Adapter 是模板方法模式的一个典型例子。它提供了固定的流程(如绑定视图和管理数据集),开发者只需要重写特定的步骤即可。

    Android 的 Activity 生命周期也可以看作模板方法模式的实现。系统调用固定的方法顺序,开发者根据需要重写特定方法。

    模板方法onCreateViewHolderonBindViewHoldergetItemCount

    开发者只需要实现具体的逻辑,而不需要关心整个流程的调用。

  • 责任链模式(Chain of Responsibility)

    责任链模式是一种行为型设计模式,允许多个对象按顺序处理请求,直到其中一个对象能够处理它为止。请求发送者并不知道具体由哪个对象处理,而是将请求沿着链传递,动态地决定由谁处理。

    假设有一个系统用来处理不同等级的请求:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    // 抽象处理者
    abstract class Handler {
    private var nextHandler: Handler? = null

    fun setNext(handler: Handler): Handler {
    nextHandler = handler
    return handler
    }

    fun handle(request: Int) {
    if (canHandle(request)) {
    process(request)
    } else {
    nextHandler?.handle(request)
    }
    }

    protected abstract fun canHandle(request: Int): Boolean
    protected abstract fun process(request: Int)
    }

    // 具体处理者 A
    class HandlerA : Handler() {
    override fun canHandle(request: Int): Boolean {
    return request <= 10
    }

    override fun process(request: Int) {
    println("HandlerA processed request: $request")
    }
    }

    // 具体处理者 B
    class HandlerB : Handler() {
    override fun canHandle(request: Int): Boolean {
    return request in 11..20
    }

    override fun process(request: Int) {
    println("HandlerB processed request: $request")
    }
    }

    // 具体处理者 C
    class HandlerC : Handler() {
    override fun canHandle(request: Int): Boolean {
    return request > 20
    }

    override fun process(request: Int) {
    println("HandlerC processed request: $request")
    }
    }

    // 客户端
    fun main() {
    val handlerA = HandlerA()
    val handlerB = HandlerB()
    val handlerC = HandlerC()

    // 创建责任链
    handlerA.setNext(handlerB).setNext(handlerC)

    // 请求处理
    val requests = listOf(5, 15, 25, 30)
    for (request in requests) {
    handlerA.handle(request)
    }
    }

    在 Android 中的应用,Android 的 View 事件分发机制是责任链模式的典型应用,OkHttp 的拦截器机制也是责任链模式的应用

  • 命令模式(Command)

    命令模式是一种行为型设计模式,将请求封装成一个对象,使你可以用不同的请求、队列或者日志来参数化对象,同时支持撤销和恢复操作。

    假设你有一个智能家居系统,用户可以通过遥控器操作家电(例如:灯光开关)。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    // 命令接口
    interface Command {
    fun execute()
    fun undo() // 支持撤销操作
    }

    // 接收者:灯
    class Light {
    fun turnOn() {
    println("Light is ON")
    }

    fun turnOff() {
    println("Light is OFF")
    }
    }

    // 具体命令:打开灯
    class TurnOnLightCommand(private val light: Light) : Command {
    override fun execute() {
    light.turnOn()
    }

    override fun undo() {
    light.turnOff()
    }
    }

    // 具体命令:关闭灯
    class TurnOffLightCommand(private val light: Light) : Command {
    override fun execute() {
    light.turnOff()
    }

    override fun undo() {
    light.turnOn()
    }
    }

    // 调用者:遥控器
    class RemoteControl {
    private val commandHistory = mutableListOf<Command>()

    fun setCommand(command: Command) {
    commandHistory.add(command)
    command.execute()
    }

    fun undoLastCommand() {
    if (commandHistory.isNotEmpty()) {
    val lastCommand = commandHistory.removeAt(commandHistory.size - 1)
    lastCommand.undo()
    }
    }
    }

    // 客户端
    fun main() {
    val light = Light()
    val turnOnCommand = TurnOnLightCommand(light)
    val turnOffCommand = TurnOffLightCommand(light)

    val remoteControl = RemoteControl()

    // 打开灯
    remoteControl.setCommand(turnOnCommand)

    // 关闭灯
    remoteControl.setCommand(turnOffCommand)

    // 撤销操作
    remoteControl.undoLastCommand()
    }

    在 Android 中的应用中,按钮点击事件、视频播放器控制等都是命令模式

  • 观察者模式(Observer)

    观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,当被观察的对象(Subject)状态发生改变时,所有依赖于它的观察者(Observers)都会收到通知并更新

    1. Subject(被观察者)
      • 保存观察者的引用,并提供注册(addObserver)、移除(removeObserver)和通知(notifyObservers)的方法。
    2. Observer(观察者接口)
      • 定义更新的接口,所有观察者必须实现此接口。
    3. ConcreteSubject(具体被观察者)
      • 实现被观察者接口,维护具体的状态,并在状态改变时通知观察者。
    4. ConcreteObserver(具体观察者)
      • 实现观察者接口,具体处理收到的通知。

    以天气监测系统为例,WeatherStation(天气站)是被观察者,而手机和网页应用是观察者。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    // 观察者接口
    interface Observer {
    fun update(temperature: Float, humidity: Float, pressure: Float)
    }

    // 被观察者接口
    interface Subject {
    fun addObserver(observer: Observer)
    fun removeObserver(observer: Observer)
    fun notifyObservers()
    }

    // 具体被观察者
    class WeatherStation : Subject {
    private val observers = mutableListOf<Observer>()
    private var temperature: Float = 0.0f
    private var humidity: Float = 0.0f
    private var pressure: Float = 0.0f

    override fun addObserver(observer: Observer) {
    observers.add(observer)
    }

    override fun removeObserver(observer: Observer) {
    observers.remove(observer)
    }

    override fun notifyObservers() {
    for (observer in observers) {
    observer.update(temperature, humidity, pressure)
    }
    }

    // 模拟数据更新
    fun setMeasurements(temperature: Float, humidity: Float, pressure: Float) {
    this.temperature = temperature
    this.humidity = humidity
    this.pressure = pressure
    notifyObservers() // 数据变化时通知观察者
    }
    }

    // 具体观察者:手机应用
    class MobileApp : Observer {
    override fun update(temperature: Float, humidity: Float, pressure: Float) {
    println("MobileApp - 温度: $temperature, 湿度: $humidity, 压力: $pressure")
    }
    }

    // 具体观察者:网页应用
    class WebApp : Observer {
    override fun update(temperature: Float, humidity: Float, pressure: Float) {
    println("WebApp - 温度: $temperature, 湿度: $humidity, 压力: $pressure")
    }
    }

    // 客户端代码
    fun main() {
    val weatherStation = WeatherStation()

    val mobileApp = MobileApp()
    val webApp = WebApp()

    // 注册观察者
    weatherStation.addObserver(mobileApp)
    weatherStation.addObserver(webApp)

    // 模拟天气变化
    weatherStation.setMeasurements(25.0f, 65.0f, 1013.0f)
    weatherStation.setMeasurements(27.0f, 70.0f, 1012.0f)

    // 移除观察者
    weatherStation.removeObserver(webApp)

    // 模拟新数据
    weatherStation.setMeasurements(28.0f, 75.0f, 1011.0f)
    }

    在 Android Jetpack 的架构中,LiveDataEventBusBroadcastReceiver等是观察者模式的典型应用

  • 中介者模式(Mediator)

    中介者模式是一种行为型设计模式,它通过一个中介对象来封装一组对象之间的交互。中介者模式通过将对象间复杂的网状关系转换为中介者与对象之间的单向关系,来降低对象之间的耦合性,从而更容易实现对象的独立复用。

    1. Mediator(中介者接口)
      • 定义了一个接口,用于通信和协调不同对象之间的交互。
    2. ConcreteMediator(具体中介者)
      • 实现中介者接口,协调和管理不同同事对象之间的通信。
    3. Colleague(同事类接口)
      • 定义与中介者通信的接口,持有中介者的引用。
    4. ConcreteColleague(具体同事类)
      • 实现同事类接口,通过中介者与其他同事类进行通信。

    以聊天室为例,中介者负责管理用户之间的消息传递。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    // 中介者接口
    interface ChatMediator {
    fun sendMessage(msg: String, sender: User)
    fun addUser(user: User)
    }

    // 具体中介者
    class ChatRoomMediator : ChatMediator {
    private val users = mutableListOf<User>()

    override fun addUser(user: User) {
    users.add(user)
    }

    override fun sendMessage(msg: String, sender: User) {
    for (user in users) {
    // 消息不能发送给自己
    if (user != sender) {
    user.receive(msg)
    }
    }
    }
    }

    // 同事类
    abstract class User(val mediator: ChatMediator, val name: String) {
    abstract fun send(msg: String)
    abstract fun receive(msg: String)
    }

    // 具体同事类
    class ChatUser(mediator: ChatMediator, name: String) : User(mediator, name) {
    override fun send(msg: String) {
    println("$name 发送消息: $msg")
    mediator.sendMessage(msg, this)
    }

    override fun receive(msg: String) {
    println("$name 收到消息: $msg")
    }
    }

    // 客户端代码
    fun main() {
    val mediator = ChatRoomMediator()

    val user1 = ChatUser(mediator, "Alice")
    val user2 = ChatUser(mediator, "Bob")
    val user3 = ChatUser(mediator, "Charlie")

    mediator.addUser(user1)
    mediator.addUser(user2)
    mediator.addUser(user3)

    user1.send("Hello everyone!")
    user2.send("Hi Alice!")
    }

    在 Android 中的应用,ViewGroup 充当中介者的角色,它管理和协调子 View 之间的关系;

    Navigation 组件也是中介者模式的典型实现。它负责在不同的 Fragment 之间进行导航,并解耦了 Fragment 与 Activity 的直接关系。

    中介者模式在 Android 中有着广泛的应用,从 UI 控件的布局管理到 Jetpack 的架构组件,提供了解耦和集中管理的优势。通过中介者,可以有效地简化复杂系统中的交互逻辑,同时增强系统的扩展性和可维护性。

  • 状态模式(State)

    状态模式是一种行为型设计模式,它允许一个对象在其内部状态改变时改变其行为。也就是说,状态模式通过将状态的逻辑分散到状态类中,避免了在对象中使用大量的条件语句来管理状态。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    // 状态接口
    interface ElevatorState {
    fun pressButton(context: ElevatorContext)
    }

    // 具体状态:电梯运行中
    class MovingState : ElevatorState {
    override fun pressButton(context: ElevatorContext) {
    println("电梯正在运行,按钮无效。")
    }
    }

    // 具体状态:电梯停止中
    class StoppedState : ElevatorState {
    override fun pressButton(context: ElevatorContext) {
    println("电梯停止中,开始运行。")
    context.setState(MovingState())
    }
    }

    // 上下文类
    class ElevatorContext {
    private var state: ElevatorState = StoppedState()

    fun setState(state: ElevatorState) {
    this.state = state
    }

    fun pressButton() {
    state.pressButton(this)
    }
    }

    // 测试代码
    fun main() {
    val elevator = ElevatorContext()

    elevator.pressButton() // 电梯停止中,开始运行。
    elevator.pressButton() // 电梯正在运行,按钮无效。
    }

    在 Android 中,MediaPlayer 是状态模式的一个实际应用。

    Android 的 View 组件通常具有多种状态,例如 ButtonEnabledDisabled 状态

  • 策略模式(Strategy)

    策略模式是一种行为型设计模式,它定义了一系列算法(策略),并将它们封装到独立的类中,使它们可以互相替换,而不影响使用这些算法的客户端代码。

    策略模式的核心思想是:将算法的定义与使用分离,使得客户端能够灵活地选择不同的策略来完成任务。

    以支付系统为例:支持不同的支付方式(如支付宝、微信支付、银行卡支付)。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    // 策略接口
    interface PaymentStrategy {
    fun pay(amount: Double)
    }

    // 具体策略:支付宝支付
    class AlipayStrategy : PaymentStrategy {
    override fun pay(amount: Double) {
    println("使用支付宝支付 $amount 元")
    }
    }

    // 具体策略:微信支付
    class WeChatPayStrategy : PaymentStrategy {
    override fun pay(amount: Double) {
    println("使用微信支付 $amount 元")
    }
    }

    // 具体策略:银行卡支付
    class BankCardStrategy : PaymentStrategy {
    override fun pay(amount: Double) {
    println("使用银行卡支付 $amount 元")
    }
    }

    // 上下文类
    class PaymentContext(private var strategy: PaymentStrategy) {
    fun setStrategy(strategy: PaymentStrategy) {
    this.strategy = strategy
    }

    fun executePayment(amount: Double) {
    strategy.pay(amount)
    }
    }

    // 测试代码
    fun main() {
    val paymentContext = PaymentContext(AlipayStrategy())

    // 使用支付宝支付
    paymentContext.executePayment(100.0)

    // 切换为微信支付
    paymentContext.setStrategy(WeChatPayStrategy())
    paymentContext.executePayment(200.0)

    // 切换为银行卡支付
    paymentContext.setStrategy(BankCardStrategy())
    paymentContext.executePayment(300.0)
    }

    RecyclerView 的 ItemDecoration 是一种灵活的实现策略模式的方式,可以通过不同的 ItemDecoration 策略来设置间距、分隔线等。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    class CustomItemDecoration(private val strategy: DecorationStrategy) : RecyclerView.ItemDecoration() {
    override fun getItemOffsets(
    outRect: Rect,
    view: View,
    parent: RecyclerView,
    state: RecyclerView.State
    ) {
    strategy.decorate(outRect, view, parent, state)
    }
    }

    // 策略接口
    interface DecorationStrategy {
    fun decorate(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State)
    }

    // 具体策略:设置均等间距
    class EqualSpacingStrategy(private val space: Int) : DecorationStrategy {
    override fun decorate(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
    outRect.set(space, space, space, space)
    }
    }

    // 具体策略:仅设置底部间距
    class BottomSpacingStrategy(private val space: Int) : DecorationStrategy {
    override fun decorate(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
    outRect.set(0, 0, 0, space)
    }
    }

    // 使用
    val recyclerView: RecyclerView = ...
    recyclerView.addItemDecoration(CustomItemDecoration(EqualSpacingStrategy(16)))

  • 访问者模式(Visitor)

    访问者模式是一种行为型设计模式,它允许我们在不改变数据结构(对象模型)的情况下,向结构中的元素添加新的行为(操作)。
    通过将操作逻辑与对象结构分离,访问者模式实现了对操作的解耦,使得新的操作能够灵活地添加到结构中。

    假设我们有一个应用,其中有不同类型的视图(例如,按钮、文本框和图像),每个视图需要执行不同的操作,比如设置不同的样式或响应不同的事件。我们可以通过访问者模式来集中这些操作。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    // 访问者接口
    interface ViewVisitor {
    fun visit(button: ButtonView)
    fun visit(textView: TextViewView)
    fun visit(imageView: ImageViewView)
    }

    // 具体访问者
    class StyleVisitor : ViewVisitor {
    override fun visit(button: ButtonView) {
    println("Applying style to Button")
    // Apply button style
    }

    override fun visit(textView: TextViewView) {
    println("Applying style to TextView")
    // Apply textview style
    }

    override fun visit(imageView: ImageViewView) {
    println("Applying style to ImageView")
    // Apply imageview style
    }
    }

    // 元素接口
    interface ViewComponent {
    fun accept(visitor: ViewVisitor)
    }

    // 具体元素
    class ButtonView : ViewComponent {
    override fun accept(visitor: ViewVisitor) {
    visitor.visit(this)
    }
    }

    class TextViewView : ViewComponent {
    override fun accept(visitor: ViewVisitor) {
    visitor.visit(this)
    }
    }

    class ImageViewView : ViewComponent {
    override fun accept(visitor: ViewVisitor) {
    visitor.visit(this)
    }
    }

    // 对象结构
    class ViewContainer {
    private val views: MutableList<ViewComponent> = mutableListOf()

    fun addView(view: ViewComponent) {
    views.add(view)
    }

    fun applyStyles(visitor: ViewVisitor) {
    views.forEach { it.accept(visitor) }
    }
    }

    fun main() {
    val viewContainer = ViewContainer()

    val buttonView = ButtonView()
    val textViewView = TextViewView()
    val imageViewView = ImageViewView()

    viewContainer.addView(buttonView)
    viewContainer.addView(textViewView)
    viewContainer.addView(imageViewView)

    // 使用访问者进行样式应用
    val styleVisitor = StyleVisitor()
    viewContainer.applyStyles(styleVisitor)
    }

  • 迭代器模式(Iterator)

    **迭代器模式(Iterator Pattern)**是一种行为型设计模式,允许客户端访问一个集合对象的元素而不暴露集合对象的内部结构。它提供了一种方法来依次访问集合中的每一个元素,而不需要知道集合的具体实现。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    // 迭代器接口
    interface Iterator<T> {
    fun hasNext(): Boolean
    fun next(): T
    }

    // 具体迭代器
    class ConcreteIterator<T>(private val collection: List<T>) : Iterator<T> {
    private var position = 0

    override fun hasNext(): Boolean {
    return position < collection.size
    }

    override fun next(): T {
    if (this.hasNext()) {
    return collection[position++]
    } else {
    throw NoSuchElementException("No more elements")
    }
    }
    }

    // 聚合接口
    interface Aggregate<T> {
    fun createIterator(): Iterator<T>
    }

    // 具体聚合
    class ConcreteAggregate<T>(private val items: List<T>) : Aggregate<T> {
    override fun createIterator(): Iterator<T> {
    return ConcreteIterator(items)
    }
    }

    fun main() {
    val aggregate = ConcreteAggregate(listOf("A", "B", "C", "D", "E"))
    val iterator = aggregate.createIterator()

    while (iterator.hasNext()) {
    println(iterator.next())
    }
    }

    在 Android 开发中,迭代器模式通常用于以下场景:

    1. 遍历列表:例如,RecyclerView 和 ListView 中使用适配器模式进行数据绑定时,可以使用迭代器模式对数据进行遍历。
    2. 遍历视图:对于动态生成的视图,使用迭代器模式可以更方便地遍历和操作它们。例如,逐一为每个子视图设置样式、事件等。
    3. 多种数据集合的遍历:当应用中有不同类型的数据集合(例如,List、Set、Map)时,可以统一使用迭代器模式来遍历所有这些集合。
  • 备忘录模式(Memento)

    **备忘录模式(Memento Pattern)**是一种行为型设计模式,允许在不暴露对象内部状态的情况下保存和恢复对象的状态。这个模式的目的是在对象状态发生变化时,保存其先前的状态,以便后续可以恢复。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    // 备忘录类,用于存储对象的状态
    data class Memento(val state: String)

    // 发起人类,表示需要备份和恢复状态的对象
    class Originator(var state: String) {

    // 创建备忘录,保存当前状态
    fun createMemento(): Memento {
    return Memento(state)
    }

    // 从备忘录中恢复状态
    fun restoreMemento(memento: Memento) {
    this.state = memento.state
    }

    // 显示当前状态
    fun showState() {
    println("State: $state")
    }
    }

    // 负责人类,管理备忘录对象
    class Caretaker {

    private val mementos: MutableList<Memento> = mutableListOf()

    // 保存备忘录
    fun addMemento(memento: Memento) {
    mementos.add(memento)
    }

    // 获取指定位置的备忘录
    fun getMemento(index: Int): Memento {
    return mementos[index]
    }
    }

    fun main() {
    val originator = Originator("State 1") // 创建一个发起人对象
    val caretaker = Caretaker() // 创建负责人对象

    originator.showState() // 显示当前状态

    // 创建并保存备忘录
    caretaker.addMemento(originator.createMemento())

    // 改变状态
    originator.state = "State 2"
    originator.showState() // 显示新状态

    // 恢复状态
    originator.restoreMemento(caretaker.getMemento(0))
    originator.showState() // 显示恢复的状态
    }

    在 Android 开发中,备忘录模式通常应用于以下场景:

    1. 撤销/重做功能:例如,图像编辑器、文本编辑器等应用中,可以通过保存编辑的历史状态来实现撤销和重做功能。
      • 例如:在绘图应用中,用户每次操作都生成一个备忘录,在需要撤销时恢复到某个历史状态。
    2. 游戏存档和回滚操作:游戏应用中的存档功能,通过保存游戏的当前状态,可以实现随时恢复游戏进度。
      • 例如:每次玩家进入一个新关卡时,可以保存当前的游戏状态,以便于在玩家退出后再次恢复。
    3. 复杂的数据表单提交:在处理复杂表单时,如果用户在提交前需要返回并查看之前的状态,可以通过备忘录保存表单数据的状态。
      • 例如:表单中输入的数据、选择的选项等都可以通过备忘录模式进行管理和恢复。