一周两个设计模式—设计模式之享元模式(第四周)

举报
浮生闲半日 发表于 2021/11/17 14:52:50 2021/11/17
【摘要】 背景:书接上文,自从小犬把天堂咖啡厅的项目做完之后,瞬间在天庭的技术圈是名声四起,是公认的大牛级人物了,昨天又顺利牵到玉兔的小手,弄得这只万年单身汪兴奋到了后半夜,今天小犬刚从美梦中醒来接到了一个电话,一看来显,哪吒三太子,该不会是系统出问题了吧,赶紧接听,原来是天庭职称考试,哪吒居然报了个技术岗位,于是哪吒最近狂补技术知识,这不昨天看到了享元模式,死活理解不了(毕竟三头六臂,不太理解共享)...

背景:

书接上文,自从小犬把天堂咖啡厅的项目做完之后,瞬间在天庭的技术圈是名声四起,是公认的大牛级人物了,
昨天又顺利牵到玉兔的小手,弄得这只万年单身汪兴奋到了后半夜,今天小犬刚从美梦中醒来接到了一个电话,一看来显,哪吒三太子,
该不会是系统出问题了吧,赶紧接听,原来是天庭职称考试,哪吒居然报了个技术岗位,于是哪吒最近狂补技术知识,这不昨天看到了
享元模式,死活理解不了(毕竟三头六臂,不太理解共享),这不找到技术大牛哮天犬了。

小犬一听,享元模式,这个倒不是很难,于是就有了一下的介绍。

定义:

如果一个对象实例一经创建就不可变,那么反复创建相同的实例就没有必要,直接向调用方返回一个共享的实例就行,
这样即节省内存,又可以减少创建对象的过程,提高运行速度。共享一个对象。享元模式是池技术的重要实现方式,缓存。

UML图:(网上找的)

享元模式UML.png

Flyweight是抽象享元角色。它是产品的抽象类,同时定义出对象的外部状态和内部状态的接口或实现;
内在状态:不随环境的变化而变化,上面例子中不管位置如何变化,A就是A。字母A就是内在状态。
外在状态:会随着环境的变化而变化,上面例子中位置变化所以输出的位置也是不一致的。字母A的位置就是外在状态

ConcreteFlyweight是具体享元角色,是具体的产品类,实现抽象角色定义的业务;

UnsharedConcreteFlyweight是不可共享的享元角色,一般不会出现在享元工厂中;

FlyweightFactory是享元工厂,它用于构造一个池容器,同时提供从池中获得对象的方法。

案例图:

共享案例图.png

享元工厂角色:这个角色主要负责创建和管理享元角色。判断是否存在符合要求的享元对象,如果存在则直接拿取,如果不存在的话就会创建一个享元对象并保存。

抽象享元角色:这个角色是所有享元角色的基类。提供需要实现的公共接口

具体享元角色:继承于抽象享元角色。实现其抽象的接口。

客户端:负责调用并处理逻辑,且保存多有享元对象的状态

代码如下:

Flyweight抽象类

abstract class Flyweight(extrinsic:String) {
    //内部状态
    lateinit var intrinsic:String

    //外部状态,享元角色必须受外部状态
    protected val extrinsic = extrinsic

    /**
     * 定义业务操作
     */
    abstract fun operate(extrinsic:Int)

}

继承Flyweight超类或实现Flyweight接口,并为其内部状态增加存储空间

class ConcreteFlyweight(extrinsic:String):Flyweight(extrinsic) {

    override fun operate(extrinsic: Int) {
        Log.v("===========","具体Flyweight:$extrinsic")
    }

}

指那些不需要共享的Flyweight子类

class UnsharedConcreteFlyweight(extrinsic:String):Flyweight(extrinsic) {
    override fun operate(extrinsic: Int) {
        Log.v("=========","不共享的具体Flyweight:$extrinsic")
    }
}

一个享元工厂,用来创建并管理Flyweight对象,主要是用来确保合理地共享Flyweight,当用户请求一个Flyweight时,

  • FlyweightFactory对象提供一个已创建的实例或创建一个实例。
object FlyweightFactory {

     var pool:HashMap<String,Flyweight> = hashMapOf()

    fun getFlyWeight(extrinsic:String):Flyweight?{
        var flyWeight:Flyweight ?= null

        if(pool.containsKey(extrinsic)){
            flyWeight = pool[extrinsic]
            Log.v("===========", "已有 $extrinsic 直接从池中取---->")
        }else{
            flyWeight = ConcreteFlyweight(extrinsic)
            pool[extrinsic] = flyWeight
            Log.v("===========", "创建 $extrinsic 并从池中取出---->")
        }

        return flyWeight
    }

}

点击实现:

var extrinsic = 22

findViewById<Button>(R.id.btnCreateX).setOnClickListener {
    val flyweightX: Flyweight = FlyweightFactory.getFlyWeight("X")!!
    flyweightX.operate(++extrinsic)
}
findViewById<Button>(R.id.btnCreateY).setOnClickListener {
    val flyweightY: Flyweight = FlyweightFactory.getFlyWeight("Y")!!
    flyweightY.operate(++extrinsic)

}
findViewById<Button>(R.id.btnCreateZ).setOnClickListener {
    val flyweightZ: Flyweight = FlyweightFactory.getFlyWeight("Z")!!
    flyweightZ.operate(++extrinsic)

}
findViewById<Button>(R.id.btnGetX).setOnClickListener {
    val flyweightReX: Flyweight = FlyweightFactory.getFlyWeight("X")!!
    flyweightReX.operate(++extrinsic)
}
findViewById<Button>(R.id.btnGetXX).setOnClickListener {
    val unsharedFlyweight: Flyweight = UnsharedConcreteFlyweight("X")
    unsharedFlyweight.operate(++extrinsic)
}

运行结果:

企业微信截图_16365051982344.png

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。