[置顶]c# 设计模式(3)行为型
2011-07-14 17:39 乱世文章 阅读(143) 评论(0) 编辑 收藏 举报
| |
名称 | Interpreter |
结构 | |
意图 | 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。 |
适用性 |
|
Code Example | namespace Interpreter_DesignPattern { using System; using System.Collections; class Context { } abstract class AbstractExpression { abstract public void Interpret(Context c); } // class for terminal symbol class TerminalExpression : AbstractExpression { override public void Interpret(Context c) { } } // class for grammar rule (one per rule needed) class NonterminalExpression : AbstractExpression { override public void Interpret(Context c) { } } // to extend grammar, just add other NonterminalExpression classes /// <summary> /// Summary description for Client. /// </summary> public class Client { public static int Main(string[] args) { Context c = new Context(); ArrayList l = new ArrayList(); //really need a tree here! // build up context information // . . . // Populate abstract syntax tree with data l.Add(new TerminalExpression()); l.Add(new NonterminalExpression()); // interpret foreach (AbstractExpression exp in l) { exp.Interpret(c); } return 0; } } } |
名称 | Template Method |
结构 | |
意图 | 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Te m p l a t e M e t h o d 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 |
适用性 |
|
Code Example | namespace TemplateMethod_DesignPattern { using System; class Algorithm { public void DoAlgorithm() { Console.WriteLine("In DoAlgorithm"); // do some part of the algorithm here // step1 goes here Console.WriteLine("In Algorithm - DoAlgoStep1"); // . . . // step 2 goes here Console.WriteLine("In Algorithm - DoAlgoStep2"); // . . . // Now call configurable/replacable part DoAlgoStep3(); // step 4 goes here Console.WriteLine("In Algorithm - DoAlgoStep4"); // . . . // Now call next configurable part DoAlgoStep5(); } virtual public void DoAlgoStep3() { Console.WriteLine("In Algorithm - DoAlgoStep3"); } virtual public void DoAlgoStep5() { Console.WriteLine("In Algorithm - DoAlgoStep5"); } } class CustomAlgorithm : Algorithm { public override void DoAlgoStep3() { Console.WriteLine("In CustomAlgorithm - DoAlgoStep3"); } public override void DoAlgoStep5() { Console.WriteLine("In CustomAlgorithm - DoAlgoStep5"); } } /// <summary> /// Summary description for Client. /// </summary> public class Client { public static int Main(string[] args) { CustomAlgorithm c = new CustomAlgorithm(); c.DoAlgorithm(); return 0; } } } |
名称 | Chain of Responsibility |
结构 | |
意图 | 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。 |
适用性 |
|
Code Example | namespace ChainOfResponsibility_DesignPattern { using System; abstract class Handler { protected Handler successorHandler; abstract public void HandleRequest(Request request); public void SetSuccessor(Handler sucessor) { successorHandler = sucessor; } } class ConcreteHandler1 : Handler { override public void HandleRequest(Request request) { // determine if we can handle the request if (request.RequestType == 1) // some complex decision making! { // request handling code goes here Console.WriteLine("request handled in ConcreteHandler1"); } else { // not handled here - pass on to next in the chain if (successorHandler != null) successorHandler.HandleRequest(request); } } } class ConcreteHandler2 : Handler { override public void HandleRequest(Request request) { // determine if we can handle the request if (request.RequestType == 2) // some complex decision making! { // request handling code goes here Console.WriteLine("request handled in ConcreteHandler2"); } else { // not handled here - pass on to next in the chain if (successorHandler != null) successorHandler.HandleRequest(request); } } } class ConcreteHandler3 : Handler { override public void HandleRequest(Request request) { // determine if we can handle the request if (request.RequestType == 3) // some complex decision making! { // request handling code goes here Console.WriteLine("request handled in ConcreteHandler3"); } else { // not handled here - pass on to next in the chain if (successorHandler != null) successorHandler.HandleRequest(request); } } } class Request { private int iRequestType; private string strRequestParameters; public Request(int requestType, string requestParameters) { iRequestType = requestType; strRequestParameters = requestParameters; } public int RequestType { get { return iRequestType; } set { iRequestType = value; } } } /// <summary> /// Summary description for Client. /// </summary> public class Client { public static int Main(string[] args) { // Set up chain (usually one need to be done once) Handler firstHandler = new ConcreteHandler1(); Handler secondHandler = new ConcreteHandler2(); Handler thirdHandler = new ConcreteHandler3(); firstHandler.SetSuccessor(secondHandler); secondHandler.SetSuccessor(thirdHandler); // After setting up the chain of responsibility, we can // now generate requests and pass then off to the // chain to be handled // generate and fire request Request newRequest = new Request(2,"This are the request parameters"); firstHandler.HandleRequest(newRequest); return 0; } } } |
名称 | Command |
结构 | |
意图 | 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。 |
适用性 |
|
Code Example | namespace Command_DesignPattern { using System; abstract class Command { abstract public void Execute(); protected Receiver r; public Receiver R { set { r = value; } } } class ConcreteCommand : Command { override public void Execute() { Console.WriteLine("Command executed"); r.InformAboutCommand(); } } class Receiver { public void InformAboutCommand() { Console.WriteLine("Receiver informed about command"); } } class Invoker { private Command command; public void StoreCommand(Command c) { command = c; } public void ExecuteCommand() { command.Execute(); } } /// <summary> /// Summary description for Client. /// </summary> public class Client { public static int Main(string[] args) { // Set up everything Command c = new ConcreteCommand(); Receiver r = new Receiver(); c.R = r; Invoker i = new Invoker(); i.StoreCommand(c); // now let application run // the invoker is how the command is exposed for the end-user // (or a client) initiates the command, // (e.g. toolbar button, menu item) i.ExecuteCommand(); return 0; } } } |
名称 | Iterator |
结构 | |
意图 | 提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。 |
适用性 |
|
Code Example | namespace Iterator_DesignPattern { using System; using System.Collections; class Node { private string name; public string Name { get { return name; } } public Node(string s) { name = s; } } class NodeCollection { private ArrayList list = new ArrayList(); private int nodeMax = 0; // left as a student exercise - implement collection // functions to remove and edit entries also public void AddNode(Node n) { list.Add(n); nodeMax++; } public Node GetNode(int i) { return ((Node) list[i]); } public int NodeMax { get { return nodeMax; } } } /* * The iterator needs to understand how to traverse the collection * It can do that as way it pleases - forward, reverse, depth-first, */ abstract class Iterator { abstract public Node Next(); } class ReverseIterator : Iterator { private NodeCollection nodeCollection; private int currentIndex; public ReverseIterator (NodeCollection c) { nodeCollection = c; currentIndex = c.NodeMax -1; // array index starts at 0! } // note: as the code stands, if the collection changes, // the iterator needs to be restarted override public Node Next() { if (currentIndex == -1) return null; else return(nodeCollection.GetNode(currentIndex--)); } } /// <summary> /// Summary description for Client. /// </summary> public class Client { public static int Main(string[] args) { NodeCollection c = new NodeCollection(); c.AddNode(new Node("first")); c.AddNode(new Node("second")); c.AddNode(new Node("third")); // now use iterator to traverse this ReverseIterator i = new ReverseIterator(c); // the code below will work with any iterator type Node n; do { n = i.Next(); if (n != null) Console.WriteLine("{0}", n.Name); } while (n != null); return 0; } } }
|
名称 | Mediator |
结构 | |
意图 | 用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。 |
适用性 |
|
Code Example | namespace Mediator_DesignPattern { using System; class Mediator { private DataProviderColleague dataProvider; private DataConsumerColleague dataConsumer; public void IntroduceColleagues(DataProviderColleague c1, DataConsumerColleague c2) { dataProvider = c1; dataConsumer = c2; } public void DataChanged() { int i = dataProvider.MyData; dataConsumer.NewValue(i); } } class DataConsumerColleague { public void NewValue(int i) { Console.WriteLine("New value {0}", i); } } class DataProviderColleague { private Mediator mediator; private int iMyData=0; public int MyData { get { return iMyData; } set { iMyData = value; } } public DataProviderColleague(Mediator m) { mediator = m; } public void ChangeData() { iMyData = 403; // Inform mediator that I have changed the data if (mediator != null) mediator.DataChanged(); } } /// <summary> /// Summary description for Client. /// </summary> public class Client { public static int Main(string[] args) { Mediator m = new Mediator(); DataProviderColleague c1 = new DataProviderColleague(m); DataConsumerColleague c2 = new DataConsumerColleague(); m.IntroduceColleagues(c1,c2); c1.ChangeData(); return 0; } } } |
名称 | Memento |
结构 | |
意图 | 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。 |
适用性 |
|
Code Example | namespace Memento_DesignPattern { using System; class Originator { private double manufacturer=0; private double distributor = 0; private double retailer = 0; public void MakeSale(double purchasePrice) { // We assume sales are divided equally amount the three manufacturer += purchasePrice * .40; distributor += purchasePrice *.3; retailer += purchasePrice *.3; // Note: to avoid rounding errors for real money handling // apps, we should be using decimal integers // (but hey, this is just a demo!) } public Memento CreateMemento() { return (new Memento(manufacturer, distributor, retailer)); } public void SetMemento(Memento m) { manufacturer = m.A; distributor = m.B; retailer = m.C; } } class Memento { private double iA; private double iB; private double iC; public Memento(double a, double b, double c) { iA = a; iB = b; iC = c; } public double A { get { return iA; } } public double B { get { return iB; } } public double C { get { return iC; } } } class caretaker { } /// <summary> /// Summary description for Client. /// </summary> public class Client { public static int Main(string[] args) { Originator o = new Originator(); // Assume that during the course of running an application // we we set various data in the originator o.MakeSale(45.0); o.MakeSale(60.0); // Now we wish to record the state of the object Memento m = o.CreateMemento(); // We make further changes to the object o.MakeSale(60.0); o.MakeSale(10.0); o.MakeSale(320.0); // Then we decide ot change our minds, and revert to the saved state (and lose the changes since then) o.SetMemento(m); return 0; } } } |
名称 | Observer |
结构 | |
意图 | 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。 |
适用性 |
|
Code Example | namespace Observer_DesignPattern { using System; using System.Collections;
class Subject { private ArrayList list = new ArrayList();
private string strImportantSubjectData = "Initial";
public string ImportantSubjectData { get { return strImportantSubjectData; } set { strImportantSubjectData = value; } }
public void Attach(Observer o) { list.Add(o); o.ObservedSubject = this; }
public void Detach(Observer o) {
}
public void Notify() { foreach (Observer o in list) { o.Update(); } } }
class ConcreteSubject : Subject { public void GetState() {
}
public void SetState() {
} }
abstract class Observer { protected Subject s; public Subject ObservedSubject { get { return s; } set { s = value; } } abstract public void Update(); }
class ConcreteObserver : Observer { private string observerName;
public ConcreteObserver(string name) { observerName = name; }
override public void Update() { Console.WriteLine("In Observer {0}: data from subject = {1}", observerName, s.ImportantSubjectData); } }
/// <summary> /// Summary description for Client. /// </summary> public class Client { public static int Main(string[] args) { // Set up everything ConcreteSubject s = new ConcreteSubject(); ConcreteObserver o1 = new ConcreteObserver("first observer"); ConcreteObserver o2 = new ConcreteObserver("second observer");
s.Attach(o1); s.Attach(o2);
// make changes to subject s. ImportantSubjectData = "This is important subject data";
// Notify all observers s.Notify(); return 0; } } } |
名称 | State |
结构 | |
意图 | 允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。 |
适用性 |
|
Code Example | namespace State_DesignPattern { using System; abstract class State { protected string strStatename; abstract public void Pour(); // do something state-specific here } class OpenedState : State { public OpenedState () { strStatename = "Opened"; } override public void Pour() { Console.WriteLine("...pouring..."); Console.WriteLine("...pouring..."); Console.WriteLine("...pouring..."); } } class ClosedState : State { public ClosedState() { strStatename = "Closed"; } override public void Pour() { Console.WriteLine("ERROR - bottle is closed - cannot pour"); } } class ContextColaBottle { public enum BottleStateSetting { Closed, Opened }; // If teh state classes had large amounts of instance data, // we could dynamically create them as needed - if this demo // they are tiny, so we just create them as data members OpenedState openedState = new OpenedState(); ClosedState closedState = new ClosedState(); public ContextColaBottle () { // Initialize to closed CurrentState = closedState; } private State CurrentState; public void SetState(BottleStateSetting newState) { if (newState == BottleStateSetting.Closed) { CurrentState = closedState; } else { CurrentState = openedState; } } public void Pour() { CurrentState.Pour(); } } /// <summary> /// Summary description for Client. /// </summary> public class Client { public static int Main(string[] args) { ContextColaBottle contextColaBottle = new ContextColaBottle(); Console.WriteLine("initial state is closed"); Console.WriteLine("Now trying to pour"); contextColaBottle.Pour(); Console.WriteLine("Open bottle"); contextColaBottle.SetState(ContextColaBottle.BottleStateSetting.Opened); Console.WriteLine("Try to pour again"); contextColaBottle.Pour(); return 0; } } } |
名称 | Strategy |
结构 | |
意图 | 定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。 |
适用性 |
|
Code Example | namespace Strategy_DesignPattern { using System; abstract class Strategy { abstract public void DoAlgorithm(); } class FirstStrategy : Strategy { override public void DoAlgorithm() { Console.WriteLine("In first strategy"); } } class SecondStrategy : Strategy { override public void DoAlgorithm() { Console.WriteLine("In second strategy"); } } class Context { Strategy s; public Context(Strategy strat) { s = strat; } public void DoWork() { // some of the context's own code goes here } public void DoStrategyWork() { // now we can hand off to the strategy to do some // more work s.DoAlgorithm(); } } /// <summary> /// Summary description for Client. /// </summary> public class Client { public static int Main(string[] args) { FirstStrategy firstStrategy = new FirstStrategy(); Context c = new Context(firstStrategy); c.DoWork(); c.DoStrategyWork(); return 0; } } } |
名称 | Visitor |
结构 | |
意图 | 表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。 |
适用性 |
|
Code Example | namespace Visitor_DesignPattern { using System; abstract class Visitor { abstract public void VisitElementA(ConcreteElementA a); abstract public void VisitElementB(ConcreteElementB b); } class ConcreteVisitor1 : Visitor { override public void VisitElementA(ConcreteElementA a) { } override public void VisitElementB(ConcreteElementB b) { } } abstract class Element { abstract public void Accept(Visitor v); } class ConcreteElementA : Element { public Visitor myVisitor; override public void Accept(Visitor v) { myVisitor = v; } public void OperationA() { } public void DoSomeWork() { // do some work here // . . . // Get visitor to visit myVisitor.VisitElementA(this); // do some more work here // . . . } } class ConcreteElementB : Element { override public void Accept(Visitor v) { } public void OperationB() { } } /// <summary> /// Summary description for Client. /// </summary> public class Client { public static int Main(string[] args) { ConcreteElementA eA = new ConcreteElementA(); ConcreteElementB eB = new ConcreteElementB(); ConcreteVisitor1 v1 = new ConcreteVisitor1(); eA.Accept(v1); eA.DoSomeWork(); return 0; } } } |