SSE658_Bridges_Gluvna_Project+3

=Introduction= This project will demonstrate four design patterns covered in "Head First Design Patterns" from Chapter 8 through the end of the book. Visual Studios 2008 C# Microsoft .Net 3.5 Framework will be used for all code examples in this project. =The Patterns= In this section you will find the patterns (Iterator, Proxy, State and Template). Each pattern section will first state the benefits of the pattern and then alternative designs and there problems. After alternative designs and the problems this paper will then introduce problems solved by the current sections pattern and then go over a code example of the sections pattern. We decided to take the first four patterns in the book skipping the composite pattern because it was so tightly coupled to the iterated pattern. MVC or Model-View-Controller is a great pattern but we intentionally did not use this pattern because it is so widely available and we wanted to create a document that the information was not so widely covered everywhere.

Iterator Pattern
As per the Head First book the Iterator pattern provides a way to access the elements of an aggregate object sequentially without exposing the underlying representation. That definition is online with about 99% of other sites as well.

Benefits of the Iterator Pattern
The main benefit of the Iterator pattern is that if you have several objects (let’s say an array, hash table and a list) that need to be iterated through and all objects need to contain a search, sort and next method then you will not have to have all three methods for each structure. If you use the Iterator pattern you can have one implementation for each of the several objects, in this case the array, the hash table and the list. Nine methods just went down to three.

Alternative Design
Alternative designs one is to program an interface to each collection, this means for each collection type you would have an interface (one for arrays, one for hash tables, one for list). Alternative design two is to develop an interface for all the collections and to pass out some generic collection. Alternative design three would be to use generic list for the .Net framework. Mind you that these generic list are actually [typed] generic list. You could use these lists for a good portion of what you needed and possibly extend the object adding other required items.

Alternative Design Problems
Alternative design one problems are that you have three times the number of objects methods to develop and maintain. Alternative design two problems are that you will cause you to lose some flexibility in the types of object you upper layers will be exposed to. Alternative design problem three will have little or no problems if designed well. The biggest problem we foresee is that it may be confusing for junior developers to catch on to what you are trying to do right away.

Problems Solved by Iterator Pattern
The main problems solved by the Iterator pattern is that you give a common interface to a list of collections which will in turn make your collection of objects easy to enumerate through without having to know each collection and its inner workings.

Iterator Pattern Code Example
The following is a very simple code example we created that is used to iterate through a group of reports. code format="csharp" using System; using System.Collections;

