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编码,这样在控制台中能正常的显示中文,不会出现乱码。

  • 相关阅读:
    最近的一些想法Booch和高斯
    校内网自动分享视频flash xss蠕虫分析
    使用Axis2开发Web Service简单演示实例
    最近的一些想法UML和算法
    JavaScript2.0 :抢先尝鲜
    有一种感觉,百度应该开发浏览器
    mongodb修改器
    mongdb时间类型
    mongodb文档替换
    mongodb 分片集群+副本集搭建
  • 原文地址:https://www.cnblogs.com/nbkhic/p/2105796.html
Copyright © 2011-2022 走看看