亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Ruby > 正文

詳解組合模式的結構及其在Ruby設計模式編程中的運用

2020-10-29 19:36:11
字體:
來源:轉載
供稿:網友

定義:也叫合成模式,或者部分-整體模式,主要是用來描述部分與整體的關系,定義,將對象組合成樹形結構以表示“部分-整體”的層次結構,使得用戶對單個對象和組合對象的使用具有一致性。

類圖:

2016316161807337.jpg (431×346)

角色說明:

Componnent抽象構件角色:定義參加組合對象的共有方法和屬性,可以定義一些默認的行為或屬性。
Leaf葉子構件:葉子對象,其下再也沒有其他的分支,也就是遍歷的最小單位。
Composite樹枝構件:樹枝對象,它的作用是組合樹枝節點和葉子節點形成一個樹形結構。

實例:
聽說你們公司最近新推出了一款電子書閱讀應用,市場反應很不錯,應用里還有圖書商城,用戶可以在其中隨意選購自己喜歡的書籍。你們公司也是對此項目高度重視,加大了投入力度,決定給此應用再增加點功能。
好吧,你也知道你是逃不過此劫了,沒過多久你的leader就找到了你。他告訴你目前的應用對每本書的瀏覽量和銷售量做了統計,但現在想增加對每個書籍分類的瀏覽量和銷售量以及所有書籍總的瀏覽量和銷售量做統計的功能,希望你可以來完成這項功能。
領導安排的工作當然是推脫不掉的,你只能硬著頭皮上了,不過好在這個功能看起來也不怎么復雜。
你比較喜歡看小說,那么就從小說類的統計功能開始做起吧。首先通過get_all_novels方法可以獲取到所有的小說名,然后將小說名傳入get_browse_count方法可以得到該書的瀏覽量,將小說名傳入get_sale_count方法可以得到該書的銷售量。你目前只有這幾個已知的API可以使用,那么開始動手吧!

def get_novels_browse_count   browse_count = 0   all_novels = get_all_novels()   all_novels.each do |novel|     browse_count += get_browse_count(novel)   end   browse_count end  def get_novels_sale_count   sale_count = 0   all_novels = get_all_novels()   all_novels.each do |novel|     sale_count += get_browse_count(novel)   end   sale_count end 

很快你就寫下了以上兩個方法,這兩個方法都是通過獲取到所有的小說名,然后一一計算每本小說的瀏覽量和銷售量,最后將結果相加得到總量。
小說類的統計就完成了,然后你開始做計算機類書籍的統計功能,代碼如下所示:

def get_computer_books_browse_count   browse_count = 0   all_computer_books = get_all_computer_books()   all_computer_books.each do |computer_book|     browse_count += get_browse_count(computer_book)   end   browse_count end  def get_computer_books_sale_count   sale_count = 0   all_computer_books = get_all_computer_books()   all_computer_books.each do |computer_book|     sale_count += get_browse_count(computer_book)   end   sale_count end 

除了使用了get_all_computer_books方法獲取到所有的計算機類書名,其它的代碼基本和小說統計中的是一樣的。
現在你才完成了兩類書籍的統計功能,后面還有醫學類、自然類、歷史類、法律類、政治類、哲學類、旅游類、美食類等等等等書籍。你突然意識到了一些問題的嚴重性,工作量大倒還不算什么,但再這么寫下去,你的方法就要爆炸了,這么多的方法讓人看都看不過來,別提怎么使用了。
這個時候你只好向你的leader求助了,跟他說明了你的困惑。只見你的leader思考了片刻,然后自信地告訴你,使用組合模式不僅可以輕松消除你的困惑,還能出色地完成功能。
他立刻向你秀起了編碼操作,首先定義一個Statistics類,里面有兩個方法:

class Statistics      def get_browse_count     raise "You should override this method in subclass."   end      def get_sale_count     raise "You should override this method in subclass."   end    end 

這兩個方法都是簡單地拋出一個異常,因為需要在子類中重寫這兩個方法。
然后定義一個用于統計小說類書籍的NovelStatistics類,繼承剛剛定義的Statistics類,并重寫Statistics中的兩個方法:

class NovelStatistics < Statistics    def get_browse_count     browse_count = 0     all_novels = get_all_novels()     all_novels.each do |novel|       browse_count += get_browse_count(novel)     end     browse_count   end      def get_sale_count     sale_count = 0     all_novels = get_all_novels()     all_novels.each do |novel|       sale_count += get_browse_count(novel)     end     sale_count   end  end 

在這兩個方法中分別統計了小說類書籍的瀏覽量和銷售量。那么同樣的方法,你的leader又定義了一個ComputerBookStatistics類用于統計計算機類書籍的瀏覽量和銷售量:

class ComputerBookStatistics < Statistics    def get_browse_count     browse_count = 0     all_computer_books = get_all_computer_books()     all_computer_books.each do |computer_book|       browse_count += get_browse_count(computer_book)     end     browse_count   end      def get_sale_count     sale_count = 0     all_computer_books = get_all_computer_books()     all_computer_books.each do |computer_book|       sale_count += get_browse_count(computer_book)     end     sale_count   end  end 

