Archive for the ‘Behavioral Patterns’ tag
C# Design Patterns – State Pattern
State pattern is intended to provide a mechanism to allow an object to alter its behavior in response to internal state changes. To the client, it appears as though th object has changed its class.
And last, but not least, my most favorite design pattern: the State pattern. Why it is my favourite pattern? I am not sure, but I just like the fact that you can manipulate the state of an object. Once you get the idea of states, it is a very powerful way to add behavior to an object.
All the client needs to know is about a certain context and a state, which is injected into the context. Voila, the context has a state. By calling a method Request another state is requested. Nice, huh?
class Client
{
static void Main()
{
State state = new FirstConcreteState();
Context context = new Context(state);
Console.Write(context.State.GetType().Name + "->");
context.Request();
Console.Write(context.State.GetType().Name + "->");
context.Request();
Console.WriteLine(context.State.GetType().Name);
Console.ReadKey();
}
}
The abstract class State defines a method to handle the change of state within the current context.
abstract class State
{
public abstract void
Handle(Context context);
}
Upon creation of the context a state is injected and can be changed by calling a method Request.
class Context
{
public Context(State state)
{
this.State = state;
}
public State State { get; set; }
public void Request()
{
this.State.Handle(this);
}
}
The concrete states implement how the change of state is handled.
class FirstConcreteState : State
{
public override void Handle(Context context)
{
context.State = new SecondConcreteState();
}
}
class SecondConcreteState : State
{
public override void Handle(Context context)
{
context.State = new FirstConcreteState();
}
}
I think this is a nice pattern. You can apply this pattern in many ways, for example simple workflow or wizard like pages. One example I like is that of a dataform. When it shows up there is no need to save data, since it not has been altered. As soon as data is filled in the state of the form changes and the save button is enabled.
This post is part of a series on the foundational design patterns in C#. In this series we explore the ancient design patterns and their use in real-world programming situations of today. In these series of posts we explore each pattern by looking at a minimalistic example to reveal its structure and then look at more concrete and useful real-world C# code that implements the pattern.
C# Design Patterns – Strategy Pattern
The Strategy pattern is intended to provide you with a means to define a family of algorithms, encapsulate each one as an object, and make them interchangeable.
This is one of my favorite design patterns, because it provides you a way to encapsulate a strategy. This comes in very handy when you suspect that there will be a strategy update in the near future. For example, you could use this pattern for report engine selection.
The client first creates a context, in which a strategy is injected. In this simplified example a result is returned by a method called ContextInterface. Independent of the strategy selected, invocation of the method and collecting its result remains the same.
class MainApp
{
static void Main()
{
Context context;
Strategy strategy = new FirstConcreteStrategy();
context = new Context(strategy);
string result = context.ContextInterface();
Console.WriteLine(result);
strategy = new SecondConcreteStrategy();
context = new Context(strategy);
result = context.ContextInterface();
Console.WriteLine(result);
Console.ReadKey();
}
}
An abstract class Strategy defines an algorithm interface as a method.
abstract class Strategy
{
public abstract string AlgorithmInterface();
}
The concrete classes implement the abstract method.
class FirstConcreteStrategy : Strategy
{
public override string AlgorithmInterface()
{
return "FirstConcreteStrategy";
}
}
class SecondConcreteStrategy : Strategy
{
public override string AlgorithmInterface()
{
return "SecondConcreteStrategy";
}
}
The Context class contains a strategy, which is injected upon instantiation. The public method ContextInterface provide a way to call the algorithm interface of the encapsulated strategy.
class Context
{
private Strategy m_Strategy;
public Context(Strategy strategy)
{
this.m_Strategy = strategy;
}
public string ContextInterface()
{
return m_Strategy.AlgorithmInterface();
}
}
You see? It is a relatively simple pattern and similar to the factory method pattern. In my humble opinion there is not much difference between them.
This post is part of a series on the foundational design patterns in C#. In this series we explore the ancient design patterns and their use in real-world programming situations of today. In these series of posts we explore each pattern by looking at a minimalistic example to reveal its structure and then look at more concrete and useful real-world C# code that implements the pattern.
C# Design Patterns – Visitor Pattern
The Visitor pattern uses an external class to act on data in other classes. This is a useful approach to you when you have a polymorphic operation that cannot reside in the class hierarchy. Visitor is also a useful way to extend the behavior of a class hierarchy without the need to alter existing classes or to implement the new behavior in every subclass that requires it.
I think the visitor pattern feels a bit of a weird pattern. I mean weird in a way that it feels not very object-oriented nor structured way of programming. On the other hand, sometimes you have a collection of similar classes which differ in one or more methods. If you don’t want to ‘pollute’ your object-oriented hierarchy with these class-specific methods, then you can use the visitor pattern.
All the client needs is an object structure, a visitor and an element. One or more elements are attached to the object structure. The visitor visits the object structure and does ‘something’ with the attached elements.
class Client
{
static void Main()
{
ObjectStructure objectstructure = new ObjectStructure();
Element element = new ConcreteElement();
objectstructure.Attach(element);
ConcreteVisitor visitor = new ConcreteVisitor();
objectstructure.Accept(visitor);
Console.ReadKey();
}
}
The abstract class Visitor can have one or more concrete implementations, which do their work on the attached elements.
abstract class Visitor
{
public abstract void VisitConcreteElement(ConcreteElement concreteElement);
}
class ConcreteVisitor : Visitor
{
public override void VisitConcreteElement(ConcreteElement concreteElement)
{
Console.WriteLine("{0} visited by {1}", concreteElement.GetType().Name, this.GetType().Name);
}
}
The element class accepts a visitor and propagates an operation towards this visitor.
abstract class Element
{
public abstract void Accept(Visitor visitor);
}
class ConcreteElement : Element
{
public override void Accept(Visitor visitor)
{
visitor.VisitConcreteElement(this);
}
public void Operation()
{
}
}
The object structure contains all machinery needed for maintenance of a list of attached elements. In this way it resembles the subject class of the observer pattern.
class ObjectStructure
{
private List m_Elements = new List();
public void Attach(Element element)
{
m_Elements.Add(element);
}
public void Detach(Element element)
{
m_Elements.Remove(element);
}
public void Accept(Visitor visitor)
{
foreach (Element element in m_Elements)
{
element.Accept(visitor);
}
}
}
By now you should get some idea how the visitor pattern works.
Handy? I am not sure, I never used it in real life. What do you think. Please let me know.
This post is part of a series on the foundational design patterns in C#. In this series we explore the ancient design patterns and their use in real-world programming situations of today. In these series of posts we explore each pattern by looking at a minimalistic example to reveal its structure and then look at more concrete and useful real-world C# code that implements the pattern.
C# Design Patterns – Observer Pattern
The Observer pattern is intended to provide you with a means to present data in several different forms at once so that when one object changes state, all its dependents are notified and updated automatically.
The Observer pattern can be found everywhere. Mostly it is used when you have more than one view on the same data. For example, a list view and a detail view.
In the client, a couple of observers are attached to their subject of interest. As soon as the state of the subject changes, all observers are notified that there is a change of state.
class Client
{
static void Main()
{
ConcreteSubject subject = new ConcreteSubject();
ConcreteObserver observer1 = new ConcreteObserver(subject, "A");
subject.Attach(observer1);
ConcreteObserver observer2 = new ConcreteObserver(subject, "B");
subject.Attach(observer2);
subject.SubjectState = "NEW_SUBJECT_STATE";
subject.Notify();
Console.ReadKey();
}
}
The abstract parent class Subject contains a list of observers and methods necessary for attaching and detaching observers. Most important method is notify which traverses the list and notifies all attached observers.
abstract class Subject
{
private List m_Observers = new List();
public void Attach(Observer observer)
{
m_Observers.Add(observer);
}
public void Detach(Observer observer)
{
m_Observers.Remove(observer);
}
public void Notify()
{
foreach (Observer o in m_Observers)
{
o.Update();
}
}
}
The concrete child class contains a certain state, which can be virtually anything. In this example, something simple. Just a string containing im-por-tant information.
class ConcreteSubject : Subject
{
public string SubjectState { get; set; }
}
All observers need some way to update their state when they are notified. This is done by implementing the Update method of abstract class Observer.
abstract class Observer
{
public abstract void Update();
}
The concrete observer implements the abstract update method, plus its own methods.
class ConcreteObserver : Observer
{
private string m_Name;
private string m_ObserverState;
public ConcreteObserver(ConcreteSubject subject, string name)
{
this.Subject = subject;
this.m_Name = name;
}
public override void Update()
{
m_ObserverState = Subject.SubjectState;
Console.WriteLine("Observer {0}'s new state is {1}", m_Name, m_ObserverState);
}
public ConcreteSubject Subject { get; set; }
}
When you think about the problem this pattern solves, you probably agree with me that this is a relatively simple but powerful pattern.
This post is part of a series on the foundational design patterns in C#. In this series we explore the ancient design patterns and their use in real-world programming situations of today. In these series of posts we explore each pattern by looking at a minimalistic example to reveal its structure and then look at more concrete and useful real-world C# code that implements the pattern.
C# Design Patterns – Mediator Pattern
The Mediator pattern is intended to define an object that encapsulates how a set of objects interacts. Object do not communicate directly with eachother, but through a mediator. This reduces the dependencies between communicating objects.
The client instantiates the communicating objects, so called colleagues, and a mediator through which they are communicating.
Colleague c1 = new ConcreteColleague1(m); Colleague c2 = new ConcreteColleague2(m); Mediator m = new ConcreteMediator(); m.AddColleague(c1); m.AddColleague(c2); c1.Send(c2, "Hello, c2. Are you there?"); c2.Send(c1, "No, goodbye!");
The abstract class Colleague contains a Mediator, which is injected at instantiation. In this example, it has two methods for communication. One for sending a message, the other for receiving a message.
abstract class Colleague
{
protected Mediator mediator;
public Colleague(Mediator mediator)
{
this.mediator = mediator;
}
abstract public void Send(Colleague to, string message);
abstract public void Received(Colleague from, string message);
}
The abstract class Mediator contains an internal store for colleages and a method for adding colleagues. It also contains an abstract method for sending a message to the preferred colleague.
abstract class Mediator
{
protected List colleagues = new List();
public void AddColleague(Colleague colleague)
{
colleagues.Add(colleague);
}
public abstract void Send(Colleague colleague, string message);
}
The concrete class implements the abstract method. In this case, it forwards the message to the selected colleague.
class ConcreteMediator : Mediator
{
public override void Send(Colleague to, string message)
{
to.Received(to,message);
}
}
Finally, the selected concrete colleague receives the message. I only show the concrete class ConcreteColleague1, since ConcreteColleague2 is almost identical to this one. So if you want to try this code, I suggest you do a search and replace on ConcreteColleague1.
class ConcreteColleague1 : Colleague
{
public ConcreteColleague1(Mediator mediator)
: base(mediator) { }
override public void Send(Colleague to, string message)
{
Console.WriteLine("Sending message (ConcreteColleague1)-----------------------------");
Console.WriteLine("To : " + to.GetType().Name);
Console.WriteLine("Message: " + message);
Console.WriteLine();
mediator.Send(to,message);
}
override public void Received(Colleague from, string message)
{
Console.WriteLine("Receiving message (ConcreteColleague1)---------------------------");
Console.WriteLine("From : " + from.GetType().Name);
Console.WriteLine("Message: " + message);
Console.WriteLine();
}
}
This post is part of a series on the foundational design patterns in C#. In this series we explore the ancient design patterns and their use in real-world programming situations of today. In these series of posts we explore each pattern by looking at a minimalistic example to reveal its structure and then look at more concrete and useful real-world C# code that implements the pattern.
C# Design Patterns – Iterator Pattern
The iterator pattern provides a client with a way to access the elements of an aggregate object sequentially without having to know the underlying representation. The iterator is especially useful because it provides the client with a common interface so it doesn’t need to know anything about the underlying data structure.
If you want to loop through an collection of elements, the iterator pattern comes in very handy. In this example the client first fills an aggregate object with string elements. Next, an iterator is instantiated with the collection. Last, the iteration is done. The fun part is that you can change the implementations of underlying data and iterator without having to change the client.
Aggregate aggregate = new ConcreteAggregate();
for (int i = 0; i < 5; i++)
{
aggregate[i] = string.Format("listitem {0}", i);
}
Iterator iterator = new ConcreteIterator(aggregate);
Console.WriteLine("Items in list:\n");
object item = iterator.First();
while (item != null)
{
Console.WriteLine(item);
item = iterator.Next();
}
The abstract aggregate class its most important abstract method is CreateIterator. For convenience of this example, an indexer and a property Count are also defined. The concrete aggregate object is just a wrapper around an ordinary ArrayList.
abstract class Aggregate
{
public abstract object this[int i] { get; set; }
public abstract int Count { get; }
public abstract Iterator CreateIterator();
}
class ConcreteAggregate : Aggregate
{
private ArrayList m_Items = new ArrayList();
public override Iterator CreateIterator()
{
return new ConcreteIterator(this);
}
public override int Count
{
get
{
return m_Items.Count;
}
}
public override object this[int index]
{
get
{
return m_Items[index];
}
set
{
m_Items.Insert(index, value);
}
}
}
The iterator does the looping work. First, an aggregate object is injected into the iterator upon instantiation. The rest of the code is just implementation of all abstract members.
class ConcreteIterator : Iterator
{
private Aggregate m_Aggregate;
private int m_Index = 0;
public ConcreteIterator(Aggregate aggregate)
{
this.m_Aggregate = aggregate;
}
public override object First()
{
return m_Aggregate[0];
}
public override object Next()
{
object result = null;
if (m_Index < m_Aggregate.Count - 1)
{
result = m_Aggregate[++m_Index];
}
return result;
}
public override object CurrentItem()
{
return m_Aggregate[m_Index];
}
public override bool IsDone()
{
return m_Index >= m_Aggregate.Count;
}
}
Knowing this, can you imagine a real world situation when to use this pattern? This is such an important pattern, that it is a built-in pattern in C#. If you want read more about use of this pattern, read Using the Iterator Pattern in C# ASP .NET, by Kory Becker
This post is part of a series on the foundational design patterns in C#. In this series we explore the ancient design patterns and their use in real-world programming situations of today. In these series of posts we explore each pattern by looking at a minimalistic example to reveal its structure and then look at more concrete and useful real-world C# code that implements the pattern.
C# Design Patterns – Memento Pattern
The Memento pattern provides you with the ability to restore an object to its previous state (undo by rollback).
The Memento pattern can have different purposes, but above all is known as the Undo Pattern. If you are mentally in an object oriented mood you could ask yourself…
Why on earth and above want they to put the internal data outside of the class in question? That’s not data hiding, is it?
… but the truth is that memento pattern doesn’t violate encapsulation of the internal state.
As a consequence, this pattern can come very handy when you want to store its internal state and reclaim it later without knowledge of the original object.
The client creates an originator object, which has a certain internal state. This can be any object, of course. The important objects are the caretaker and memento. A memento is created by the originator and stored in the caretaker. At a later point in time the previous state can be restored by setting the originators memento to the caretaker’s stored memento.
class Client
{
public static void Run()
{
Originator originator = new Originator();
originator.State = "First state";
// a memento is created and stored
Caretaker caretaker = new Caretaker();
caretaker.Memento = originator.CreateMemento();
// change the internal state of the originator object
originator.State = "Second state";
Console.WriteLine("Restoring previous state.");
originator.SetMemento(caretaker.Memento);
}
}
The originator object can be any object, as long as they implement a CreateMemento and SetMemento method. The CreateMemento method should return a filled memento object, whilst the SetMemento should read the data stored in the memento and restore its internal state.
class Originator
{
private string m_State;
public string State
{
get { return m_State; }
set
{
m_State = value;
Console.WriteLine("current state = {0}", m_State);
}
}
public Memento CreateMemento()
{
return (new Memento(State));
}
public void SetMemento(Memento memento)
{
State = memento.State;
}
}
The Memento object contains the originators internal state, so must have a similar structure. To design a Memento class you could start with a copy of the originator class and strip all unnecessary methods and attributes.
class Memento
{
private string m_State;
public Memento(string state)
{
this.m_State = state;
}
public string State
{
get { return m_State; }
}
}
The Caretaker only contains the memento. In this example there is just one memento, but normally the caretaker contains a list of mementos.
class Caretaker
{
public Memento Memento;
}
And of course, you can click here for a simplified
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
enum ArticleStatus
{
Draft,
PendingReview,
Published
}
class Client
{
static void Run(string[] args)
{
// initial state
Article article = new Article();
article.Status = ArticleStatus.Draft;
// save state
StatusStore store = new StatusStore();
store.StoredStatus = article.CreateStoredStatus();
// user pressed the publish button
article.Status = ArticleStatus.Published;
article.Save();
// user presse the undo button
article.RestoreToPreviousState(store.StoredStatus);
article.Save();
}
}
class Article
{
private ArticleStatus m_State;
public ArticleStatus Status
{
get { return m_State; }
set
{
m_State = value;
}
}
public void Save()
{
// persisting logic
}
public ArticleState CreateStoredStatus()
{
return (new ArticleState(Status));
}
public void RestoreToPreviousState(ArticleState memento)
{
Status = memento.State;
}
}
class ArticleState
{
private ArticleStatus m_State;
public ArticleState(ArticleStatus state)
{
this.m_State = state;
}
public ArticleStatus State
{
get { return m_State; }
}
}
class StatusStore
{
public ArticleState StoredStatus;
}
This post is part of my series on the foundational design patterns in C#. In this series I explore the ancient design patterns and their use in real-world programming situations of today. In these series of posts we explore each pattern by looking at a minimalistic example to reveal its structure and then look at more concrete and useful real-world C# code that implements the pattern.
C# Design Patterns – Chain of Responsibility Pattern
The Chain of Responsibility is intended to promote loose coupling between the sender of a request and its receiver by giving more than one object an opportunity to handle the request. The receiving objects are chained and pass the request along the chain until one of the objects handles it.
What I like about this pattern is the chaining part. If the first handler cannot handle the request, the second one will. Or the third, fourth, or … And you only have to call the first handler of the chain.
You must be aware that if you want to use this pattern you should be very keen on exception handling, because the major drawback of this pattern is the possibility that the chain breaks.
And you probably heard this before:
A chain is only as strong as its weakest link
This also holds true for the chain of responsibility pattern. If one handler doesn’t do its work right the working of the following handlers are possibly compromised, which is especially important if the handler is one of the first components in the chain.
The client creates the chain by linking the handlers and does its request to the first handler in the chain, that’s it.
class Client
{
static void Main()
{
Handler handler1 = new ConcreteHandler1();
Handler handler2 = new ConcreteHandler2();
handler1.SetSuccessor(handler2);
handler1.HandleRequest(1);
handler1.HandleRequest(2);
Console.ReadKey();
}
}
As is the case in most design patterns, there is an abstract class. The abstract class Handler defines SetSuccessor, which is responsible for the actual chaining.
abstract class Handler
{
protected Handler m_Successor;
public void SetSuccessor(Handler successor)
{
this.m_Successor = successor;
}
public abstract void HandleRequest(int request);
}
The concrete class implements the actual handling of the request.
// first concrete Handler
class ConcreteHandler1 : Handler
{
public override void HandleRequest(int request)
{
Console.Write("Request {0} is handled by Handler1", request);
if (request == 1)
{
Console.WriteLine();
}
else if (m_Successor != null)
{
Console.Write("->");
m_Successor.HandleRequest(request);
}
}
}
// second concrete Handler
class ConcreteHandler2 : Handler
{
public override void HandleRequest(int request)
{
Console.Write("Handler2");
if (request == 2)
{
Console.WriteLine();
}
else if (m_Successor != null)
{
Console.Write("->");
m_Successor.HandleRequest(request);
}
}
}
I also have included a real world example, a message handler which can handle different versions of requests. The first link in the chain handles version 1, the second version 2, and so forth…
Click here for a simplified
class Client
{
static void Main()
{
MessageHandler handler1 = new MessageHandler_v1();
MessageHandler handler2 = new MessageHandler_v2();
handler1.SetSuccessor(handler2);
handler1.HandleRequest("..");
handler1.HandleRequest("..");
Console.ReadKey();
}
}
abstract class MessageHandler
{
protected MessageHandler m_Successor;
public void SetSuccessor(MessageHandler successor)
{
this.m_Successor = successor;
}public abstract void HandleRequest(Request request);
}
class MessageHandler_v1 : MessageHandler
{
public override void HandleRequest(Request request)
{
if (request.version == 1)
{
// Handle message
}
else if (m_Successor != null)
{
m_Successor.HandleRequest(request);
}
}
}
class MessageHandler_v2 : MessageHandler
{
public override void HandleRequest(Request request)
{
if (request.version == 1)
{
// Handle message
}
else if (m_Successor != null)
{
m_Successor.HandleRequest(request);
}
}
}
This post is part of my series on the foundational design patterns in C#. In this series we explore the ancient design patterns and their use in real-world programming situations of today. In these series of posts we explore each pattern and look at simplified real-world C# code that implements the pattern.
C# Design Patterns – Template Pattern
The Template Design Pattern is used to set up the outline or skeleton of an algorithm, leaving the details to specific implementations later. This way, subclasses can override parts of the algorithm without changing its overall structure.
The template pattern is a relatively simple pattern. You can use it when you have some similar classes with only minor differences and it is possible to isolated the differences into one method while the shared similarities are provided by the base class. Using the template pattern the client only has to instantiate the concrete class and call the desired template method.
class Client
{
static void Main()
{
AbstractClass template = new ConcreteClass();
template.TemplateMethod();
Console.ReadKey();
}
}
The abstract class contains a template method which calls an abstract operation which is defined in the base class and implemented in the concrete class.
abstract class AbstractClass
{
public void TemplateMethod()
{
Operation1();
}
protected abstract void Operation1();
}
The concrete class overrides the abstract method of the base class.
class ConcreteClass : AbstractClass
{
override protected void Operation1()
{
Console.WriteLine("Operation1 within ConcreteClass");
}
}
Thus, the client calls a template method of the base class which calls a method of a concrete class.
Click here for a simplified
class Client
{
static void Main()
{
MessagePacker template = new XmlMessagePacker();
string message = template.CreateMessage("User324", "Hello, user.");
Console.WriteLine(message);
Console.ReadKey();
}
}
abstract class MessagePacker
{
public string CreateMessage(string to, string message)
{
return Pack(to, message);
}
protected abstract string Pack(string to, string message);
}
class XmlMessagePacker : MessagePacker
{
override protected string Pack(string to, string message)
{
return string.Format("{0}{1}", to, message);
}
}
This post is part of a series on the foundational design patterns in C#. In this series we explore the ancient design patterns and their use in real-world programming situations of today. In these series of posts we explore each pattern by looking at a minimalistic example to reveal its structure and then look at more concrete and useful real-world C# code that implements the pattern.
C# Design Patterns – Interpreter Pattern
The Interpreter pattern is intended to provide you with a way to define representation of the grammar of a language whith an interpreter that uses the representation to interpret sentences in the language.
Some applications provide support for built-in scripting and macro languages so users can describe operations they can perform in the application. If this ability is what you want, then I am sorry to inform you: please use one of the many scripting engines available, for example CS-Script – The C# Script Engine.
The interpreter pattern is especially useful for parsing algorithmic expressions, but it is also very useful for interpretation of small strings containing foreign code. On the net you can find an abundance of examples that use the interpreter pattern for conversion of a Roman numeral to a decimal.
Nice as it is, but instead of ruminating the Roman example we will apply the interpreter pattern for conversion of binary code to decimal.
All you have to do in the client is to construct an interpretation tree, and later on to walk the tree with the provided context. The context contains all necessary information that is global to the interpreter.
class Client
{
static void Main()
{
string input = "00100011";
Context context = new Context(input);
// Construct interpretation tree
ArrayList list = new ArrayList();
for (int i = 0; i < input.Length; i++) list.Add(new TerminalExpression());
// Interpret
foreach (AbstractExpression expression in list)
{
expression.Interpret(context);
}
Console.WriteLine("interpret {0} = {1}", input, context.Output);
Console.ReadKey();
}
}
In our case, the context contains a binary input and a decimal output. I know, these should be properties instead of global variables. So you should refactor them.
class Context
{
public string Input;
public int Output;
public Context(string input)
{
this.Input = input;
}
}
The base class AbstractExpression is the mother of all expressions. Maybe you should refactor it to an interface. In this example it contains one abstract method which receives the context.
abstract class AbstractExpression
{
public abstract void Interpret(Context context);
}
As always the concrete class does all the work, conversion of binary code to decimal. It’s no rocket science, but nicely shows how this pattern works.
class TerminalExpression : AbstractExpression
{
public override void Interpret(Context context)
{
int power = context.Input.Length - 1;
if (context.Input.StartsWith("1"))
{
context.Output += (int)Math.Pow(2, power );
} context.Input = context.Input.Remove(0, 1);
}
}
At this point you probably are thinking: Hey, where is the NonTerminalExpression? Honestly, I tried to use it in the example, but the example became a little bit to complex. So I purged it. On the other hand, you probably would not use it very often in real world situations, except for building a calculator.
The expression "5*(3+2)" contains the nonterminal expression "(3+2)". You could rewrite the expression like this:
a=3+2; 5*a;
If you want to try this yourself and incorporate a nonterminal expression, be my guest. I will wait right here for you. See you later, then.
This post is part of my series on the foundational design patterns in C#. In this series we explore the ancient design patterns and their use in real-world programming situations of today. In these series of posts we explore each pattern and look at simplified real-world C# code that implements the pattern.















