zoukankan      html  css  js  c++  java
  • Ruby设计模式系列之模板模式

    写过java的同学一定对java中无处不在的设计模式印象深刻。相比较而已ruby在设计模式这一块就显得稍微有些拿不出手了。作为一门动态到极致的语言,设计模式在ruby中的应用可能不太传统,有些许的变种。但万变不离其宗,在这里我们就通过一些ruby代码所描述的例子来理解和学习一些基本的设计模式。

    注:本文中所有例子及代码均来自ruby design pattern一书,无任何本人原创,请勿对本人产生个人崇拜。

    从这里开始:模板模式。

    下面的代码实现了一个简单的模板,代码通俗易懂,应该很好理解。

    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('<html>')
                puts(' <head>')
                puts(" <title>#{@title}</title>")
                puts(' </head>')
                puts(' <body>')
            else
                raise "Unknown format: #{format}"
        end
            @text.each do |line|
            if format == :plain
                puts(line)
            else
                puts(" <p>#{line}</p>" )
            end
            end
            if format == :html
                puts(' </body>')
                puts('</html>')
            end
        end
    end
    

    上面的代码判断了format的类型,如果是html则打印html模板,如果是plain text则打印普通的文字模板。

    我们可以很容易的看出上述代码的一些缺陷:

    • 扩展性差。若再添加1个format的话代码改动量还是很大的;
    • 代码重复。print report的过程实际上都是一样的,每个format只是重复一下这个过程而已。

    于是我们就需要一个更好的设计模式来解决这个问题。模板模式开始粉墨登场。

    仔细的研究一下代码,我们发现下面的这些事情是一成不变的:

    • 打印header;
    • 打印title;
    • 打印报告的每一行;
    • 打印报告的结尾;

    我们可以把上面的”模板”性质的工作定义在一个模板类中,每个format都继承自这个模板基类,实现如下:

    #ruby1.9实现
    #report.rb文件,模板基类
    
    #encoding: utf-8
    class Report
      def initialize
            @title = '我的报告'
            @text = %w[第一行 第二行 第三行]
      end #initialize
    
      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.encode('gb2312')
            end
      end
    
      def output_start
            raise '不能直接调用该抽象方法'.encode('gb2312')
      end
    
      def output_head
            raise '不能直接调用该抽象方法'.encode('gb2312')
      end
    
      def output_body_start
            raise '不能直接调用该抽象方法'.encode('gb2312')
      end
    
      def output_line line
            raise '不能直接调用该抽象方法'.encode('gb2312')
      end
    
      def output_body_end
            raise '不能直接调用该抽象方法'.encode('gb2312')
      end
    
      def output_end
            raise '不能直接调用该抽象方法'.encode('gb2312')
      end
    
    end #class
    
    # formater_report.rb文件
    # 实现各种format
    
    require './report'
    class HTMLReport < Report
      def output_start
            puts '<html>'
      end
    
      def output_head
            puts '<head>'
            puts "    <title>#{@title.encode('gb2312')}</title>"
            puts '</head>'
      end
    
      def output_body_start
            puts '<body>'
      end
    
      def output_line line
            puts "    <p>#{line}</p>"
      end
    
      def output_body_end
            puts '</body>'
      end
    
      def output_end
            puts '</html>'
      end
    end #class
    
    class PlainTextReport < Report
        def output_start;end        
    
        def output_head
            puts "**** #{@title.encode 'gb2312'} ****"
            puts
        end
    
        def output_body_start; end
    
        def output_line line
            puts line
        end
    
        def output_body_end; end
        def output_end; end
    end
    
    HTMLReport.new.output_report
    PlainTextReport.new.output_report
    

    在Report基类中,由于ruby没有抽象方法的概念,所以我们使用raise exception的方式来模拟抽象方法被调用时所出现的异常。 另外因为ruby1.9中编码的问题,我们调用encode 'gb2312'方法来将字符串转码成gb2312编码,这样在控制台中能正常的显示中文,不会出现乱码。

  • 相关阅读:
    一文带你了解接口测试价值与体系
    干货|app自动化测试之设备交互API详解
    干货|app自动化测试之Appium问题分析及定位
    干货| app自动化测试之Andriod微信小程序的自动化测试
    如果你也有这些职场困惑,周六一直线上答疑
    文末福利 | 团队管理第一步之高效招聘
    精准化测试原理简介与实践探索
    文末有福利 | 面试时如何命中面试官的考题?
    Visual studio prebuild/postbuild 设置条件不生效
    使用腾讯地图api获取定位信息经纬度(需要浏览器支持,且需要https)
  • 原文地址:https://www.cnblogs.com/nbkhic/p/2105796.html
Copyright © 2011-2022 走看看