《大话设计模式》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"
    end

end


xc=Person.new('小菜')
puts  "******第一种装扮"
xc.wear_t_shirts
xc.wear_big_trouser
xc.wear_sneakers
xc.show

puts  "******第二种装扮"
xc.wear_suit
xc.wear_tie
xc.wear_leather_shoes
xc.show

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

 

代码版本二

# -*- encoding: utf-8 -*-

class Person
    attr_accessor :name
    
    def initialize(name)
        @name = name
    enddef show
        puts "*****装扮的#{name}\n\n"
    end

end


class Finery
    def show
    end
end

class TShirts < Finery
    def show
        puts '大T恤'
    end
end

class BigTrouser < Finery
    def show
        puts '垮裤'
    end
end

class Sneakers < Finery
    def show
        puts '破球鞋'
    end
end

class Suit < Finery
    def show
        puts '西装'
    end
end

class Tie < Finery
    def show
        puts '领带'
    end
end


class LeatherShoes < Finery
    def show
        puts '皮鞋'
    end
end


xc=Person.new('小菜')
ts = TShirts.new
bt = BigTrouser.new
sk = Sneakers.new
puts  "******第一种装扮"
ts.show
bt.show
sk.show
xc.show


suit = Suit.new
tie = Tie.new
ls = LeatherShoes.new
puts  "******第二种装扮"
suit.show
tie.show
ls.show
xc.show

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

代码版本三

 

# -*- encoding: utf-8 -*-

class Person
    attr_accessor :name
    
    def initialize(name=nil)
        @name = name
    end
    
    def show
        puts "*****装扮的#{name}\n\n"
    end

end


class Finery < Person
    attr_accessor :componet

    def decorate(componet)
        @componet = componet
    end

    def show
        componet.show if componet
    end
end

class TShirts < Finery
    def show
        super
        puts '大T恤'
    end
end

class BigTrouser < Finery
    def show
        super
        puts '垮裤'
    end
end

class Sneakers < Finery
    def show
        super
        puts '破球鞋'
    end
end

class Suit < Finery
    def show
        super
        puts '西装'
    end
end

class Tie < Finery
    def show
        super
        puts '领带'
    end
end


class LeatherShoes < Finery
    def show
        super
        puts '皮鞋'
    end
end


xc=Person.new('小菜')
ts = TShirts.new
bt = BigTrouser.new
sk = Sneakers.new
puts  "******第一种装扮"
ts.decorate xc
bt.decorate ts
sk.decorate bt
sk.show


suit = Suit.new
tie = Tie.new
ls = LeatherShoes.new
puts  "******第二种装扮"
suit.decorate xc
tie.decorate suit
ls.decorate bt
ls.show

 

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

 

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

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

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

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

优点

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

posted @ 2014-12-31 22:11  范孝鹏  阅读(245)  评论(0编辑  收藏  举报