You are here:   ArielOrtiz.com > Software Design and Architecture > Lab 7: State Pattern

Lab 7: State Pattern

Objectives

During this lab session:

This activity helps the student 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

This lab is based on chapter 10 of [FREEMAN]. It can be developed individually or in pairs.

Make a new folder called chapter10. Place all the files you create in this folder.

  1. You have the following state diagram that allows matching block comments likes those used in programming languages like C:

    State Diagram

    Our implementation of the State pattern has the purpose of stripping off all the comments found in a given input text. All other characters (those outside the comments) should remain as part of the resulting string.

    Your job is to provide the implementation of the four states presented in the diagram. They must be called CommentStateA, CommentStateB, CommentStateC, and CommentStateD respectively. Each of these is a class that must implement the following interface:

    namespace Headfirst.State {
    
        public interface CommentState {
            string FoundSlash();
            string FoundStar();
            string FoundOther(char other);
            string FoundEnd();
        }
    }

    NOTE: The FoundEnd method allows a state to carry out a final action once the input text has been completely processed. For example, it can be used to raise an exception if the final state is not an accepting state.

    The Context for our State pattern implementation is provided as the following class (do not modify this code):

    namespace Headfirst.State {
        
        using System.Text;
        
        public class CommentStateMachine {
            
            public CommentState StateA { get; set; }
            public CommentState StateB { get; set; }
            public CommentState StateC { get; set; }
            public CommentState StateD { get; set; }                
            public CommentState State  { get; set; } 
            
            public CommentStateMachine() {
                StateA = new CommentStateA(this);
                StateB = new CommentStateB(this);
                StateC = new CommentStateC(this);
                StateD = new CommentStateD(this);                        
            }
            
            public string FoundSlash() {
                return State.FoundSlash();
            }
            
            public string FoundStar() {
                return State.FoundStar();
            }
            
            public string FoundOther(char other) {
                return State.FoundOther(other);
            }
            
            public string FoundEnd() {
                return State.FoundEnd();
            }
            
            public string StripComments(string input) {
                
                var result = new StringBuilder();
                
                State = StateA;
                foreach (char c in input) {
                    switch (c) {
                    case '/': 
                        result.Append(FoundSlash());
                        break;
                    case '*':
                        result.Append(FoundStar());
                        break;
                    default:
                        result.Append(FoundOther(c));
                        break;
                    }
                }
                
                result.Append(FoundEnd());
                
                return result.ToString();
            }
        }
    }
  2. Make sure the code that you write behaves exactly as expected by the following unit tests:

    namespace Headfirst.State {
        
        using System;    
        using NUnit.Framework;
        
        [TestFixture]
        public class TestCommentStateMachine {
            
            CommentStateMachine machine;
            
            [SetUp]
            public void Init() {
                machine = new CommentStateMachine();
            }
            
            [Test]
            public void TestNormal() {            
                Assert.AreEqual(
                    "** A small test! **", 
                    machine.StripComments("** A small test! **"));
                Assert.AreEqual(
                    "A small test!", 
                    machine.StripComments("A small /*little*/test!"));
                Assert.AreEqual(
                    "An other test!",                
                    machine.StripComments(
                        "An other /******** /// * * * * */t/*/***********\n"
                        + "test,\n*/"
                        + "/*this one\n"
                        + " *bigger than the last\n"
                        + " */e/**/s/****/t!/* The End */"));
                Assert.AreEqual(
                    "sha //// la //// la ////",                
                    machine.StripComments("sha //// la //// la ////"));                        
            }
            
            [Test]
            public void TestErrors() {
                try {
                    machine.StripComments("An /*/ **** incomplete comment");
                    Assert.Fail();
                } catch (InvalidOperationException e) {
                    Assert.AreEqual("*/ expected at end of input", 
                        e.Message); 
                }
                try {
                    machine.StripComments("An /*** incomplete comment ***");
                    Assert.Fail();
                } catch (InvalidOperationException e) {
                    Assert.AreEqual("*/ expected at end of input", 
                        e.Message); 
                }
            }
        }    
    }

Deliverables

To hand in your lab work, follow these instructions:

Evaluation

This activity will be evaluated using the following criteria:

100 The code works as requested.
60-90 The code works, but has some flaws.
20-50 The code doesn't work, but it seams that some amount of time was spent on it.
DA The program was plagiarized.
© 1996-2009 by Ariel Ortiz (ariel.ortiz@itesm.mx)
Made with Django | Licensed under Creative Commons | Valid XHTML | Valid CSS