Design patterns:solidify Your C # application Arch

Source: Internet
Author: User
Tags abstract array implement include visual studio
Design patterns:solidify Your C # application architecture with design Patterns Chinese version (next) optimizer (translation)

Keyword design pattern singleton strategy Decorator Composite State

SOURCE http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnmag01/html/PATTERNS.asp



Design patterns:solidify Your C # application architecture with design Patterns Chinese version (next article)

Author: Samir Bajaj

Translator: Glory

"Preface: C # Advanced article. The translator simply collates the C # examples provided by Samir (some of the code provided by the author cannot be compiled in the translator's environment) and writes the corresponding C + + example, which is also put in the program so that the reader can match it. All C #, C + + program debugging environments in the translation are Microsoft Visual Studio.NET 7.0 Beta2 "

C + + Example:

#include "stdafx.h";

#include <iostream>

#include <list>

using namespace Std;

Class Shape

{

Public

virtual void Draw () {};

};

Class Line:public Shape

{

Private

Double x1, y1, x2, y2;

Public

Line (double x1, double y1, double x2, double y2)

{

this->x1 = x1;

this->y1 = y1;

this->x2 = x2;

This->y2 = y2;

}

void Draw ()

{

Draw a line from (x1, y1) to (x2, y2)

cout<< "Drawing a line" <<endl;

}

};

Class Circle:public Shape

{

Private

Double x, Y, R;

Public

Circle (double x, double y, double radius)

{

this->x = x;

This->y = y;

This->r = R;

}

void Draw ()

{

With (x, y) as the center, R for RADIUS draw a circle

cout<< "Drawing a Circle" <<endl;

}

};

Class Drawing:public Shape

{

Private

list<shape*> shapes;

List<shape*>::iterator it;

Public

Drawing ()

{

}

~drawing ()

{

for (it = Shapes.begin (); it!= shapes.end (); it++)

{

if (*it)

{

Delete *it;

*it = NULL;

}

}

Shapes.clear ();

}

void Add (shape* s)

{

Shapes.push_back (s);

}

void Draw ()

{

for (it = Shapes.begin (); it!= shapes.end (); it++)

{

(Dynamic_cast<shape*> (*it))->draw ();

}

}

};

int _tmain (int argc, _tchar* argv[])

{

line* line = new Line (0, 0, 10, 12);

circle* Circle = new Circle (2, 3, 5.5);

drawing* dwg = new Drawing ();

Dwg->add (New Line (3, 4, 3, 5));

Dwg->add (New Circle (5, 6, 7.7));

shape* Array[3] = {line, circle, DWG};

Draw all the graphics, note: Access to all objects in a consistent way

for (int i = 0; i < 3; ++i)

{

Array[i]->draw ();

Delete Array[i];

}

return 0;

}

/* The following is the program output result:

Drawing a line

Drawing a circle

Drawing a line

Drawing a circle

*/



State

Each developer has at least one finite state machine implemented in his or her career. You can't avoid them, they're everywhere, and not just in software development. It is not surprising that the literature on the design and implementation of deterministic finite automata is everywhere. When it comes to finite state machines, I'm often surprised to see poorly designed cases that are full of bugs and do not consider extensibility at all. The ability to add more states to a finite automaton is usually an unwritten requirement. When you need to add more states and transitions, you often need to modify the implementation. If designed well, you can anticipate and deal with this change. More importantly, the behavior and operational details of any state in a finite state machine should only be limited to the representation of that state. In other words, the state detail code should reside in the object that implements the state, which is easy to add to the new state and easy to convert.

The method based on table lookup is a popular design method of finite state machine. A table maps all possible inputs to state transitions (that is, transitions that can cause a finite state machine to transform to another state). Needless to say, although this approach is relatively simple, it is not possible to adapt to changing requirements without making significant changes to existing implementation code. A better alternative is to use the state design pattern.

Suppose the software is used to implement a carbonated beverage vending machine, which accepts only 5 points, 10 cents and 25 cents, and emits a can of a beverage when the coin has accumulated to or exceeds 25. Each time a coin is put into the slot, the vending machine is converted to a different state until the number of coins is reached, and the machine sends a can of drinks and resets back to the start state. The table 10 code defines an abstract class state, which represents the base class of all States that the vending machine can transform.

Table 10

Abstract class State

{

public virtual void Addnickel (Vendingmachine vm) {}

public virtual void Adddime (Vendingmachine vm) {}

public virtual void Addquarter (Vendingmachine vm) {}

protected virtual void Changestate (Vendingmachine vm, State s)

{

Vm. Changestate (s);

}

}


All 5 states derive from the base class and overload the corresponding virtual method. For example, when the vending machine is in the start state, put a 5 cent coin, the machine becomes five state, if another 5 cents, then switch to ten state. This separates the transformation logic into each object that implements the state. Table 11 shows the two classes that implement the status.

Table 11

Class Start:state

{

private static state = new Start ();

Private Start ()

{

}

public static state Instance ()

{

Singleton logic

Console.WriteLine ("credit:0c");

return state;

}

public override void Addnickel (Vendingmachine vm)

{

Changestate (VM, Five.instance ());

}

public override void Adddime (Vendingmachine vm)

{

Changestate (VM, Ten.instance ());

}

public override void Addquarter (Vendingmachine vm)

{

Vm. Vend ();

}

}

Class Five:state

{

private static state = new Five ();

Private Five ()

{

}

public static state Instance ()

{

Singleton logic

Console.WriteLine ("credit:5c");

return state;

}

public override void Addnickel (Vendingmachine vm)

{

Changestate (VM, Ten.instance ());

}

public override void Adddime (Vendingmachine vm)

{

Changestate (VM, Fifteen.instance ());

}

public override void Addquarter (Vendingmachine vm)

{

Vm. Vend ();

Changestate (VM, Start.instance ()); No change returned:-)

}

}


The vending machine doesn't have to care about state transition logic, it only works with the current state instance, so that it's completely decoupled from the details of the status. See table 12.

Table 12

Class Vendingmachine

{

Private state State;

Public Vendingmachine ()

{

Console.WriteLine ("The Vending Machine is now online:product costs 25c");

State = Start.instance ();

}

public void Changestate

{

state = to;

}

public void Vend ()

{

Hair Drinks

Console.WriteLine ("Dispensing product ...") Thank you! ");

}

public void Addnickel ()

{

State. Addnickel (this);

}

public void Adddime ()

{

State. Adddime (this);

}

public void Addquarter ()

{

State. Addquarter (this);

}

}


I've explained that state mode is better than simple, table lookup based implementations. In summary, this design pattern facilitates the reuse and extension of the software by helping to localize the state detail behavior into the classes that implement the specific state. This also avoids the need to write conditional statements around in the program code, which will make it miserable for the programmers who maintain the code, and in reality, the number of those responsible for maintaining the programmer is much larger than the original implementation.






Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.