You are here:   ArielOrtiz.com > Software Design and Architecture > Lab 5: Adapter Pattern and Refactoring

Lab 5: Adapter Pattern and Refactoring

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

The lab activities can be developed individually or in pairs.

The lab report must be developed individually.

  1. Create a folder called adapter_refactoring. Inside this folder, create five files called: simple_queue.rb, queue_adapter.rb, test_adapter.rb, student.rb, and test_student.rb.

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

    # Lab 5: Adapter Pattern and Refactoring
    # Date: 22-Feb-2011
    # Authors:
    # 456654  Anthony Stark 
    # 1160611 Thursday Rubinstein
  2. The content of the file simple_queue.rb is as follows:

    # File: simple_queue.rb
    
    # IMPORTANT: Do not modify the following class in any way!
    
    class SimpleQueue
      
      def initialize
        @info =[]
      end
      
      def insert(x)
        @info.push(x)
        self
      end
      
      def remove
        if empty?
          raise "Can't remove if queue is empty"
        else
          @info.shift
        end
      end
      
      def empty?
        @info.empty?
      end
      
      def size
        @info.size
      end
      
      def inspect
        @info.inspect
      end
    end
    

    The SimpleQueue class contains a First-In First-Out (FIFO) data structure that implements the following methods:

    Method Signature Description
    insert(x) Inserts x at the back of this queue. Returns this queue.
    remove Removes and returns the element at the front of this queue. Raises an exception if this queue happens to be empty.
    empty? Returns true if this queue is empty, otherwise returns false.
    size Returns the number of elements currently stored in this queue.

    Write an adapter class called QueueAdapter (place it in the file called queue_adapter.rb) that makes a SimpleQueue instance (as implemented above) behave like a Last-In First-Out (LIFO) stack with the following interface:

    Method Signature Description
    initialize(q) Initializes a new stack, using q as the adaptee.
    push(x) Inserts x at the top of this stack. Returns this stack.
    pop Returns nil if this stack is empty, otherwise removes and returns its top element.
    peek Returns nil if this stack is empty, otherwise returns its top element without removing it.
    empty? Returns true if this stack is empty, otherwise returns false.
    size Returns the number of elements currently stored in this stack.
  3. The following unit test verifies the correct behavior of the QueueAdapter class. Place the test class in the test_adapter.rb source file.
    # File: test_adapter.rb 
    
    require 'test/unit'
    require './simple_queue'
    require './queue_adapter'
    
    class QueueAdapterTest < Test::Unit::TestCase  
    
      def test_queue_adapter    
        q = SimpleQueue.new
        qa = QueueAdapter.new(q)
        assert q.empty?
        assert qa.empty?
        assert_nil qa.pop 
        qa.push("Foo")
        assert_equal "Foo", qa.peek
        assert !q.empty?
        assert !qa.empty?
        qa.push("Bar")
        assert_equal "Bar", qa.peek
        qa.push("Baz").push("Quux")
        assert_equal 4, q.size
        assert_equal 4, qa.size
        assert_equal "Quux", qa.peek
        assert_equal "Quux", qa.pop
        assert_equal "Baz", qa.peek
        assert_equal "Baz", qa.pop
        assert_equal "Bar", qa.peek
        assert_equal "Bar", qa.pop
        assert_equal "Foo", qa.peek
        qa.push("Goo")
        assert_equal "Goo", qa.peek
        assert_equal "Goo", qa.pop
        assert_equal "Foo", qa.peek
        assert_equal 1, qa.size
        assert_equal "Foo", qa.pop
        assert_nil qa.peek
        assert_nil qa.pop
        assert q.empty?
        assert qa.empty? 
        assert_equal 0, q.size
        assert_equal 0, qa.size
      end
      
    end
  4. Place the following code in the file called student.rb:

    # File: student.rb
    
    class Student
    
      attr_reader :name, :id
      attr_accessor :anual_income, :grade1, :grade2, :grade3  
            
      def initialize(name, id)
        @name = name 
        @id = id
        @anual_income = 0
        @grade1 = 0
        @grade2 = 0
        @grade3 = 0        
      end
      
      def display
        # Display Personal Information
        puts "Name: #{@name} ID: #{@id}"
        puts "Anual income: #{@anual_income}"
        grade_average = (@grade1 + @grade2 + @grade3) / 3.0
        puts "Grade average: #{grade_average}"
            
        # Display Disclaimer
        puts 'The contents of this class must not be considered an offer,'
        puts 'proposal, understanding or agreement unless it is confirmed'
        puts 'in a document signed by at least five blood-sucking lawyers.'
      end
      
      def scholarship_worthy
        # A student is worthy of a scholarship if he/she has good grades and
        # is poor.
        ((@grade1 + @grade2 + @grade3) / 3.0 >= 85) and (@anual_income < 15_000)
      end
      
    end
    

    In the test_student.rb file write a complete unit test class in order to thoroughly verify the current behavior of Student instances. Make sure to individually test the display and scholarship_worthy methods.

  5. Modify the Student class so that you carry out the following refactorings:

    • Extract method
    • Replace temp with query
    • Introduce explaining variable

    Any new methods you introduce should be defined as private. Run your unit tests again to make sure that the refactorings didn't modify the external behavior.

Deliverables

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

Due date is Monday, February 28.

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.
© 1996-2011 by Ariel Ortiz (ariel.ortiz@itesm.mx)
Made with Django | Licensed under Creative Commons | Valid XHTML | Valid CSS