這樣將具體的統計實現分散在各個類中,就不會再出現你剛剛那種方法爆炸的情況了。不過這還沒開始真正使用組合模式呢,好戲還在后頭,你的leader吹噓道。

再定義一個MedicalBookStatistics類繼承Statistics,用于統計醫學類書籍的瀏覽量和銷售量,代碼如下如示:

class MedicalBookStatistics < Statistics    def get_browse_count     browse_count = 0     all_medical_books = get_all_medical_books()     all_medical_books.each do |medical_book|       browse_count += get_browse_count(medical_book)     end     browse_count   end      def get_sale_count     sale_count = 0     all_medical_books = get_all_medical_books()     all_medical_books.each do |medical_book|       sale_count += get_browse_count(medical_book)     end     sale_count   end  end 

不知道你發現了沒有,計算機類書籍和醫學類書籍其實都算是科技類書籍,它們是可以組合在一起的。這個時候你的leader定義了一個TechnicalStatistics類用于對科技這一組合類書籍進行統計:

class TechnicalStatistics < Statistics    def initialize     @statistics = []     @statistics << ComputerBookStatistics.new     @statistics << MedicalBookStatistics.new   end    def get_browse_count     browse_count = 0     @statistics.each do |s|       browse_count += s.get_browse_count     end     browse_count   end      def get_sale_count     sale_count = 0     @statistics.each do |s|       sale_count += s.get_sale_count     end     sale_count   end  end 

可以看到,由于這個類是組合類,和前面幾個類還是有不少區別的。首先TechnicalStatistics中有一個構造函數,在構造函數中將計算機類書籍和醫學類書籍作為子分類添加到statistics數組當中,然后分別在get_browse_count和get_sale_count方法中遍歷所有的子分類,計算出它們各自的瀏覽量和銷售量,然后相加得到總額返回。
組合模式的擴展性非常好,沒有各種條條框框,想怎么組合就怎么組合,比如所有書籍就是由各個分類組合而來的,你的leader馬上又向你炫耀了統計所有書籍的瀏覽量和銷售量的辦法。
定義一個AllStatistics類繼承Statistics,具體代碼如下所示:

class AllStatistics < Statistics    def initialize     @statistics = []     @statistics << NovelStatistics.new     @statistics << TechnicalStatistics.new   end    def get_browse_count     browse_count = 0     @statistics.each do |s|       browse_count += s.get_browse_count     end     browse_count   end      def get_sale_count     sale_count = 0     @statistics.each do |s|       sale_count += s.get_sale_count     end     sale_count   end  end 

在AllStatistics的構造函數中將小說類書籍和科技類書籍作為子分類添加到了statistics數組當中,目前你也就只寫好了這幾個分類。然后使用同樣的方法在get_browse_count和get_sale_count方法中統計出所有書籍的瀏覽量和銷售量。
當前組合結構的示意圖如下:

2016316161840481.png (592×336)

現在你就可以非常方便的得到任何分類書籍的瀏覽量和銷售量了,比如說獲取科技類書籍的瀏覽量,你只需要調用:

TechnicalStatistics.new.get_browse_count 

而獲取所有書籍的總銷量,你只需要調用:

AllStatistics.new.get_sale_count 

當然你后面還可以對這個組合結構隨意地改變,添加各種子分類書籍,而且子分類的層次結構可以任意深,正如前面所說,組合模式的擴展性非常好。
你的leader告訴你,目前他寫的這份代碼重復度比較高,其實還可以好好優化一下的,把冗余代碼都去除掉。當然這個任務就交給你來做了,你的leader可是大忙人,早就一溜煙跑開了。

總結

組合模式的優點:
能夠靈活的組合局部對象和整體對象之間的關心,對客戶端來說,局部對象和整體對象的調用沒有差別,使調用簡單。

組合模式的缺點:
1.組合操作的成本很高,如果一個對象樹中有很多子對象,可能一個簡單的調用就可能使系統崩潰;
2.對象持久化的問題,組合模式是樹形結構,不能很好地在關系數據庫中保存數據,但是卻非常適合用于xml持久化。

