You are here:   ArielOrtiz.info > Software Design and Architecture > Lab 2: Template Method Pattern

Lab 2: Template Method Pattern

Objectives

During this lab session:

This activity helps students develop the following skills, values and attitudes: ability to analyze and synthesize, capacity for identifying and solving problems, and efficient use of computer systems.

Activity Description

IMPORTANT NOTE: The lab activities can be developed individually or in pairs. The lab report must be developed individually.

  1. Create a folder called templatemethod. Inside this folder, create three files called: table_generator.rb, tc_table_generator.rb, and student.rb.

    All three Ruby source files must start with a comment containing the lab’s title, date, and the authors’ personal information. For example:

    # Lab 2: Template Method Pattern
    # Date: 28-Aug-2013
    # Authors:
    # 456654  Thursday Rubinstein 
    # 1160611 Anthony Stark
    

    The initial content of the table_generator.rb and student.rb files should be as follows. Study them carefully so you understand how they work.

    # File name: table_generator.rb
    
    class TableGenerator
    
      def initialize(header, data)
        @header = header
        @data = data
      end
    
      def generate
        generate_header_row + (@data.map {|x| generate_row(x)}).join
      end
    
      def generate_header_row
        (@header.map {|x| generate_header_item(x)}).join
      end
    
      def generate_item(item)
        item
      end
    
      def generate_row(row)
        (row.map {|x| generate_item(x)}).join
      end
    
      def generate_header_item(item)
        item
      end
      
    end
    
    class CSVTableGenerator < TableGenerator
    
      def generate_row(row)
        "#{(row.map {|x| generate_item(x)}).join(',')}\n"
      end
    
      def generate_header_row
        generate_row(@header)
      end
    
    end
    
    # File name: student.rb
    
    class Student
    
      include Enumerable
      # Note: This class does not support the max, min, or sort methods.
    
      def initialize(id, name, grades)
        @id = id
        @name = name
        @grades = grades
      end
    
      def inspect
        "Student(#{@id}, #{@name.inspect})"
      end
    
      def grade_average
        @grades.inject(:+)/@grades.size
      end
    
      def each &block
        yield @id
        yield @name
        @grades.each(&block)
        yield grade_average
      end
    
    end
    

    The TableGenerator and its subclass CSVTableGenerator (CSV stands for Comma-separated values) are an implementation of the Template Method pattern. Given some tabular data, they allow generating tables in different kinds of text formats. The Student class will be used when testing.

  2. In the table_generator.rb source file, write the following classes: HTMLTableGenerator and AsciiDocTableGenerator. These classes must extend TableGenerator and override the appropriate methods so that the following unit tests work as expected. Place the test class in the source file called tc_table_generator.rb.
    # File name: tc_table_generator.rb
    
    require 'test/unit'
    require 'table_generator'
    require 'student'
    
    class TableGeneratorTest < Test::Unit::TestCase
    
      def setup
        @headerEmpty = []
        @dataEmpty = []
    
        @headerNums = %w{Snap Crackle Pop}
        @dataNums = [[10, 20, 30],
                     [12, 64, 13],
                     [34, 11, 29],
                     [99, 15, 34]]
    
        @headerStudents = %w{id name grade1 grade2 grade3 average}
        @dataStudents = [Student.new(123, "Selma Bouvier", [71, 84, 89]),
                         Student.new(241, "Carl Carlson", [78, 85, 90]),
                         Student.new(299, "Todd Flanders", [67, 71, 77]),
                         Student.new(311, "Barney Gumble", [24, 18, 35]),
                         Student.new(427, "Edna Krabappel", [92, 95, 99]),
                         Student.new(666, "Damian Thorn", [66, 66, 66]),
                         Student.new(718, "Manjula Nahasapeemapetilon", [53, 72, 88])]
      end
    
      def test_CSVTableGenerator
        assert_equal \
          "Snap,Crackle,Pop\n" +
          "10,20,30\n" +
          "12,64,13\n" +
          "34,11,29\n" +
          "99,15,34\n",
          CSVTableGenerator.new(@headerNums, @dataNums).generate
        assert_equal \
          "id,name,grade1,grade2,grade3,average\n" +
          "123,Selma Bouvier,71,84,89,81\n" +
          "241,Carl Carlson,78,85,90,84\n" +
          "299,Todd Flanders,67,71,77,71\n" +
          "311,Barney Gumble,24,18,35,25\n" +
          "427,Edna Krabappel,92,95,99,95\n" +
          "666,Damian Thorn,66,66,66,66\n" +
          "718,Manjula Nahasapeemapetilon,53,72,88,71\n",
          CSVTableGenerator.new(@headerStudents, @dataStudents).generate
      end
    
      def test_HTMLTableGenerator
        assert_equal \
          "<table>\n" +
          "<tr><th>Snap</th><th>Crackle</th><th>Pop</th></tr>\n" +
          "<tr><td>10</td><td>20</td><td>30</td></tr>\n" +
          "<tr><td>12</td><td>64</td><td>13</td></tr>\n" +
          "<tr><td>34</td><td>11</td><td>29</td></tr>\n" +
          "<tr><td>99</td><td>15</td><td>34</td></tr>\n" +
          "</table>\n",
          HTMLTableGenerator.new(@headerNums, @dataNums).generate
        assert_equal \
          "<table>\n" +
          "<tr><th>id</th><th>name</th><th>grade1</th>" +
          "<th>grade2</th><th>grade3</th><th>average</th></tr>\n" +
          "<tr><td>123</td><td>Selma Bouvier</td><td>71</td>" +
          "<td>84</td><td>89</td><td>81</td></tr>\n" +
          "<tr><td>241</td><td>Carl Carlson</td><td>78</td>" +
          "<td>85</td><td>90</td><td>84</td></tr>\n" +
          "<tr><td>299</td><td>Todd Flanders</td><td>67</td>" +
          "<td>71</td><td>77</td><td>71</td></tr>\n" +
          "<tr><td>311</td><td>Barney Gumble</td><td>24</td>" +
          "<td>18</td><td>35</td><td>25</td></tr>\n" +
          "<tr><td>427</td><td>Edna Krabappel</td><td>92</td>" +
          "<td>95</td><td>99</td><td>95</td></tr>\n" +
          "<tr><td>666</td><td>Damian Thorn</td><td>66</td>" +
          "<td>66</td><td>66</td><td>66</td></tr>\n" +
          "<tr><td>718</td><td>Manjula Nahasapeemapetilon</td><td>53</td>" +
          "<td>72</td><td>88</td><td>71</td></tr>\n" +
          "</table>\n",
          HTMLTableGenerator.new(@headerStudents, @dataStudents).generate
      end
    
      def test_AsciiDocTableGenerator
        assert_equal \
          "[options=\"header\"]\n" +
          "|==========\n" +
          "|Snap|Crackle|Pop\n" +
          "|10|20|30\n" +
          "|12|64|13\n" +
          "|34|11|29\n" +
          "|99|15|34\n" +
          "|==========\n",
          AsciiDocTableGenerator.new(@headerNums, @dataNums).generate
        assert_equal \
          "[options=\"header\"]\n" +
          "|==========\n" +
          "|id|name|grade1|grade2|grade3|average\n" +
          "|123|Selma Bouvier|71|84|89|81\n" +
          "|241|Carl Carlson|78|85|90|84\n" +
          "|299|Todd Flanders|67|71|77|71\n" +
          "|311|Barney Gumble|24|18|35|25\n" +
          "|427|Edna Krabappel|92|95|99|95\n" +
          "|666|Damian Thorn|66|66|66|66\n" +
          "|718|Manjula Nahasapeemapetilon|53|72|88|71\n" +
          "|==========\n",
          AsciiDocTableGenerator.new(@headerStudents, @dataStudents).generate
      end
      
    end
    

Deliverables

To hand in your individual lab work, follow these instructions.

Due date is Tuesday, September 3.

Evaluation

This activity will be evaluated using the following criteria:

50% Implementation of functional requirements.
50% Lab report.
DA The program and/or report was plagiarized.