现需要定制几个品牌的手机,如iPhone、xiaomi、huawei等,根据其功能不同进行定制,再不断的迭代中手机功能需要不停的升级
实例类图
问题来了
问题改进 根本原因在于复用机制的不合理,根据“合成复用原则”,在实现功能复用时,我们要多用关联,少用继承,因此我们可以换个角度来考虑,将PlayGame()方法抽取出来,封装在一个独立的类中,在这个类中定义一个Component类型的对象,通过调用Component的display()方法来显示最基本的构件,同时再通过setScrollBar()方法对基本构件的功能进行增强
动态地给一个对象添加一些额外的职责,就扩展功能来说,装饰模式比生成子类更加灵活
组合模式类图
使用装饰模式进行系统设计时将产生很多小对象,这些对象的区别在于它们之间相互连接的方式有所不同,而不是它们的类或者属性值有所不同,大量小对象的产生势必会占用更多的系统资源,在一定程序上影响程序的性能
需求V1:现需要定制几个品牌的手机,如iPhone、xiaomi、huawei等,根据其功能不同进行定制,再不断的迭代中手机功能需要不停的升级
构建类
//抽象构件,可以给这些对象动态添加方法
class Phone {
func supportFunctions() {
}
}
//具体构件类,也可以给这个对象添加方法
class iPhone : Phone {
var name : String
init(name:String) {
self.name = name
}
override func supportFunctions() {
print("\(self.name)支持以上功能")
}
}
//具体构件类,也可以给这个对象添加方法
class Xiaomi : Phone {
var name : String
init(name:String) {
self.name = name
}
override func supportFunctions() {
print("\(self.name)支持以上功能")
}
}
装饰类
//抽象装饰类,继承Phone从外类来扩展Phone类的功能,但是对于Phone来说,是无需知道PhoneDecorator的存在的
class PhoneDecorator : Phone {
var phone : Phone
init(phone:Phone) {
self.phone = phone
}
override func supportFunctions() {
self.phone.supportFunctions()
}
}
//具体的装饰对象,起到给Phone类添加技能的方法
class PlayGame: PhoneDecorator {
override func supportFunctions() {
self.playGame()
super.supportFunctions()
}
func playGame() {
print("打游戏")
}
}
//具体的装饰对象,起到给Phone类添加技能的方法
class Map : PhoneDecorator{
override func supportFunctions() {
self.map()
super.supportFunctions()
}
func map() {
print("导航")
}
}
客户端
let iphone = iPhone.init(name: "apple")
let playGamePhone = PlayGame.init(phone: iphone)
let mapPhone = Map.init(phone: playGamePhone)
mapPhone.supportFunctions()
let xiaomi = Xiaomi.init(name: "xiaomi")
let mapXiaomi = Map.init(phone: xiaomi)
mapXiaomi.supportFunctions()
log:
//导航
//打游戏
//apple支持以上功能
//导航
//xiaomi支持以上功能
需求V2:再原有基础上,支持音乐播放功能
只需创建PlayMusic继承PhoneDecorator,客户端直接调用便可
class PlayMusic : PhoneDecorator {
override func supportFunctions() {
self.playMusic()
super.supportFunctions()
}
func playMusic() {
print("音乐播放")
}
}
客户端
let xiaomi = Xiaomi.init(name: "xiaomi")
let mapXiaomi = Map.init(phone: xiaomi)
let playMusic = PlayMusic.init(phone: mapXiaomi)
playMusic.supportFunctions()
log
//音乐播放
//导航
//xiaomi支持以上功能