a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁(yè) > 編程 > Ruby > 正文

實(shí)例講解Ruby使用設(shè)計(jì)模式中的裝飾器模式的方法

2020-10-29 19:36:19
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

概述
       若你從事過(guò)面向?qū)ο箝_(kāi)發(fā),實(shí)現(xiàn)給一個(gè)類或?qū)ο笤黾有袨椋褂美^承機(jī)制,這是所有面向?qū)ο笳Z(yǔ)言的一  個(gè)基本特性。如果已經(jīng)存在的一個(gè)類缺少某些方法,或者須要給方法添加更多的功能(魅力),你也許會(huì)僅僅繼承這個(gè)類來(lái)產(chǎn)生一個(gè)新類―這建立在額外的代碼上。
      通過(guò)繼承一個(gè)現(xiàn)有類可以使得子類在擁有自身方法的同時(shí)還擁有父類的方法。但是這種方法是靜態(tài)的,用戶不能控制增加行為的方式和時(shí)機(jī)。如果  你希望改變一個(gè)已經(jīng)初始化的對(duì)象的行為,你怎么辦?或者,你希望繼承許多類的行為,改怎么辦?前一個(gè),只能在于運(yùn)行時(shí)完成,后者顯然時(shí)可能的,但是可能會(huì)導(dǎo)致產(chǎn)生大量的不同的類―可怕的事情。
問(wèn)題
      你如何組織你的代碼使其可以容易的添加基本的或者一些很少用到的 特性,而不是直接不額外的代碼寫(xiě)在你的類的內(nèi)部?

解決方案

  •        動(dòng)態(tài)地給一個(gè)對(duì)象添加一些額外的職責(zé)或者行為。就增加功能來(lái)說(shuō), Decorator模式相比生成子類更為靈活。
  •        提供了改變子類的靈活方案。裝飾器模式在不必改變?cè)愇募褪褂美^承的情況下,動(dòng)態(tài)的擴(kuò)展一個(gè)對(duì)象的功能。它是通過(guò)創(chuàng)建一個(gè)包裝對(duì)象,也就是裝飾來(lái)包裹真實(shí)的對(duì)象。
  •        當(dāng)用于一組子類時(shí),裝飾器模式更加有用。如果你擁有一族子類(從一個(gè)父類派生而來(lái)),你需要在與子類獨(dú)立使用情況下添加額外的特性,你可以使用裝飾器模式,以避免代碼重復(fù)和具體子類數(shù)量的增加。

 適用性

       以下情況使用Decorator模式

  •       在不影響其他對(duì)象的情況下,以動(dòng)態(tài)、透明的方式給單個(gè)對(duì)象添加職責(zé)。
  •       處理那些可以撤消的職責(zé)。
  •       當(dāng)不能采用生成子類的方法進(jìn)行擴(kuò)充時(shí)。一種情況是,可能有大量獨(dú)立的擴(kuò)展,

      為支持每一種組合將產(chǎn)生大量的子類,使得子類數(shù)目呈爆炸性增長(zhǎng)。

      另一種情況可能是因?yàn)轭惗x被隱藏,或類定義不能用于生成子類。
 
實(shí)例

class SimpleWriter  def initialize(path)   @file = File.open(path,"w")  end    def write_line(line)   @file.print(line)   @file.print("/n")  end    #字符數(shù)  def pos   @file.pos  end    #它將會(huì)將文件指針指向文件的開(kāi)頭  def rewind   @file.rewind  end    def close   @file.colse  end end   sw = SimpleWriter.new("test.txt") sw.write_line("你好") puts sw.pos puts sw.rewind   #基類 class WriterDecorator  def initialize(real_writer)   @real_writer = real_writer  end    def write_line   @real_writer.write_line  end    def pos   @real_writer.pos  end    def rewind   @real_writer.rewind  end    def close   @real_writer.close  end end   class NumberingWriter < WriterDecorator  attr :line_number  def initialize(real_writer)   super(real_writer)   @line_number = 1  end    #實(shí)際調(diào)用的是WriterDecorator的write_line方法,只是在寫(xiě)入的內(nèi)容前加上了編號(hào)(裝飾)  #所以說(shuō)NumberingWriter對(duì)WriterDecorator的接口wirte_line進(jìn)行了裝飾  #  def write_line(line)   @real_writer.write_line("#{@line_number}:#{line}")   @line_number += 1  end end   sw = SimpleWriter.new("numbering_write.txt") nw = NumberingWriter.new(sw) nw.write_line("hello,world") nw.write_line("hello,ruby") puts nw.line_number   class CheckSummingWriter < WriterDecorator  attr_reader :check_num    def initialize(real_writer)   super(real_writer)   @check_num = 0  end    def write_line(line)   line.each_byte{|byte| @check_num += byte % 256}   @real_writer.write_line(line)  end end   sw = SimpleWriter.new("check_num_writer.txt") csw = CheckSummingWriter.new(sw) csw.write_line("hello,world") puts csw.check_num   class TimeStampingWriter < WriterDecorator    def initialize(real_writer)   super(real_writer)  end    def write_line(line)   @real_writer.write_line("#{Time.now}: #{line}")  end   end   #倒著看 #5. 實(shí)際調(diào)用的是SimpleWriter得write_line方法,將內(nèi)容寫(xiě)入文件 sw = SimpleWriter.new("mix.txt") #4. 實(shí)際調(diào)用的是NumberingWriter得write_line方法,對(duì)在輸入的數(shù)據(jù)前加上了編號(hào) #  然后傳給@real_writer,此時(shí)的@real_witer為sw nw = NumberingWriter.new(sw) #3. 實(shí)際調(diào)用的是TimeStampingWriter得write_line方法,對(duì)在輸入的數(shù)據(jù)前加上了時(shí)間戳 #  然后傳給@real_writer,此時(shí)的@real_witer為nw tsw = TimeStampingWriter.new(nw) #2. 實(shí)際調(diào)用的是CheckSummingWriter得write_line方法,對(duì)輸入的數(shù)據(jù)進(jìn)行了字節(jié)數(shù)的統(tǒng)計(jì) #  然后傳給@real_writer,此時(shí)的@real_witer為tsw csw = CheckSummingWriter.new(tsw) #1. csw調(diào)用write_line csw.write_line("hello,world") puts csw.check_num 