組合模式的適用場景:
1.維護和展示部分―整體關系得場景,如樹形菜單、文件和文件夾管理。
2.從一個整體中能夠獨立出部分模塊或功能的場景。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久九九国产精品怡红院| 韩日欧美一区二区| 国产福利视频一区| 国产精品永久在线| 国产精品亚洲美女av网站| 亚洲第一视频网| 成人a在线观看| 伊人久久综合97精品| 国产精品夫妻激情| 国产一区玩具在线观看| 91久久国产精品91久久性色| 欧美成年人在线观看| 欧美激情在线视频二区| 色999日韩欧美国产| 国产日韩视频在线观看| 98精品国产自产在线观看| 国产精品扒开腿做爽爽爽男男| 国产精品91在线观看| 色黄久久久久久| 日韩综合中文字幕| 俺去了亚洲欧美日韩| 国产精品扒开腿做| 亚洲人成电影网站色| 精品久久久久国产| 国产欧美va欧美va香蕉在线| 最近中文字幕mv在线一区二区三区四区| 亚洲久久久久久久久久久| 色综合视频网站| 欧美日韩xxx| 亚洲欧美激情在线视频| 日韩精品视频在线观看免费| 日本人成精品视频在线| 国产精品欧美一区二区三区奶水| 永久555www成人免费| 日韩在线中文视频| 81精品国产乱码久久久久久| 麻豆成人在线看| 欧美日韩国产在线| 色哟哟网站入口亚洲精品| 亚洲va久久久噜噜噜| 国产成人一区二| 欧美日韩激情视频| 国产精品一区二区三区毛片淫片| 亚洲人成在线观| 色老头一区二区三区在线观看| 欧美日韩另类字幕中文| 尤物yw午夜国产精品视频| 亚洲精品久久久久久久久久久| 在线丨暗呦小u女国产精品| 色婷婷亚洲mv天堂mv在影片| 亚洲人成电影在线观看天堂色| 91夜夜未满十八勿入爽爽影院| 成人黄色生活片| 91豆花精品一区| 久久精品国产一区| 18一19gay欧美视频网站| 精品久久久999| 欧美一级高清免费| 亚洲欧美综合精品久久成人| 国产精品久久久久久久久久新婚| 伊人久久久久久久久久| 亚洲区在线播放| 日韩欧美精品在线观看| 2019国产精品自在线拍国产不卡| 日韩在线视频观看正片免费网站| 久久偷看各类女兵18女厕嘘嘘| 久久久久在线观看| 国产精品免费久久久| 国产精品美女www爽爽爽视频| 日韩美女激情视频| 精品久久久久久中文字幕| 欧美激情在线有限公司| 久久99视频免费| 日韩精品视频免费| 久久99国产精品久久久久久久久| 羞羞色国产精品| 欧美一级淫片丝袜脚交| 亚洲欧美日韩在线一区| 成人精品网站在线观看| 精品久久久久久亚洲国产300| 91国语精品自产拍在线观看性色| 日本精品久久久| 国产精品久久久久久久av电影| 国产精品一区二区3区| 久久久中精品2020中文| 欧美电影在线播放| 成人激情视频在线| 日韩中文视频免费在线观看| 国产精品精品久久久久久| 久热精品视频在线免费观看| 中文字幕成人精品久久不卡| 日韩经典第一页| 亚洲999一在线观看www| 日韩美女视频中文字幕| 欧美电影在线观看高清| 午夜免费在线观看精品视频| 亚洲电影免费观看高清完整版在线观看| 最近2019中文字幕在线高清| 国产精品91久久| 欧美精品在线视频观看| 亚洲97在线观看| 亚洲激情视频在线| 欧美激情在线视频二区| 亚洲欧美三级在线| 高清欧美性猛交xxxx黑人猛交| 亚洲高清久久久久久| 成人黄色午夜影院| 日韩国产在线看| 久久久噜噜噜久噜久久| 91精品久久久久| 亚洲最大av网站| 精品国产31久久久久久| 欧美激情网友自拍| 欧美激情在线观看视频| 久久久久久综合网天天| 国产欧美一区二区三区在线| 欧美有码在线观看视频| 国产精品一区二区3区| 国产精品 欧美在线| 日本精品免费一区二区三区| 免费91麻豆精品国产自产在线观看| 亚洲综合中文字幕在线观看| 91亚洲国产成人久久精品网站| 久久久久久97| 国产精品午夜一区二区欲梦| 亚洲欧美日韩国产中文| 久久久视频免费观看| 国产精品欧美激情| 蜜臀久久99精品久久久久久宅男| 亚洲人成网站免费播放| 亚洲3p在线观看| 日韩电影在线观看永久视频免费网站| 韩曰欧美视频免费观看| 国模精品视频一区二区| 91av免费观看91av精品在线| 亚洲免费伊人电影在线观看av| 欧美日韩视频在线| 久久香蕉频线观| 久久天天躁狠狠躁老女人| 一夜七次郎国产精品亚洲| 欧美资源在线观看| 曰本色欧美视频在线| 在线不卡国产精品| 久久视频国产精品免费视频在线| 操人视频在线观看欧美| 久久中文字幕在线视频| 成人久久久久久久| 亚洲人成网站999久久久综合| 日韩大胆人体377p| 不卡av日日日| 亚洲精品久久久久久久久久久久| 国产午夜精品久久久| 成人黄色免费片| 色老头一区二区三区| 亚洲社区在线观看| 欧美性猛交xxxx久久久| 国产婷婷97碰碰久久人人蜜臀| 久久色在线播放| 国产成人小视频在线观看| 中文字幕日韩免费视频| 亚洲欧美精品在线| 午夜精品一区二区三区在线视频| 亚洲摸下面视频| 日韩精品免费视频|