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