• 安卓常见设计模式8------享元模式(Kotlin版)


    1. W1 是什么,什么是享元模式?​

    1. 享元模式(Flyweight Pattern)是一种结构型设计模式,用于有效地支持大量细粒度的对象共享。
    2. 在 Android 中,享元模式可以用于减少内存使用和提高性能,特别是在需要创建大量相似对象的情况下。

    2. W2 为什么,为什么需要使用享元模式,能给我们编码带来什么好处?​

    1. 资源利用率提高:享元模式可以实现对象的共享,减少了系统中相同对象的数量,从而降低了内存的占用。通过共享对象,可以提高系统的资源利用率,特别是在需要创建大量相似对象的情况下。

    2. 性能提升:由于享元模式减少了对象的数量,减少了对象的创建和销毁开销,从而提高了系统的性能。通过共享对象,可以避免重复创建相同的对象,减少了系统中频繁的对象创建和销毁操作,提高了系统的响应速度和效率。

    3. 内存占用减少:通过共享相同的对象,享元模式可以减少内存的占用。相同的对象只需保存一份,而不是为每个对象都保存一份数据,从而降低了内存的使用量。这对于需要创建大量对象的应用程序来说尤为重要。

    4. 状态外部化:享元模式将对象的状态外部化,使得对象可以共享状态。这样可以简化对象的内部状态,使对象更加轻量级。状态的外部化也使得对象的状态可以在多个对象之间共享和传递,提供了更大的灵活性和可扩展性。

    解释:当我们使用享元模式时,可以将对象的一部分状态(称为内部状态)从对象内部移到对象外部,这就是状态外部化。这样做的目的是让多个对象可以共享相同的状态,从而节省内存并提高性能。

    想象一下,你正在玩一个多人游戏,每个玩家都有一个角色对象。这些角色对象可能有一些共同的属性,比如血量、等级等。使用享元模式,我们可以将这些共同的属性作为内部状态,并将其存储在一个共享的对象中。

    这意味着每个角色对象只需要存储自己的特有属性(称为外部状态),比如位置、装备等。而那些共同的属性,比如血量和等级,可以由共享对象管理和维护。

    通过共享内部状态,我们可以大大减少内存消耗,因为相同的属性只需要在内存中存储一份。此外,当需要修改共享属性时,只需修改共享对象的状态,而不需要修改每个角色对象的状态。

    这种方式还提供了灵活性和可扩展性。如果新的角色加入游戏,它们可以共享现有的属性,而无需创建新的对象。同时,如果需要改变共享属性的行为,只需修改共享对象即可,这将自动影响到所有共享该属性的角色对象。

    1. 可维护性提高:通过使用享元模式,可以明确区分内部状态和外部状态,使得代码结构更加清晰和易于理解。共享对象的管理集中化,使得代码更加易于维护和扩展。

    4. W3,如何使用?下面是代码示例:

    // 在一个文字处理app中,用户可以选择不同的字体来设置文本样式。然而,创建和管理大量字体对象可能会导致内存消耗过高。这时可以使用享元模式来共享和复用已经创建的字体对象,从而减少内存占用。

    首先,我们定义享元对象接口 Font,它表示字体对象:

    interface Font {
        fun apply(text: String): String
    }
    
    • 1
    • 2
    • 3

    然后,我们创建具体的享元对象实现,例如 ArialFont 和 TimesNewRomanFont:

    class ArialFont : Font {
        override fun apply(text: String): String {
            return "$text"
        }
    }
    
    class TimesNewRomanFont : Font {
        override fun apply(text: String): String {
            return "$text"
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这个例子中,我们假设字体对象的 apply 方法会将给定的文本应用相应的字体样式,并返回带有 HTML 标记的文本。

    接下来,我们创建享元工厂类 FontFactory,用于创建和管理字体对象:

    object FontFactory {
        private val fonts: MutableMap<String, Font> = HashMap()
    
        fun getFont(fontName: String): Font {
            return fonts.getOrPut(fontName) {
                when (fontName) {
                    "Arial" -> ArialFont()
                    "Times New Roman" -> TimesNewRomanFont()
                    else -> throw IllegalArgumentException("Unsupported font: $fontName")
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这个例子中,我们使用一个 MutableMap 来存储已经创建的字体对象,并根据字体名称进行查找和创建。

    最后,我们可以在文字处理应用中使用享元模式来管理字体对象的创建和使用:

    // 在文字处理应用中的某个类中
    fun applyFontToText(text: String, fontName: String) {
        val font = FontFactory.getFont(fontName)
        val formattedText = font.apply(text)
        // 应用带有字体样式的文本到界面上
        // ...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    通过使用享元模式,我们可以避免重复创建相同字体的对象,而是共享和复用已经创建的字体对象,从而减少了内存占用。

    Thank you for your reading, best regards!

  • 相关阅读:
    jboss-cve-2017-12149
    具有细胞膜通透性的铕配合物单线态氧荧光探针/细胞膜次氯酸根荧光探针的相关研究
    【006身高绝对值排序(C++)】
    runHiC分析HiC_seq数据
    ClickHouse的介绍(基本sql操作,以及数据库引擎、表引擎、分片、副本、explain、优化、物化视图等)
    uboot移植之DDR初始化参数更改
    【Node.JS 练习】时钟案例
    C++实现高性能内存池(一)
    沉睡者 - 现在的人为什么不好好工作,都想着「搞点副业」?
    强平jraft阻塞和运维问题-试验对比计划
  • 原文地址:https://blog.csdn.net/qq_42751010/article/details/134296421