首页 > 代码库 > 《大话设计模式》ruby版代码:装饰模式

《大话设计模式》ruby版代码:装饰模式

需求:

给人搭配不同的服饰

代码版本一

# -*- encoding: utf-8 -*-class Person    attr_accessor :name        def initialize(name)        @name = name    end        def wear_t_shirts        puts 大T恤    end        def wear_big_trouser        puts 垮裤    end        def wear_sneakers        puts 破球鞋    end        def wear_suit        puts 西装    end        def wear_tie        puts 领带    end        def wear_leather_shoes        puts 皮鞋    end        def show        puts "*****装扮的#{name}\n\n"    endendxc=Person.new(小菜)puts  "******第一种装扮"xc.wear_t_shirtsxc.wear_big_trouserxc.wear_sneakersxc.showputs  "******第二种装扮"xc.wear_suitxc.wear_tiexc.wear_leather_shoesxc.show

这样写的话,功能是实现了,问题是如果增加“超人”的装扮,就要修改Person类,违反了开放-封闭原则。

 

代码版本二

# -*- encoding: utf-8 -*-class Person    attr_accessor :name        def initialize(name)        @name = name    enddef show        puts "*****装扮的#{name}\n\n"    endendclass Finery    def show    endendclass TShirts < Finery    def show        puts 大T恤    endendclass BigTrouser < Finery    def show        puts 垮裤    endendclass Sneakers < Finery    def show        puts 破球鞋    endendclass Suit < Finery    def show        puts 西装    endendclass Tie < Finery    def show        puts 领带    endendclass LeatherShoes < Finery    def show        puts 皮鞋    endendxc=Person.new(小菜)ts = TShirts.newbt = BigTrouser.newsk = Sneakers.newputs  "******第一种装扮"ts.showbt.showsk.showxc.showsuit = Suit.newtie = Tie.newls = LeatherShoes.newputs  "******第二种装扮"suit.showtie.showls.showxc.show

这样改了之后,如果增加超人装扮,确实不需要去修改Person类。存在的问题是,各种衣服是独立的,并且暴露在外边的,就是一件一件穿的,没有顺序,没有控制。

代码版本三

 

# -*- encoding: utf-8 -*-class Person    attr_accessor :name        def initialize(name=nil)        @name = name    end        def show        puts "*****装扮的#{name}\n\n"    endendclass Finery < Person    attr_accessor :componet    def decorate(componet)        @componet = componet    end    def show        componet.show if componet    endendclass TShirts < Finery    def show        super        puts 大T恤    endendclass BigTrouser < Finery    def show        super        puts 垮裤    endendclass Sneakers < Finery    def show        super        puts 破球鞋    endendclass Suit < Finery    def show        super        puts 西装    endendclass Tie < Finery    def show        super        puts 领带    endendclass LeatherShoes < Finery    def show        super        puts 皮鞋    endendxc=Person.new(小菜)ts = TShirts.newbt = BigTrouser.newsk = Sneakers.newputs  "******第一种装扮"ts.decorate xcbt.decorate tssk.decorate btsk.showsuit = Suit.newtie = Tie.newls = LeatherShoes.newputs  "******第二种装扮"suit.decorate xctie.decorate suitls.decorate btls.show

 

每穿一件衣服,都会给当前对象的componet赋值,值为已经person或者其子类,这样,最后一个子类的show方法,就会沿着调用顺序,打印出每一个衣服。

 

装饰模式是为已有功能动态地添加更很多功能的一种方式。

当系统需要新功能的时候,是向旧的类中添加新的代码,这些新加的代码通常修饰了原有类的核心职责或主要行为。在主类中加入了新的字段、新的方法和新的逻辑,从而增加了增加了主类的复杂度。这些新加入的东西仅仅是为了满足一些只在某些特定情况下才会执行的特殊行为的需要。

装饰模式提供了一个非常好的解决方案,把每个要装饰的

功能放在单独的类中,并让这个类包装它所修饰的对象,因此,当需要执行特殊行为时,客户代码就可以运行时根据需要有选择地、按顺序地使用装饰对象功能包装对象了。

优点

把类中的装饰功能从类中搬移去除,简化原有的类。有效地把类的核心职责和装饰功能区分开了,而且可以去除相关类中重复的装饰逻辑。

《大话设计模式》ruby版代码:装饰模式