栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Ruby开发

Alex学Ruby[ Ruby Design Pattern

Ruby开发 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Alex学Ruby[ Ruby Design Pattern


突然对Ruby实现的设计模式比较感兴趣,边学习边记录一下吧。 Template method模式是最简单的一种设计模式了,下文的解释引自追mm与设计模式一文( 没想到写这文章的哥们是个YD的青年啊,不过也有助于帮助理解设计模式 ):

Template method——看过《如何说服女生上床》这部经典文章吗?女生从认识到上床的不变的步骤分为巧遇、打破僵局、展开追求、接吻、前戏、动手、爱抚、进去八大步骤(Template method),但每个步骤针对不同的情况,都有不一样的做法,这就要看你随机应变啦(具体实现);

模板方法模式:模板方法模式准备一个抽象类,将部分逻辑以具体方法以及具体构造子的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。先制定一个顶级逻辑框架,而将逻辑的细节留给具体的子类去实现。

以一个例子来说, 写一个输出一个不同格式的report generater。可以输出html格式,也可以输出纯文本的内容。

这个例子是hard-coded输出html格式的report类,但是无法处理纯文本格式。

class Report

  def initialize

    @title = 'Monthly Report'

    @text =  [ 'Things are going', 'really, really well.' ]

  end

  def output_report

    puts('')

    puts('  ')

    puts("    #{@title}")

    puts('  ')

    puts('  ')

    @text.each do |line|

       puts("    

#{line}

" )

    end

    puts('  ')

    puts('')

  end

end

如果你要处理纯文本,那么只能重新写一个类:

class Report

  def initialize

    @title = 'Monthly Report'

    @text =  ['Things are going', 'really, really well.']

  end

  def output_report(format)

    if format == :plain

      puts("*** #{@title} ***")

    elsif format == :html

      puts('')

      puts('  ')

      puts("    #{@title}")

      puts('  ')

      puts('  ')

    else

      raise "Unknown format: #{format}"

    end

    @text.each do |line|

      if format == :plain

        puts(line)

      else

        puts("    

#{line}

" )

      end

    end

    if format == :html

      puts('  ')

      puts('')

    end

  end

end

上面的代码是可以工作的,但是如果将来又有需要让你处理其他格式呢,再重写一遍啊?这个时候template method就起作用了。我们可以把公共的部分抽象出来,也就是说先制定一个顶级逻辑框架,而将逻辑的细节留给具体的子类去实现。Ruby本身并没有抽象类,那么我们可以像下面方式一样去模拟:

class Report

  def initialize

    @title = 'Monthly Report'

    @text =  ['Things are going', 'really, really well.']

  end

  def output_report

    output_start

    output_head

    output_body_start

    output_body

    output_body_end

    output_end

  end

  def output_body

    @text.each do |line|

      output_line(line)

    end

  end

  def output_start

    raise 'Called abstract method: output_start'

  end

  def output_head

    raise 'Called abstract method: output_head'

  end

  def output_body_start

    raise 'Called abstract method: output_body_start'

  end

  def output_line(line)

    raise 'Called abstract method: output_line'

  end

  def output_body_end

    raise 'Called abstract method: output_body_end'

  end

  def output_end

    raise 'Called abstract method: output_end'

  end

end

 那么我们可以实现处理html的子类了:

class HTMLReport < Report

    def output_start

        puts('')

    end

    def output_head

       puts('  ')

       puts("    #{@title}")

       puts('  ')

   end

   def output_body_start

      puts('')

   end

   def output_line(line)

      puts("  

#{line}

")

   end

   def output_body_end

      puts('')

   end

   def output_end

       puts('')

   end

end

同样,处理文本的子类:

class PlainTextReport < Report

    def output_start

    end

   

    def output_head

        puts("**** #{@title} ****")

        puts

     end

     def output_body_start

     end

     def output_line(line)

        puts(line)

     end

     def output_body_end

    end

    def output_end

    end

end

 

看看结果:

 

report = HTMLReport.new

report.output_report

#=>

  Monthly Report

Things are going

really, really well.

report = PlainTextReport.new

report.output_report

#=>

** Monthly Report ****

Things are going

really, really well.

 

 

©著作权归作者所有:来自51CTO博客作者blackanger的原创作品,如需转载,请注明出处,否则将追究法律责任


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/226279.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号