Pages: Prev 1 2 3 4 5 6 7 Next
– page 6

Agile & Lean Software Development Management

deep thoughts on doing real work

The Composite pattern is intended to allow you to compose tree structures to represent whole-part hierarchies so that clients can treat individual objects and compositions of objects uniformly.

image

When I hear "composite pattern", immediately XML pops up in my mind. A composite is an element and a leaf is an attribute.

<composite>
    <composite leaf="value">
        Important Text
    </composite>
</composite>

The client creates the root of the tree and adds composites and leafs. Next an operation can be performed on the complete tree by calling the method on the root. Thereafter the operation is ‘automagically’ called recursively.

class Client
{
    static void Main(string[] args)
    {
        Composite root = new Composite("composite1");
        // add a leaf root.Add(new Leaf("leaf1"));
        //example of removing a leaf Leaf leaf = new Leaf("leaf2");
        root.Add(leaf);
        root.Remove(leaf);
        root.Add(new Leaf("leaf3"));
        //adding another composite Composite comp = new Composite("composite2");
        comp.Add(new Leaf("leaf1"));
        root.Add(comp);
        // recursively operation int depth = 1;
        root.Operation(depth);
        Console.ReadKey();

    }
}

The key of this pattern is the abstract class Component, which is the parent of the composite object and leaf. It defines a property and an operation. It also has methods for adding and removing objects from the tree. These methods are not necessary, but – indeed – very convenient.

abstract class Component
{
    protected string name;
    public Component(string name)
    {
        this.name = name;
    }
    public abstract void Add(Component component);
    public abstract void Remove(Component component);
    //this is the key operation
    public abstract void Operation(int depth);
}

The composite is the concrete class which implements all methods of the abstract parent class, thus can contain another composite or leaf.

class Composite : Component
{
    private List m_Children = new List();

    // Constructor
    public Composite(string name) : base(name) { }

    public override void Add(Component component)
    {
        m_Children.Add(component);
    }

    public override void Remove(Component component)
    {
        m_Children.Remove(component);
    }

    public override void Operation(int depth)
    {
        if (depth > 1) Console.WriteLine(">");
        Console.Write(new String(' ', depth) + string.Format("< {0}", name));

        // Recursively display child nodes
        foreach (Component component in m_Children)
        {
            component.Operation(depth + 2);
        }
        Console.WriteLine(">");

        Console.Write(new String(' ', depth) + string.Format("< {0}", name));

        if (depth == 1) Console.WriteLine(">");
    }
}

The leaf, on the other hand, is a crippled implementation of the abstract parent class. It cannot contain other parts, it is an endpoint.

In this example, a xml-structure is created and the method Operation is use to display itself. Therefore, Display() would be a better name. Maybe we should refactor it.

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.

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.

image

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.

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.

image

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.

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.

image

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.

The Abstract Factory pattern provides a way to encapsulate a group of individual factories that have a common theme.

image

In normal usage, the client software would create a concrete implementation of the abstract factory and then use the generic interfaces to create the concrete objects that are part of the theme. The client does not know (or care) about which concrete objects it gets from each of these internal factories since it uses only the generic interfaces of their products. This pattern separates the details of implementation of a set of objects from its general usage.

It sounds all a bit complex to you, don’t worry. In fact, it is really simple. Think about database access in general. There you have a whole bunch of database specific commands, for example SqlConnection, SqlCommand, etc. for SQL Server. For Oracle you have OracleConnection and OracleCommand. And surrise, for ODBC you have OdbcConnection and OdbcCommand. These all have the same parent, DbConnection and DbCommand, respectively.

This can be summarized as follows:

Base class SQL Server Oracle Odbc
DbConnection SqlConnection OracleConnection OdbcConnection
DbCommand SqlCommand OracleCommand OdbcCommand
DbDataReader SqlDataReader OracleDataReader OdbcDataReader

Mostly, I use a SQL Database. This corresponds with the following code:

