当前位置:网站首页>Kotlin - 改良装饰者模式
Kotlin - 改良装饰者模式
2022-07-03 12:03:00 【GitLqr】
欢迎关注微信公众号:FSA全栈行动
- Kotlin - 改良工厂模式
- Kotlin - 改良构建者模式
- Kotlin - 改良观察者模式
- Kotlin - 改良策略模式
- Kotlin - 改良迭代器模式
- Kotlin - 改良责任链模式
- Kotlin - 改良装饰者模式
一、前言
- 装饰者模式
- 作用:在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。
- 本质:该模式通过创建一个包装对象,来包裹真实的对象。
- 核心操作:
- 创建一个装饰类,包含一个被装饰类的实例
- 装饰类重写所有被装饰类的方法
- 在装饰类中对需要增强的功能进行扩展
二、使用装饰者模式
- 例子:枪支部件
- 重点:装饰器类设计(实现被装饰类相同的接口,构造器接收被装饰类的接口实例对象)
像绝地求生这种大型射击游戏,里面的枪支系统是很复杂的,有很多种枪,而且几乎每种枪上都可以装配各种各样的部件,比如消声器、八倍镜之类的,部件的作用各不相同,有的可以增加火力,有的可以提高精确度,等等,现在我们来简单设计一下这个枪支系统,枪有很多种,所以需要定义一个接口来描述枪都有哪些能力,供后续扩展各种新枪:
/** * 枪支接口 * * @author GitLqr */
interface Gun {
/** * 攻击力 */
fun attack(): Float
/** * 噪音 */
fun noise(): Float
/** * 生产日期 */
fun prodDate(): String
}
/** * Ump9 * * @author GitLqr */
class Ump9Gun : Gun {
override fun attack() = 100f
override fun noise() = 20f
override fun prodDate() = "2020-02-18"
}
这里只实现了 Ump9 这个型号的枪,后续还可以根据需要扩展,现在来想想枪支部件怎么设计?在 Java 中,给一个类扩展行为有两种选择:
- 设计一个继承它的子类
- 使用装饰者模式对该类进行装饰
那么枪支部件合适用继承方式来设计吗?显然不合适,因为一个部件可以装配在不只一种枪上,所以继承这种方式排除。另一种方式,使用装饰者模式有一个很大的优势,在于符合“组合优于继承”的设计原则,我们知道,部件可以和任意枪组合,显示,使用装饰者模式来设计枪支部件是一个不错的选择:
/** * 枪支部件 * * @author GitLqr */
abstract class GunPart(protected val gun: Gun) : Gun
/** * 消声器 * * @author GitLqr */
class Muffler(gun: Gun) : GunPart(gun) {
override fun attack() = gun.attack() - 5
override fun noise() = 0f
override fun prodDate() = gun.prodDate()
}
/** * 燃烧子弹 * * @author GitLqr */
class FireBullet(gun: Gun) : GunPart(gun) {
override fun attack() = gun.attack() + 200
override fun noise() = gun.noise()
override fun prodDate() = gun.prodDate()
}
程序设计时,装饰器(部件)会引用被装饰实例(枪),并实现被装饰实例的所有接口,然后在需要增强的接口方法中加入增强逻辑。因为枪支部件 GunPart 接收 Gun 类型构造参数,而且本身也是 Gun 接口的实现类,所以,可以让多种枪支部件 GunPart 嵌套修饰枪实例:
// 使用
var ump9: Gun = Ump9Gun()
println("装配前:ump9 攻击力 ${
ump9.attack()},噪音 ${
ump9.noise()}")
ump9 = Muffler(FireBullet(ump9)) // 装配了 燃烧子弹、消声器 的ump9
println("装配后:ump9 攻击力 ${
ump9.attack()},噪音 ${
ump9.noise()}")
// 输出
装配前:ump9 攻击力 100.0,噪音 20.0
装配后:ump9 攻击力 295.0,噪音 0.0
三、改良装饰者模式
- 例子:枪支部件
- 重点:类委托(
by关键字)
在上面的例子中,装饰者模式可以很好的解决实例组合的情况,但是代码还是显得比较啰唆,因为需要重写所有的装饰对象方法,所以可能会存在大量样板代码。比如 FireBullet 只装饰增强 attack() 方法,而 noise()、prodDate() 均不做修改,但还要是把这两个方法重写一遍。Kotlin 中有类委托特性,利用 by 关键字,将装饰类的所有方法委托给一个被装饰的类对象,然后只需覆写装饰的方法即可:
/** * 枪支部件 * * @author GitLqr */
abstract class GunPart(protected val gun: Gun) : Gun by gun
/** * 消声器 * * @author GitLqr */
class Muffler(gun: Gun) : GunPart(gun) {
override fun attack() = gun.attack() - 5
override fun noise() = 0f
}
/** * 燃烧子弹 * * @author GitLqr */
class FireBullet(gun: Gun) : GunPart(gun) {
override fun attack() = gun.attack() + 200
}
可以看到,使用类委托之后,装饰类 FireBullet 中的样板代码不用重写了,从而减少了代码量。
如果文章对您有所帮助, 请不吝点击关注一下我的微信公众号:FSA全栈行动, 这将是对我最大的激励. 公众号不仅有Android技术, 还有iOS, Python等文章, 可能有你想要了解的技能知识点哦~
边栏推荐
- 【习题六】【数据库原理】
- Detailed explanation of the most complete constraintlayout in history
- The upward and downward transformation of polymorphism
- It feels great to know you learned something, isn‘t it?
- Kung Fu pays off, and learning is done
- Oh my Zsh + TMUX installation
- CNN MNIST handwriting recognition
- I'm too lazy to write more than one character
- Xctf mobile--app3 problem solving
- Four problems and isolation level of MySQL concurrency
猜你喜欢

最新版盲盒商城thinkphp+uniapp

Day 1 of kotlin learning: simple built-in types of kotlin

Harmonic current detection based on synchronous coordinate transformation

Xctf mobile--app1 problem solving

Gan totem column bridgeless boost PFC (single phase) seven PFC duty cycle feedforward

idea将web项目打包成war包并部署到服务器上运行

Eureka自我保护

T430 toss and install OS majave 10.14

Xctf mobile--rememberother problem solving

Low code platform international multilingual (I18N) technical solution
随机推荐
Method overloading and rewriting
Four problems and isolation level of MySQL concurrency
Approve iPad, which wants to use your icloud account
低代码平台国际化多语言(i18n)技术方案
How to stand out quickly when you are new to the workplace?
如何在微信小程序中获取用户位置?
Seven second order ladrc-pll structure design of active disturbance rejection controller
【数据库原理及应用教程(第4版|微课版)陈志泊】【第六章习题】
【数据库原理及应用教程(第4版|微课版)陈志泊】【SQLServer2012综合练习】
[ManageEngine] the role of IP address scanning
ncnn神經網絡計算框架在香柳丁派OrangePi 3 LTS開發板中的使用介紹
[exercise 7] [Database Principle]
ncnn神经网络计算框架在香橙派OrangePi 3 LTS开发板中的使用介绍
CNN MNIST handwriting recognition
Apache Mina开发手册
最新版盲盒商城thinkphp+uniapp
初入职场,如何快速脱颖而出?
Project video based on Linu development
Sword finger offer03 Repeated numbers in the array [simple]
Record your vulnhub breakthrough record