Bridges_Gluvna

=  = =   = =   = == This project will demonstrate four design patterns covered in "Head First Design Patterns" from the 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. == 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.

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.

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 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 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.

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.

The following is a very simple code example we created that is used to iterate through a group of reports. 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; } }  }  }

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.”

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.

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.

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.

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.

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. 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); } }  }

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.

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.

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.

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.

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.

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. 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); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes stateFullInventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "stateFullInventory" ); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // creates an instance of Inventory with stateFullInventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Inventory inventory = new Inventory ( new stateFullInventory ); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // calls inventory.Request passes in count and max inventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.Request(100, 100); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes *** set state for test *** <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "*** set state for test ***" ); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // set instance object equal to new stateFullInventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.state = new stateFullInventory ; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // calls inventory.Request passes in count and max inventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.Request(75, 100); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes *** set state for test *** <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "*** set state for test ***" ); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // set instance object equal to new stateFullInventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.state = new stateFullInventory ; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // calls inventory.Request passes in count and max inventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.Request(25, 100); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes *** set state for test *** <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "*** set state for test ***" ); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // set instance object equal to new stateFullInventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.state = new stateFullInventory ; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // calls inventory.Request passes in count and max inventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.Request(10, 100); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes *** set state for test *** <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "*** set state for test ***" ); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // set instance object equal to new stateFullInventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.state = new stateFullInventory ; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // calls inventory.Request passes in count and max inventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.Request(0, 100); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // ***** stateModerateInventory ***** <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine(System. Environment .NewLine); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes stateModerateInventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "stateModerateInventory" ); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes *** set state for test *** <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "*** set state for test ***" ); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // set instance object equal to new stateModerateInventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.state = new stateModerateInventory ; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // calls inventory.Request passes in count and max inventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.Request(100, 100); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes *** set state for test *** <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "*** set state for test ***" ); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // set instance object equal to new stateModerateInventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.state = new stateModerateInventory ; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // calls inventory.Request passes in count and max inventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.Request(50, 100); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes *** set state for test *** <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "*** set state for test ***" ); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // set instance object equal to new stateModerateInventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.state = new stateModerateInventory ; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // calls inventory.Request passes in count and max inventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.Request(10, 100); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes *** set state for test *** <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "*** set state for test ***" ); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // set instance object equal to new stateModerateInventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.state = new stateModerateInventory ; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // calls inventory.Request passes in count and max inventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.Request(0, 100); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // ***** stateLowInventory ***** <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine(System. Environment .NewLine); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // set instance object equal to new stateLowInventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "stateLowInventory" ); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes *** set state for test *** <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "*** set state for test ***" ); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // set instance object equal to new stateLowInventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.state = new stateLowInventory ; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // calls inventory.Request passes in count and max inventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.Request(100, 100); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes *** set state for test *** <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "*** set state for test ***" ); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // set instance object equal to new stateLowInventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.state = new stateLowInventory ; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // calls inventory.Request passes in count and max inventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.Request(25, 100); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes *** set state for test *** <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "*** set state for test ***" ); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // set instance object equal to new stateLowInventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.state = new stateLowInventory ; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // calls inventory.Request passes in count and max inventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.Request(8, 100); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes *** set state for test *** <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "*** set state for test ***" ); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // set instance object equal to new stateLowInventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.state = new stateLowInventory ; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // calls inventory.Request passes in count and max inventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.Request(0, 100); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // ***** stateOutInventory ***** <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine(System. Environment .NewLine); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes stateOutInventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "stateOutInventory" ); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // set instance object equal to new stateOutInventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.state = new stateOutInventory ; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // calls inventory.Request passes in count and max inventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.Request(0, 100); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // waits for user input <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .ReadLine; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // the class inventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> public class Inventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // property that gets or sets the class State <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> private State _state; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> public State state <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> get { return _state; } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> set <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> _state = value ; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "current state: {0}", state.GetType.Name); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // sets state object that is passed in to currents objects state <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> public Inventory( State state) <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> this .state = state; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // this method calls state.Handle and passes the current object (state) <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // and passes the count and max inventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> public void Request( double count, double maxInventory) <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> state.Handle( this, count, maxInventory); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // this is the abstact class State that the <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // (stateFullInventory, stateModerateInventory, <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // stateLowInventory, stateOutInventory) <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // will be derived from <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> public abstract class State <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // this is the interface method to Handle <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // in this code case it will be overriden by derived classes <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> public abstract void Handle( Inventory inventory, double count, double maxInventory); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // this is the class stateFullInventory derived from State <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> public class stateFullInventory : State <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // the Handle method here overrides the State.Handle method <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> public override void Handle( Inventory inventory, double count, double maxInventory) <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // divided count by maxInventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> double result = count / maxInventory; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // checks if result is greater than 0.75 <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> if (result > 0.75) <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes to console what and how order needs to be placed <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "Order not necessary slow moving item" ); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // checks if result is greater than 0.25 <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> else if (result > 0.25) <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes to console what and how order needs to be placed <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "Order {0} standard shipping!", maxInventory - count); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // sets inventory.state to Moderate <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.state = new stateModerateInventory ; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // checks if result is greater than 0.1 <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> else if (result > 0.10) <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes to console what and how order needs to be placed <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "Order {0} express shipping!", maxInventory - count); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // sets inventory.state to Low <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.state = new stateLowInventory ; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // checks if result is 0.0 <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> else if (result == 0.0) <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes to console what and how order needs to be placed <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "HOT inventory empty: Order {0} next day shipping!", maxInventory * 0.50); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "HOT inventory empty: Order {0} standard shipping!", maxInventory * 0.50); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // sets inventory.state to Full <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.state = new stateFullInventory ; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // this is the class stateModerateInventory derived from State <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> public class stateModerateInventory : State <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // the Handle method here overrides the State.Handle method <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> public override void Handle( Inventory inventory, double count, double maxInventory) <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // divided count by maxInventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> double result = count / maxInventory; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // checks if result is greater than 0.5 <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> if (result > 0.50) <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes to console what and how order needs to be placed <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "Order not necessary slow moving item" ); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // checks if result is greater than 0.25 <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> else if (result > 0.25) <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes to console what and how order needs to be placed <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "Order {0} standard shipping!", maxInventory - count); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // sets inventory.state to Low <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.state = new stateLowInventory ; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // checks if result is greater than 0.1 <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> else if (result > 0.10) <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes to console what and how order needs to be placed <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "Order {0} express shipping!", maxInventory - count); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // sets inventory.state to Low <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.state = new stateLowInventory ; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // checks if result is 0.0 <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> else if (result == 0.0) <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes to console what and how order needs to be placed <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "ITEM inventory empty: Order {0} next day shipping!", maxInventory * 0.25); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "ITEM inventory empty: Order {0} standard shipping!", maxInventory * 0.75); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // sets inventory.state to Moderate <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.state = new stateModerateInventory ; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // this is the class stateLowInventory derived from State <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> public class stateLowInventory : State <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // the Handle method here overrides the State.Handle method <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> public override void Handle( Inventory inventory, double count, double maxInventory) <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // divided count by maxInventory <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> double result = count / maxInventory; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // checks if result is greater than 0.25 <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> if (result > 0.25) <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes to console what and how order needs to be placed <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "Order not necessary slow moving item" ); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // sets inventory.state to Moderate <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.state = new stateModerateInventory ; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // checks if result is greater than 0.08 <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> else if (result > 0.08) <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes to console what and how order needs to be placed <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "Order {0} standard shipping!", maxInventory - count); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // sets inventory.state to Low <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.state = new stateLowInventory ; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // checks if result is 0.0 <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> else if (result == 0.0) <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes to console what and how order needs to be placed <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "ITEM inventory empty {0} standard shipping!", maxInventory - count); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // sets inventory.state to Moderate <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.state = new stateModerateInventory ; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // this is the class stateOutInventory derived from State <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> public class stateOutInventory : State <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // the Handle method here overrides the State.Handle method <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> public override void Handle( Inventory inventory, double count, double maxInventory) <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes to console what and how order needs to be placed <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "ITEM inventory empty: Order {0} next day shipping!", maxInventory * 0.10); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "ITEM inventory empty: Order {0} standard shipping!", maxInventory * 0.90); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // sets inventory.state to Full <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> inventory.state = new stateFullInventory ; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; line-height: 115%; mso-fareast-language: ZH-TW; mso-no-proof: yes;">}

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.

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

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.

