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