Ruby使用设计模式中的代理模式与装饰模式的代码实例
代理模式
需求:
小明让小李替他追小丽(送洋娃娃,送花,送巧克力)
没有代理的代码:
#-*-encoding:utf-8-*- #追求者类 classPursuit attr_accessor:mm definitialize(mm) @mm=mm end defgive_dolls puts"#{mm.name}送你洋娃娃" end defgive_flowers puts"#{mm.name}送你鲜花" end defgive_chocolate puts"#{mm.name}送你巧克力" end end #被追求者类 classGirl attr_accessor:name definitialize(name) @name=name end end xiao_hong=Girl.new('小红') xiao_ming=Pursuit.new(xiao_hong) xiao_ming.give_dolls xiao_ming.give_flowers xiao_ming.give_chocolate
只有代理的代码:
#-*-encoding:utf-8-*- #代理类 classProxy attr_accessor:mm definitialize(mm) @mm=mm end defgive_dolls puts"#{mm.name}送你洋娃娃" end defgive_flowers puts"#{mm.name}送你鲜花" end defgive_chocolate puts"#{mm.name}送你巧克力" end end #被追求者类 classGirl attr_accessor:name definitialize(name) @name=name end end xiao_hong=Girl.new('小红') xiao_ming=Proxy.new(xiao_hong) xiao_ming.give_dolls xiao_ming.give_flowers xiao_ming.give_chocolate
只是把追求者类换成了代理类。
实际的代理模式代码:
#-*-encoding:utf-8-*- #公共接口module moduleGiveGift defgive_dolls end defgive_flowers end defgive_chocolate end end #追求者类 classPursuit includeGiveGift attr_accessor:mm,:name definitialize(mm) @mm=mm end defgive_dolls puts"#{mm.name}替#{name}送你洋娃娃" end defgive_flowers puts"#{mm.name}替#{name}送你鲜花" end defgive_chocolate puts"#{mm.name}替#{name}送你巧克力" end end #代理类 classProxy includeGiveGift attr_accessor:gg definitialize(mm) @gg=Pursuit.new(mm) end defgive_dolls gg.give_dolls end defgive_flowers gg.give_flowers end defgive_chocolate gg.give_chocolate end end #被追求者类 classGirl attr_accessor:name definitialize(name) @name=name end end xiao_hong=Girl.new('小红') xiao_ming=Proxy.new(xiao_hong) xiao_ming.gg.name='小明' xiao_ming.give_dolls xiao_ming.give_flowers xiao_ming.give_chocolate
装饰模式
需求:
给人搭配不同的服饰
代码版本一
#-*-encoding:utf-8-*- classPerson attr_accessor:name definitialize(name) @name=name end defwear_t_shirts puts'大T恤' end defwear_big_trouser puts'垮裤' end defwear_sneakers puts'破球鞋' end defwear_suit puts'西装' end defwear_tie puts'领带' end defwear_leather_shoes puts'皮鞋' end defshow 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-*- classPerson attr_accessor:name definitialize(name) @name=name enddefshow puts"*****装扮的#{name}\n\n" end end classFinery defshow end end classTShirts<Finery defshow puts'大T恤' end end classBigTrouser<Finery defshow puts'垮裤' end end classSneakers<Finery defshow puts'破球鞋' end end classSuit<Finery defshow puts'西装' end end classTie<Finery defshow puts'领带' end end classLeatherShoes<Finery defshow 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-*- classPerson attr_accessor:name definitialize(name=nil) @name=name end defshow puts"*****装扮的#{name}\n\n" end end classFinery<Person attr_accessor:componet defdecorate(componet) @componet=componet end defshow componet.showifcomponet end end classTShirts<Finery defshow super puts'大T恤' end end classBigTrouser<Finery defshow super puts'垮裤' end end classSneakers<Finery defshow super puts'破球鞋' end end classSuit<Finery defshow super puts'西装' end end classTie<Finery defshow super puts'领带' end end classLeatherShoes<Finery defshow super puts'皮鞋' end end xc=Person.new('小菜') ts=TShirts.new bt=BigTrouser.new sk=Sneakers.new puts"******第一种装扮" ts.decoratexc bt.decoratets sk.decoratebt sk.show suit=Suit.new tie=Tie.new ls=LeatherShoes.new puts"******第二种装扮" suit.decoratexc tie.decoratesuit ls.decoratebt ls.show