The alternative design problems here are the duplicate code and the efforts it takes to maintain the code.

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.

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. <span style="color: blue; font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;">using <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> System; <span style="color: blue; font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;">using <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> System.Data; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> <span style="color: blue; font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;">namespace <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> TemplatePattern <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;">{ <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> public class Program <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // the main entry point of the program <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> public static void Main( string [] args) <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // creates an instance of reportUser <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // this instance is of type reportUser <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // from type ReportTemplate <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> ReportTemplate rt1 = new reportUser ; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // calls reportUser.initReport method <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> rt1.initReport; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes a new line <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine(System. Environment .NewLine); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // creates an instance of reportOrder <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // this instance is of type reportOrder <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // from type ReportTemplate <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> ReportTemplate rt2 = new reportOrder ; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // calls reportOrder.initReport method <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> rt2.initReport; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes a new line <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine(System. Environment .NewLine); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // waits for user input <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .ReadLine; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // creates abstract class ReportTemplate <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> public abstract class ReportTemplate <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // creates an abstract method <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // this method gets overriden in <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // classes that extend ReportTemplate <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> public abstract void getData; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // creates an abstract method <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // this method gets overriden in <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // classes that extend ReportTemplate <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> public abstract void hideColumns; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> public void initReport // The template method <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> getData; // calls getData <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> hideColumns; // calls hide columns <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes the results of returnReport as a string <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .Write(returnReport.ToString); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // returns a dataview of the report we want to run <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> private DataView returnReport <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // creates a new DataView <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // in this method here we would get real report <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // data but for this example it does not matter <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> return new DataView ; <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // creates class reportUser that derives from ReportTemplate <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> internal class reportUser : ReportTemplate <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // this method overrides the ReportTemplate.getData method <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> public override void getData <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes "USER data retrieved" to the console <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "USER data retrieved" ); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // this method overrides the ReportTemplate.hideColumns method <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> public override void hideColumns <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes "columns [SSN, Phone, Address] hidden" to the console <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "columns [SSN, Phone, Address] hidden" ); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // creates class reportOrder that derives from ReportTemplate <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> internal class reportOrder : ReportTemplate <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // this method overrides the ReportTemplate.getData method <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> public override void getData <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes "ORDER data retrieved" to the console <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "ORDER data retrieved" ); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // this method overrides the ReportTemplate.hideColumns method <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> public override void hideColumns <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> { <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> // writes "no columns hidden" to the console <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> Console .WriteLine( "no columns hidden" ); <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; mso-fareast-language: ZH-TW; mso-no-proof: yes;"> } <span style="font-family: "Courier New"; font-size: 8.0pt; line-height: 115%; mso-fareast-language: ZH-TW; mso-no-proof: yes;">}