《大话设计模式》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方法,就会沿着调用顺序,打印出每一个衣服。

 

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

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

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

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

优点

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

你可能感兴趣的:(设计模式)