设计模式 -- 装饰模式

2019-08-14  本文已影响0人  皆为序幕_

场景

现需要定制几个品牌的手机,如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支持以上功能
上一篇 下一篇

猜你喜欢

热点阅读