namespace IteratorPattern {   public class IteratorPattern {       // program entry point public static void Main(string[] args) {           // instance of aggregate class concreteAggregate Aggregate.ConcreteAggregate aggregate = new Aggregate.ConcreteAggregate; aggregate[0] = "Report 1"; // index 0 aggregate[1] = "Report 2"; // index 1 aggregate[2] = "Report 3"; // index 2 aggregate[3] = "Report 4"; // index 3

// instance of class ConcreteIterator passing in instance of aggregate class Iterator.ConcreteIterator iterator = new Iterator.ConcreteIterator(aggregate); object item = iterator.first; // create and assign object item with 1st while (item != null) // checks whil item is not null {               Console.WriteLine(item); // write the item object to the console window item = iterator.next; // moves to next object }

Console.ReadLine; // waits to read the next line }   }

// The aggregate Aggregate class public abstract class Aggregate {       // abstract interface of createIterator method public abstract Iterator createIterator;

// internal ConcreteAggregate that inherits from Aggregate internal class ConcreteAggregate : Aggregate {           // an array list to hold all items private ArrayList _items = new ArrayList;

// createIterator method that creates a new concerete iterator public override Iterator createIterator {               return new Iterator.ConcreteIterator(this); }

// returns a count of the items in the items collection internal int count {               get { return _items.Count; } }

// gets the object in the item specified index internal object this[int index] {               get { return _items[index]; } set { _items.Insert(index, value); } }       }    }

// The Iterator abstract class public abstract class Iterator {       // abstract interface of first method public abstract object first; // abstract interface of next method public abstract object next; // abstract interface of isComplete method public abstract bool isComplete; // abstract interface of currentItem method public abstract object currentItem;

// internal ConcreteIterator that inherits from Iterator internal class ConcreteIterator : Iterator {           // property that holds aggregate object private Aggregate.ConcreteAggregate _aggregate; private Aggregate.ConcreteAggregate aggregate {               get { return _aggregate; } set { _aggregate = value; } }

// property that holds current interger index private int _current = 0; private int current {               get { return _current; } set { _current = value; } }

// sets aggregate that is passed in to currents objects aggregate public ConcreteIterator(Aggregate.ConcreteAggregate aggregate) {               this.aggregate = aggregate; }

// returns aggregate at the index 0 public override object first {               return aggregate[0]; }

// returns aggregate next index object public override object next {               object ret = null; if (current < aggregate.count - 1) {                   ret = aggregate[++current]; }

return ret; }

// returns aggregate current index object public override object currentItem {               return aggregate[current]; }

// checks if last index object public override bool isComplete {               return current >= aggregate.count; }       }    } } code **Iterator Pattern Code Results** **Proxy Pattern** According to the Head First book, the proxy pattern provides a surrogate or placeholder for another object to control access to it. Since this is how the Head First book states the pattern that is the example of the proxy pattern that we wrote. We like to go along the lines of Wiki’s thinking about the proxy and the proxy pattern, “A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate.”

Benefits of the Proxy Pattern
Our favorite benefit of the proxy pattern is it helps in that housekeeping tasks can be done when an object is accessed. Another benefit is that the proxy pattern provides a sort of location transparency for distributed systems. This transparency is provided through the use of remote proxies. Finally, the proxy pattern provides optimization through the use of virtual proxies.

Alternative Design
An alternative design to the proxy pattern is to load all possible objects in memory on application load instead of loading them as needed. You could spin off a thread to load the objects while a user logs in or when a website is loaded the first time. Another alternative design to the proxy pattern may be is to just simply wait for the taxing operations to take place and find a way to distract the users from them by loading other objects or maybe putting small games in the apps.

Alternative Design Problems
Loading objects in memory will take large amount of memory and will hamper performance by utilizing all you memory or even reduce the flexibility of loading objects on the fly when new objects are added to your application. It may also be impossible to load all large files at once in memory.

Problems Solved By the Proxy Pattern
The Proxy pattern can be used when a developer needs a more complex reference to an object than just a pointer or when a developer need to provide a solution to avoid creating expensive objects. An expensive object may be a large raster image or even multiple raster images that may need to be loaded at once.

Proxy Pattern Code Example
The following is a simple code example that we created for reading a security badge that will allow you to gain access to a building or a room. A proxy is used to protect or realSecurityReader object here. code format="csharp" using System;

namespace ProxyPattern {   public class ProxyPattern {       // program entry point public static void Main(string[] args) {           // creates and stores an instance of ProxySecurityReader ProxySecurityReader proxySecurityReader = new ProxySecurityReader; // calls validateSecurityBadge and passes in guid from badge // this is a random guid for this instance but would be the // guid or ID from the security badge proxySecurityReader.validateSecurityBadge(Guid.NewGuid);

// waits for user input Console.ReadKey; }   }

// internal abstract class SecurityReader internal abstract class SecurityReader {       // abstract interface to validateSecurityBadge method public abstract void validateSecurityBadge(Guid badgeID); }

// internal class RealSecurityReader that in inherits from SecurityReader internal class RealSecurityReader : SecurityReader {       // this method overrides ProxySecurityReader's method (the proxy method) public override void validateSecurityBadge(Guid badgeID) {           // writes to console the badges guid Console.WriteLine("Validating badgeID GUID: {0}", badgeID); }   }

// internal class ProxySecurityReader that in inherits from SecurityReader // this is our proxy internal class ProxySecurityReader : SecurityReader {       // property that gets and sets RealSecurityReader.realSecurityReader private RealSecurityReader _realSecurityReader; private RealSecurityReader realSecurityReader {           get { return _realSecurityReader; } set { _realSecurityReader = value; } }

// this method overrides ProxySecurityReader's method public override void validateSecurityBadge(Guid badgeID) {           // lazy initialization of RealSecurityReader if (realSecurityReader == null) {               realSecurityReader = new RealSecurityReader; }

// calls the RealSecurityReader.validateSecurityBadge method realSecurityReader.validateSecurityBadge(badgeID); }   } } code

=State Pattern= According to the Head First book, the state pattern allows an object to alter its behavior when its internal state changes. The object will appear to change its class.

**Benefits of the State Pattern**
The state pattern is beneficial in that it provides a pattern that can be used in computer programming with the representation of the state of objects. The state pattern is a clean way for an object to partially change its type at runtime.

**Alternative Design of the State Pattern**
There are several alternative designs to the state pattern listed below.

Introduction of a event class
Developers can introduce a class for events and or enumerator types that the values of the enumeration represent the different possible events.

Flag and Condition Logic
Developers will use this approach to represent the state of the class by flags and or variables. Conditional logic within the methods will be used to determine the next state based on the current state condition.

Table Driven designs
This design involves adding a two dimensional array, table or object with states as one dimension and events as the other where each element of the array, table or object contains the next state. Developers can at anytime add addition arrays, tables or objects to support other aspects of the onEvent methods. This design approach has an advantage where the whole state machine is viewed and or housed in a single place making it easier to review and maintain the states.

**Alternative Design Problems of the State Pattern**
With all of the alternative design patterns junior developers may be unfamiliar with the techniques, but none of the designs listed above require much to understand.

**Problems Solved by the State Pattern**
States of objects can easily be maintained. The main use and problems solved of this pattern is with vending machines, traffic lights and other equipment similar to the previous ones listed.

**State Pattern Code Example**
The following is another simple code example that is almost like a state machine. This example is used to control how we order inventory for a store or supply office or something similar to the previous examples. code format="csharp" using System;

namespace StatePattern {   public class StatePattern {       // program entry point public static void Main(string[] args) {           // Set state values and run results // ***** stateFullInventory ***** // writes new line Console.WriteLine(System.Environment.NewLine); // writes stateFullInventory Console.WriteLine("stateFullInventory"); // creates an instance of Inventory with stateFullInventory Inventory inventory = new Inventory(new stateFullInventory); // calls inventory.Request passes in count and max inventory inventory.Request(100, 100); // writes *** set state for test *** Console.WriteLine("*** set state for test ***"); // set instance object equal to new stateFullInventory inventory.state = new stateFullInventory; // calls inventory.Request passes in count and max inventory inventory.Request(75, 100); // writes *** set state for test *** Console.WriteLine("*** set state for test ***"); // set instance object equal to new stateFullInventory inventory.state = new stateFullInventory; // calls inventory.Request passes in count and max inventory inventory.Request(25, 100); // writes *** set state for test *** Console.WriteLine("*** set state for test ***"); // set instance object equal to new stateFullInventory inventory.state = new stateFullInventory; // calls inventory.Request passes in count and max inventory inventory.Request(10, 100); // writes *** set state for test *** Console.WriteLine("*** set state for test ***"); // set instance object equal to new stateFullInventory inventory.state = new stateFullInventory; // calls inventory.Request passes in count and max inventory inventory.Request(0, 100);

// ***** stateModerateInventory ***** Console.WriteLine(System.Environment.NewLine); // writes stateModerateInventory Console.WriteLine("stateModerateInventory"); // writes *** set state for test *** Console.WriteLine("*** set state for test ***"); // set instance object equal to new stateModerateInventory inventory.state = new stateModerateInventory; // calls inventory.Request passes in count and max inventory inventory.Request(100, 100); // writes *** set state for test *** Console.WriteLine("*** set state for test ***"); // set instance object equal to new stateModerateInventory inventory.state = new stateModerateInventory; // calls inventory.Request passes in count and max inventory inventory.Request(50, 100); // writes *** set state for test *** Console.WriteLine("*** set state for test ***"); // set instance object equal to new stateModerateInventory inventory.state = new stateModerateInventory; // calls inventory.Request passes in count and max inventory inventory.Request(10, 100); // writes *** set state for test *** Console.WriteLine("*** set state for test ***"); // set instance object equal to new stateModerateInventory inventory.state = new stateModerateInventory; // calls inventory.Request passes in count and max inventory inventory.Request(0, 100);

// ***** stateLowInventory ***** Console.WriteLine(System.Environment.NewLine); // set instance object equal to new stateLowInventory Console.WriteLine("stateLowInventory"); // writes *** set state for test *** Console.WriteLine("*** set state for test ***"); // set instance object equal to new stateLowInventory inventory.state = new stateLowInventory; // calls inventory.Request passes in count and max inventory inventory.Request(100, 100); // writes *** set state for test *** Console.WriteLine("*** set state for test ***"); // set instance object equal to new stateLowInventory inventory.state = new stateLowInventory; // calls inventory.Request passes in count and max inventory inventory.Request(25, 100); // writes *** set state for test *** Console.WriteLine("*** set state for test ***"); // set instance object equal to new stateLowInventory inventory.state = new stateLowInventory; // calls inventory.Request passes in count and max inventory inventory.Request(8, 100); // writes *** set state for test *** Console.WriteLine("*** set state for test ***"); // set instance object equal to new stateLowInventory inventory.state = new stateLowInventory; // calls inventory.Request passes in count and max inventory inventory.Request(0, 100);

// ***** stateOutInventory ***** Console.WriteLine(System.Environment.NewLine); // writes stateOutInventory Console.WriteLine("stateOutInventory"); // set instance object equal to new stateOutInventory inventory.state = new stateOutInventory; // calls inventory.Request passes in count and max inventory inventory.Request(0, 100);

// waits for user input Console.ReadLine; }   }

// the class inventory public class Inventory {       // property that gets or sets the class State private State _state; public State state {           get { return _state; } set {               _state = value; Console.WriteLine("current state: {0}", state.GetType.Name); }       }

// sets state object that is passed in to currents objects state public Inventory(State state) {           this.state = state; }

// this method calls state.Handle and passes the current object (state) // and passes the count and max inventory public void Request(double count, double maxInventory) {           state.Handle(this, count, maxInventory); }   }

// this is the abstact class State that the // (stateFullInventory, stateModerateInventory,   // stateLowInventory, stateOutInventory) // will be derived from public abstract class State {       // this is the interface method to Handle // in this code case it will be overriden by derived classes public abstract void Handle(Inventory inventory, double count, double maxInventory); }

// this is the class stateFullInventory derived from State public class stateFullInventory : State {       // the Handle method here overrides the State.Handle method public override void Handle(Inventory inventory, double count, double maxInventory) {           // divided count by maxInventory double result = count / maxInventory; // checks if result is greater than 0.75 if (result > 0.75) // writes to console what and how order needs to be placed Console.WriteLine("Order not necessary slow moving item"); // checks if result is greater than 0.25 else if (result > 0.25) {               // writes to console what and how order needs to be placed Console.WriteLine("Order {0} standard shipping!", maxInventory - count); // sets inventory.state to Moderate inventory.state = new stateModerateInventory; }           // checks if result is greater than 0.1 else if (result > 0.10) {               // writes to console what and how order needs to be placed Console.WriteLine("Order {0} express shipping!", maxInventory - count); // sets inventory.state to Low inventory.state = new stateLowInventory; }           // checks if result is 0.0 else if (result == 0.0) {               // writes to console what and how order needs to be placed Console.WriteLine("HOT inventory empty: Order {0} next day shipping!", maxInventory * 0.50); Console.WriteLine("HOT inventory empty: Order {0} standard shipping!", maxInventory * 0.50); // sets inventory.state to Full inventory.state = new stateFullInventory; }       }    }

// this is the class stateModerateInventory derived from State public class stateModerateInventory : State {       // the Handle method here overrides the State.Handle method public override void Handle(Inventory inventory, double count, double maxInventory) {           // divided count by maxInventory double result = count / maxInventory; // checks if result is greater than 0.5 if (result > 0.50) // writes to console what and how order needs to be placed Console.WriteLine("Order not necessary slow moving item"); // checks if result is greater than 0.25 else if (result > 0.25) {               // writes to console what and how order needs to be placed Console.WriteLine("Order {0} standard shipping!", maxInventory - count); // sets inventory.state to Low inventory.state = new stateLowInventory; }           // checks if result is greater than 0.1 else if (result > 0.10) {               // writes to console what and how order needs to be placed Console.WriteLine("Order {0} express shipping!", maxInventory - count); // sets inventory.state to Low inventory.state = new stateLowInventory; }           // checks if result is 0.0 else if (result == 0.0) {               // writes to console what and how order needs to be placed Console.WriteLine("ITEM inventory empty: Order {0} next day shipping!", maxInventory * 0.25); Console.WriteLine("ITEM inventory empty: Order {0} standard shipping!", maxInventory * 0.75); // sets inventory.state to Moderate inventory.state = new stateModerateInventory; }       }    }

// this is the class stateLowInventory derived from State public class stateLowInventory : State {       // the Handle method here overrides the State.Handle method public override void Handle(Inventory inventory, double count, double maxInventory) {           // divided count by maxInventory double result = count / maxInventory; // checks if result is greater than 0.25 if (result > 0.25) {               // writes to console what and how order needs to be placed Console.WriteLine("Order not necessary slow moving item"); // sets inventory.state to Moderate inventory.state = new stateModerateInventory; }           // checks if result is greater than 0.08 else if (result > 0.08) {               // writes to console what and how order needs to be placed Console.WriteLine("Order {0} standard shipping!", maxInventory - count); // sets inventory.state to Low inventory.state = new stateLowInventory; }           // checks if result is 0.0 else if (result == 0.0) {               // writes to console what and how order needs to be placed Console.WriteLine("ITEM inventory empty {0} standard shipping!", maxInventory - count); // sets inventory.state to Moderate inventory.state = new stateModerateInventory; }       }    }

// this is the class stateOutInventory derived from State public class stateOutInventory : State {       // the Handle method here overrides the State.Handle method public override void Handle(Inventory inventory, double count, double maxInventory) {           // writes to console what and how order needs to be placed Console.WriteLine("ITEM inventory empty: Order {0} next day shipping!", maxInventory * 0.10); Console.WriteLine("ITEM inventory empty: Order {0} standard shipping!", maxInventory * 0.90); // sets inventory.state to Full inventory.state = new stateFullInventory; }   } } code

Template Pattern
This pattern is used to define the program skeleton of an algorithm where one or more of the algorithm steps may be overridden by a subclass to provide their own concrete implementation. This pattern allows for differing behaviors while ensuring that the main encompassing algorithm pattern is followed. The template method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure.

Benefits of the Template Pattern
The template method benefits us because it encapsulates interchangeable behaviors and uses delegation to decide which the best behavior is to use.

Alternative Design of the Template Pattern
The alternative design to the template method is to duplicate your code where ever it is needed. You will have to duplicate the general code in the algorithm and implement it in several subclasses.

Alternative Design Problems of the Template Pattern
The alternative design problems here are the duplicate code and the efforts it takes to maintain the code.

Problems Solved by the Template Pattern
The problems solved by the template pattern are that the patterns can prevent duplicate and provide developers with a control point or points at which subclassing is allowed and implemented through overriding.

**Template Pattern Code Example**
This example is our favorite and we see a lot of potential with it. In this example we created a report template that we will hopefully one day use to give us the formatted data of a set of reports. code format="csharp" using System; using System.Data;

namespace TemplatePattern {   public class Program {       // the main entry point of the program public static void Main(string[] args) {           // creates an instance of reportUser // this instance is of type reportUser // from type ReportTemplate ReportTemplate rt1 = new reportUser; // calls reportUser.initReport method rt1.initReport; // writes a new line Console.WriteLine(System.Environment.NewLine);

// creates an instance of reportOrder // this instance is of type reportOrder // from type ReportTemplate ReportTemplate rt2 = new reportOrder; // calls reportOrder.initReport method rt2.initReport; // writes a new line Console.WriteLine(System.Environment.NewLine);

// waits for user input Console.ReadLine; }   }

// creates abstract class ReportTemplate public abstract class ReportTemplate {       // creates an abstract method // this method gets overriden in       // classes that extend ReportTemplate public abstract void getData;

// creates an abstract method // this method gets overriden in       // classes that extend ReportTemplate public abstract void hideColumns;

public void initReport // The template method {           getData; // calls getData hideColumns; // calls hide columns // writes the results of returnReport as a string Console.Write(returnReport.ToString); }

// returns a dataview of the report we want to run private DataView returnReport {           // creates a new DataView // in this method here we would get real report // data but for this example it does not matter return new DataView; }   }

// creates class reportUser that derives from ReportTemplate internal class reportUser : ReportTemplate {       // this method overrides the ReportTemplate.getData method public override void getData {           // writes "USER data retrieved" to the console Console.WriteLine("USER data retrieved"); }

// this method overrides the ReportTemplate.hideColumns method public override void hideColumns {           // writes "columns [SSN, Phone, Address] hidden" to the console Console.WriteLine("columns [SSN, Phone, Address] hidden"); }   }

// creates class reportOrder that derives from ReportTemplate internal class reportOrder : ReportTemplate {       // this method overrides the ReportTemplate.getData method public override void getData {           // writes "ORDER data retrieved" to the console Console.WriteLine("ORDER data retrieved"); }

// this method overrides the ReportTemplate.hideColumns method public override void hideColumns {           // writes "no columns hidden" to the console Console.WriteLine("no columns hidden"); }   } } code