一周两个设计模式—设计模式之享元模式(第四周)
背景:
书接上文,自从小犬把天堂咖啡厅的项目做完之后,瞬间在天庭的技术圈是名声四起,是公认的大牛级人物了,
昨天又顺利牵到玉兔的小手,弄得这只万年单身汪兴奋到了后半夜,今天小犬刚从美梦中醒来接到了一个电话,一看来显,哪吒三太子,
该不会是系统出问题了吧,赶紧接听,原来是天庭职称考试,哪吒居然报了个技术岗位,于是哪吒最近狂补技术知识,这不昨天看到了
享元模式,死活理解不了(毕竟三头六臂,不太理解共享),这不找到技术大牛哮天犬了。
小犬一听,享元模式,这个倒不是很难,于是就有了一下的介绍。
定义:
如果一个对象实例一经创建就不可变,那么反复创建相同的实例就没有必要,直接向调用方返回一个共享的实例就行,
这样即节省内存,又可以减少创建对象的过程,提高运行速度。共享一个对象。享元模式是池技术的重要实现方式,缓存。
UML图:(网上找的)
Flyweight是抽象享元角色。它是产品的抽象类,同时定义出对象的外部状态和内部状态的接口或实现;
内在状态:不随环境的变化而变化,上面例子中不管位置如何变化,A就是A。字母A就是内在状态。
外在状态:会随着环境的变化而变化,上面例子中位置变化所以输出的位置也是不一致的。字母A的位置就是外在状态
ConcreteFlyweight是具体享元角色,是具体的产品类,实现抽象角色定义的业务;
UnsharedConcreteFlyweight是不可共享的享元角色,一般不会出现在享元工厂中;
FlyweightFactory是享元工厂,它用于构造一个池容器,同时提供从池中获得对象的方法。
案例图:
享元工厂角色:这个角色主要负责创建和管理享元角色。判断是否存在符合要求的享元对象,如果存在则直接拿取,如果不存在的话就会创建一个享元对象并保存。
抽象享元角色:这个角色是所有享元角色的基类。提供需要实现的公共接口
具体享元角色:继承于抽象享元角色。实现其抽象的接口。
客户端:负责调用并处理逻辑,且保存多有享元对象的状态
代码如下:
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)
}
运行结果:
- 点赞
- 收藏
- 关注作者
评论(0)