DbConnection cnn = new SqlConnection("server=(local); ...");
DbCommand cmd = new SqlCommand("");
DbDataReader rd;

using (cnn)
{
    cmd.Connection = cnn;
    cnn.Open();
    rd = cmd.ExecuteReader();
    while (rd.Read())
    {
        string Name = rd["Name"].ToString();
    }
    cnn.Close();
}

Need I say more?

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.

The Decorator pattern is intended to give you a way to extend the behavior of an object or to dynamically compose an object’s behavior at runtime.

image

The Decorator Pattern is used for adding additional functionality to a particular object as opposed to a class of objects. It is easy to add functionality to an entire class of objects by subclassing an object, but it is impossible to extend a single object this way. With the Decorator Pattern, you can add functionality to a single object and leave others like it unmodified.

Decorators provide a flexible alternative to subclassing for extending functionality.

Code examples (click to enlarge/collapse):

  1. class Client
    {
        static void Main()
        {
            Console.WriteLine("Concrete Component -> Message");
            Component component = new ConcreteComponent();
            component.Operation();
            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine("Decorator -> Simple decoration");
            Decorator decorator = new ConcreteDecorator();
            decorator.SetComponent(component);
            decorator.Operation();
            Console.ReadKey();
    
        }
    }
    public class Decorator : Component
    {
        public Component component;
        public void SetComponent(Component component)
        {
            this.component = component;
    
        }
        public override void Operation()
        {
            if (component != null)
            {
                component.Operation();
    
            }
        }
    }
    public class ConcreteDecorator : Decorator
    {
        public override void Operation()
        {
            Console.WriteLine("*****************");
            Console.Write("* ");
            base.Operation();
            Console.WriteLine(" *");
            Console.WriteLine("*****************");
    
        }
    }
    public abstract class Component
    {
        public abstract void Operation();
    
    }
    public class ConcreteComponent : Component
    {
        public override void Operation()
        {
            Console.Write("Hello, world!");
        }
    }
  • class Client
    {
        static void Main()
        {
            Message msg = new TextMessage();
            msg.Value = "Hello, world.";
            Formatter formatter = new XmlFormatter();
            formatter.LoadMessage(msg);
            string result = formatter.ToString();
            Console.WriteLine("Formatted message: {0}", result);
            Console.ReadKey();
        }
    }
    
    public class Formatter : Message
    {
        public Message component;
        public void LoadMessage(Message component)
        {
            this.component = component;
        }
    
        public override string ToString()
        {
            if (component != null)
            {
                return component.ToString();
            }
            else return null;
        }
    }
    
    public class XmlFormatter : Formatter
    {
        public override string ToString()
        {
            return string.Format("{0}", base.ToString());
        }
    }
    
    public abstract class Message
    {
        public string Value;
        public new abstract string ToString();
    }
    
    public class TextMessage : Message
    {
        public override string ToString()
        {
            return this.Value;
        }
    }
  • 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.

    The Command pattern is intended to encapsulate a request as an object. A Command object encapsulates an action and its parameters. It is useful for implementing transactional behavior or a simple workflow.

    image

    Code examples (click to enlarge/collapse):

    1. public class Client
      {
          public static void Run()
          {
              Receiver receiver = new Receiver();
              Command command = new ConcreteCommand(receiver);
              Invoker invoker = new Invoker(command);
              invoker.DoAction();
          }
      }
      
      public abstract class Command
      {
          public abstract void Execute();
      }
      
      public class ConcreteCommand : Command
      {
          Receiver m_Receiver;
      
          public ConcreteCommand(Receiver receiver)
          {
              this.m_Receiver = receiver;
          }
      
          public override void Execute()
          {
              m_Receiver.Action();
          }
      }
      
      public class Invoker
      {
          private Command m_Command;
      
          public Invoker(Command command)
          {
              this.m_Command = command;
          }
      
          public void DoAction()
          {
              m_Command.Execute();
          }
      }
      
      public class Receiver
      {
          public void Action()
          {
              Console.WriteLine("Action performed");
          }
      }

    1. public class Client
      {
          public static void Run()
          {
              PaymentProcessor processor = new PaymentProcessor();
              IPaymentCommand action = new DoPaymentAction(processor);
              PaymentTransaction trans = new PaymentTransaction(action);
              PaymentRequest request = new PaymentRequest();
      
              request.Amount = 25.33;
              ProcessPaymentRequest(trans, request);
      
              request.Amount = -5.75;
              ProcessPaymentRequest(trans, request);
          }
      
          private static void ProcessPaymentRequest(PaymentTransaction trans, PaymentRequest request)
          {
              try
              {
                  trans.DoPayment(request);
                  trans.Commit();
              }
              catch (ActionFailedException)
              {
                  trans.Rollback();
              }
              Console.WriteLine();
          }
      }
      
      public class ActionFailedException : Exception
      {
      }
      
      public class PaymentRequest
      {
          double m_Amount;
      
          public double Amount
          {
              get { return m_Amount; }
              set { m_Amount = value; }
          }
      }
      
      public interface IPaymentCommand
      {
          void DoPayment(PaymentRequest request);
          void Rollback();
          void Commit();
      }
      
      public class DoPaymentAction : IPaymentCommand
      {
          private PaymentProcessor m_Receiver;
          public DoPaymentAction(PaymentProcessor receiver)
          {
              m_Receiver = receiver;
          }
      
          public void DoPayment(PaymentRequest arg)
          {
              m_Receiver.Action(arg);
          }
      
          public void Rollback()
          {
              m_Receiver.RollBack();
          }
      
          public void Commit()
          {
              m_Receiver.Commit();
          }
      }
      
      public class PaymentTransaction
      {
          private IPaymentCommand m_task;
          public PaymentTransaction(IPaymentCommand task)
          {
              m_task = task;
          }
      
          public void DoPayment(PaymentRequest arg)
          {
              m_task.DoPayment(arg);
          }
      
          public void Rollback()
          {
              m_task.Rollback();
          }
          public void Commit()
          {
              m_task.Commit();
          }
      }
      
      public class PaymentProcessor
      {
          double m_OriginalAmount;
          double m_CurrentAmount;
          double m_ProposedAmount;
      
          public void Action(PaymentRequest arg)
          {
              m_OriginalAmount = arg.Amount;
      
              m_ProposedAmount = m_OriginalAmount * 2.5245;
              Console.WriteLine("Calculated result: {0} * ? = {1} ", m_OriginalAmount, m_ProposedAmount);
      
              if (m_ProposedAmount < 0) throw new ActionFailedException();
          }
      
          public void RollBack()
          {
              m_CurrentAmount = m_OriginalAmount;
              Console.WriteLine("RollBack, result = {0}", m_CurrentAmount);
          }
      
          public void Commit()
          {
              m_CurrentAmount = m_ProposedAmount;
              Console.WriteLine("Commit,result = {0}", m_CurrentAmount);
          }
      }

    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.

    Design Patterns

    C# Design Patterns – Adapter Pattern

    No comments

    The Adapter pattern is intended to provide a way to use an object whose interface is different from the on expected by the client, without having to modify either.

    image

    There are two ways to create an adapter: by inheritance or by object composition. In the first case, which generally is considered best practice, we derive a class from the adaptee and add the expected methods to match the desired interface. In the other case, we include the adaptee inside the adapter and create methods to to translate the calls within the adapter.

    Code examples (click to enlarge/collapse):

    1. public class Client
      {
          static public void Run()
          {
              Console.WriteLine("Running AdapterSimple");
              Target adapter = new Adapter();
              adapter.Request();
      
              Console.ReadKey();
          }
      }
      
      class Adapter : Target
      {
          public Adaptee adaptee;
      
          public override void Request()
          {
              Console.WriteLine(" Calling->Adapter.Request");
              adaptee = new Adaptee();
              adaptee.SpecificRequest();
          }
      }
      
      abstract class Target
      {
          abstract public void Request();
      }
      
      class Adaptee
      {
          public void SpecificRequest()
          {
              Console.WriteLine(" Calling->Adaptee.SpecificRequest");
          }
      }

    1. public class Client
      {
          static public void Run()
          {
              PaymentRequestBase payment = new PaymentRequest();
              payment.DoPaymentRequest(10);
              Console.ReadKey();
          }
      }
      
      class PaymentRequest : PaymentRequestBase
      {
          public PaymentService service;
      
          public override void DoPaymentRequest(int amount)
          {
              service = new PaymentService();
              service.ProcessPayment(amount);
          }
      }
      
      abstract class PaymentRequestBase
      {
          abstract public void DoPaymentRequest(int amount);
      }
      
      class PaymentService
      {
          public void ProcessPayment(int amount)
          {
              Console.WriteLine("Processed payment of EUR {0},=.", amount);
          }
      }

    The Adapter pattern thus is really simple, so both examples are pretty straightforward. The examples above use object composition, since object composition is more often used than by inheritance. Any idea why?

    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.

    Design Patterns

    C# Design Patterns – Factory Method Pattern

    No comments

    The factory method pattern  deals with the problem of creating objects without specifying the exact class of object that will be created.

    image

    The factory method design pattern handles this problem by defining a separate method for creating the objects, whose subclasses can then override to specify the derived type  that will be created.

    More generally, the term factory method is often used to refer to any method whose main purpose is creation of objects.

    Code examples (click to enlarge/collapse):

    1. using System;
      namespace HvD.FactoryMethod
      {
          class Program
          {
              static void Main(string[] args)
              {
                  // Pesky user interface
                  Console.WriteLine("Choose a product:");
                  Console.WriteLine("1) Concrete Product 1");
                  Console.WriteLine("2) Concrete Product 2");
                  int input = int.Parse(Console.ReadLine());// the real stuff
                  Creator creator = new ConcreteCreator();
                  Product product = creator.FactoryMethod(input);
                  string productName = product.ProductName;//
                  Console.WriteLine("Product name = {0}", productName);
                  Console.ReadKey();
              }
          }
          public abstract class Product
          {
              protected string m_ProductName = "BaseProduct";
              public string ProductName
              {
                  get { return m_ProductName; }
                  set { m_ProductName = value; }
              }
          }
          public class ConcreteProduct1 : Product
          {
              public ConcreteProduct1()
              {
                  m_ProductName = "ConcreteProduct1";
              }
          }
          public class ConcreteProduct2 : Product
          {
              public ConcreteProduct2()
              {
                  m_ProductName = "ConcreteProduct2";
              }
          }
          public abstract class Creator
          {
              public abstract Product FactoryMethod(int ProductType);
          }
          public class ConcreteCreator : Creator
          {
              public override Product FactoryMethod(int ProductType)
              {
                  switch (ProductType)
                  {
                      case 1:
                          return new ConcreteProduct1();
                      case 2:
                          return new ConcreteProduct2();
                      default:
                          return null;
                  }
              }
          }
      }

    2. using System;
      namespace HvD.FactoryMethod
      {
          class Program
          {
              static void Main(string[] args)
              {
                  // Pesky user interface
                  Console.WriteLine("Enter your full name:");
                  string fullname = Console.ReadLine();// the real stuff
                  Creator creator = new NamerCreator();
                  Namer namer = creator.CreateNamer(fullname);
                  string firstName = namer.FirstName;
                  string lastName = namer.LastName;//
                  Console.WriteLine("First name = {0}", firstName);
                  Console.WriteLine("Last name = {0}", lastName);
                  Console.ReadKey();
              }
          }
          public abstract class Creator
          {
              public abstract Namer CreateNamer(string fullname);
          }
          public class NamerCreator : Creator
          {
              public override Namer CreateNamer(string fullname)
              {
                  if (fullname.IndexOf(',') < 0)
                  {
                      return new FirstNameFirst(fullname);
                  }
                  else
                  {
                      return new LastNameFirst(fullname);
                  }
              }
          }
          public abstract class Namer
          {
              protected string m_FirstName = null;
              public string FirstName
              {
                  get { return m_FirstName; }
                  set { m_FirstName = value; }
              }
              protected string m_LastName = null;
              public string LastName
              {
                  get { return m_LastName; }
                  set { m_LastName = value; }
              }
          }
          public class FirstNameFirst : Namer
          {
              public FirstNameFirst(string fullname)
              {
                  int index = fullname.IndexOf(' ');
                  m_FirstName = fullname.Substring(0, index);
                  m_LastName = fullname.Substring(index + 1);
              }
          }
          public class LastNameFirst : Namer
          {
              public LastNameFirst(string fullname)
              {
                  int index = fullname.IndexOf(',');
                  m_FirstName = fullname.Substring(index + 2);
                  m_LastName = fullname.Substring(0, index);
              }
          }
      }

    The real world example is my favourite example using a Namer factory class. Depending on how you provide your full name (First-Name-First or Last-Name-First) your first name and last name are extracted from your full name. Using this pattern you can easily add other name patterns, for example how to handle middle names.

    With this foundation you should be able to successfully implement the Factory Method Pattern.

    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 – Proxy Pattern

    No comments

    The Proxy pattern is intended to provide you with a simple placeholder that takes the place of a more complex object  that may be invoked later. It  is a kind of "wrapper" that delegates to the real object.

    image

    The Proxy pattern is especially useful for situations where object creation is a time consuming process, and you do not want to instantiate such an object unless and until it is actually requested by the client. This is also known as the "lazy loading" principle.

    Code examples (click to enlarge/collapse):

    1. class Program
      {
          static void Main(string[] args)
          {
              Proxy proxy = new Proxy();
              proxy.Request(); Console.ReadKey();
          }
      }
      
      public class Proxy : Subject
      {
          private RealSubject m_RealSubject;
      
          public override void Request()
          {
              Console.WriteLine("I am proxy doing a 'lazy load'");
              if (m_RealSubject == null)
              {
                  m_RealSubject = new RealSubject();
              }
              m_RealSubject.Request();
          }
      }
      
      public abstract class Subject
      
      {
          public abstract void Request();
      }
      
      public class RealSubject : Subject
      {
          public override void Request()
          {
              Console.WriteLine(".. and I am the real subject.");
          }
      }

    2. using System;
      class Program
      {
          static void Main(string[] args)
          {
              Employee employee = new Employee(); Console.WriteLine("Employee name: {0}", employee.EmployeeName);
              Console.WriteLine("Manager name : {0}", employee.Manager.ManagerName); Console.WriteLine("Loading manager..");
              employee.Manager.Load();
              Console.WriteLine("Manager name: {0}", employee.Manager.ManagerName);
              Console.ReadKey();
          }
      }
      
      public class Employee
      {
          public string EmployeeName = "Employee";
          public Manager Manager = new Manager();
      }
      
      public class Manager : ManagerBase
      {
          private RealManager m_RealSubject;
          public override void Load()
          {
              if (m_RealSubject == null)
              {
                  m_RealSubject = new RealManager();
              }
              m_RealSubject.Load();
              ManagerName = m_RealSubject.ManagerName;
          }
      }
      
      public abstract class ManagerBase
      {
          public string ManagerName = "Unknown";
          public abstract void Load();
      }
      
      public class RealManager : ManagerBase
      {
          public override void Load()
          {
              ManagerName = "Manager";
          }
      }


    In the simplified real world example you have two related entities Employee and Manager. Imagine both entities should be retrieved from the database. Image also that the manager has a manager, which has a manager, which has a … Before you know it, you have retreived the whole company from the database. That is not what you want, you only want to access some of the attributes of the employee and not the manager. If you want to access the employee’s manager, you have to load it explicitly.

    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.

    Pages: Prev 1 2 3 4 5 6 7 Next