兩種ruby風(fēng)格的裝飾模式應(yīng)用
 
(1)使用extend混入模塊

class SimpleWriter  def initialize(path)   @file = File.open(path,"w")  end   def write_line(line)   @file.print(line)   @file.print("/n")  end   #字符數(shù)  def pos   @file.pos  end   #它將會(huì)將文件指針指向文件的開(kāi)頭  def rewind   @file.rewind  end   def close   @file.colse  end end  #使用extend方法動(dòng)態(tài)的混入模塊,來(lái)進(jìn)行裝飾  module TimeStampingWriter  def write_line(line)   super("#{Time.now}:#{line}")  end end  module NumberingWriter  attr_reader :line_number  def write_line(line)   @line_number = 1 unless @line_number   super("#{@line_number}:#{line}")   @line_number += 1  end end 

 
最后被加入的模塊,先被調(diào)用,然后通過(guò)super來(lái)調(diào)用父類的write_line方法。 
例子中先在文本的前面加上時(shí)間戳,在加入編號(hào),最后寫(xiě)入文件  

sw = SimpleWriter.new("out3.txt") sw.extend(NumberingWriter) sw.extend(TimeStampingWriter) sw.write_line("hello,ruby") 

 
(2)使用alias關(guān)鍵字

class SimpleWriter  def initialize(path)   @file = File.open(path,"w")  end   def write_line(line)   @file.print(line)   @file.print("/n")  end   #字符數(shù)  def pos   @file.pos  end   #它將會(huì)將文件指針指向文件的開(kāi)頭  def rewind   @file.rewind  end   def close   @file.colse  end end   ruby實(shí)現(xiàn)裝飾模式的另一種動(dòng)態(tài)方法 : 修改對(duì)象的實(shí)例方法, 所以在out1.txt文件中會(huì)加入時(shí)間戳,而不影響對(duì)象sw2,out2.txt中不會(huì)加入時(shí)間戳 。 sw1 = SimpleWriter.new("out1.txt") class << sw1  alias old_write_line write_line  def write_line(line)   old_write_line("#{Time.now}:#{line}")  end end sw1.write_line("hello,world") sw2 = SimpleWriter.new("out2.txt") sw2.write_line("hello,world") 

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 欧美在线播放一区二区 | 欧美操大逼| 中文字幕精品一区久久久久 | 蜜臀av性久久久久蜜臀aⅴ流畅 | 欧美日韩1区2区3区 www.日韩精品 | 国产成人精品免费视频 | 国产精品久久久免费看 | 欧美精品激情 | 久久黄网站 | 亚洲成人免费观看 | 人成亚洲 | 免费在线中文字幕 | 欧美一级在线免费观看 | 99成人| 日韩视频一区二区三区在线观看 | 伊人激情av一区二区三区 | 日本特黄 | 欧美精品一区二区三区在线四季 | 精品欧美一区二区三区在线观看 | 娇小12一13sexvideo | 黄色免费网站视频 | 亚洲国产精久久久久久久 | 精品国产一区二区三区av片 | 情五月 | 蜜桃视频麻豆女神沈芯语免费观看 | 岛国视频 | 高清色 | 国产精品久久久久久久久久东京 | 九九热免费精品视频 | 欧美一区二区三区四区不卡 | 精品国产乱码久久久久久1区2区 | 国产成人精品视频在线观看 | 伊人天堂网 | 欧美成人一 | 欧美一区二区三区免费观看 | 国产成人免费视频 | 一级视频在线观看 | 一区二区三区四区在线 | 日韩精品亚洲一区 | 男人天堂视频网 | 99re免费视频精品全部 |