標籤:
需求:
給人搭配不同的服飾
代碼版本一
# -*- 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版代碼:裝飾模式