Thursday, January 24, 2008

Design Patterns - Observer Pattern

Introduction

This article explains the Observer patterns which is one of the C# Design Patterns, the article provides a very simple implementation so its complexity can be easily understood.

The observer pattern makes an object that if its state changed somehow, other instances will be notified (or updated) automatically, In other words, it is used to keep track of many objects.
observer
Implementation

Imagine if we have cards game, some tables, and some players..
On a table.., in the game context the suit of cards is changed time by time and we want to notify the players each time the
suit is changed.

Note* this is not a complete logic for a cards game, its an example.

The player object is going to have a function Update() which will be called by the notifier, and data:
  • Player Number (Player Identity) int

  • Current Suit string

  • Current Table Object Table



How can the player be notified? we pass the (always changes) object of the table as a parameter in the Update() function,
So the player (object) can see the new differences in the table (object).

This is the Player object..

interface IPlayer
{
void Update(Table _table);
}

class Player : IPlayer
{

public void Update(Table _table)
{
this._table = _table;
_currentSuit = _table.currentSuit;
Console.WriteLine("Player '" + _PlayerNo + "' notified that current suit is " + _currentSuit);
}

private int _PlayerNo;
private Table _table;
private string _currentSuit;

public Player(int _PlayerNo)
{
this._PlayerNo = _PlayerNo;
}

public Table CurrentTable
{
get { return _table; }
}

}



In our table object you want to add players or remove players (or count them for some reasons..)
So in the table object you'll have:
  • An array list of the players objects List<>

  • Current Suit string

  • Table Number int

  • Add Player Function AddPlayer()

  • Remove Player Function RemovePlayer()

  • Notify Function Notify()



The notify function is sending the updated object (table) to all players objects..


abstract class Table
{
private string _currentSuit;
private int _tableNo;
private List<> players = new List<>();

public Table(int _tableNo, string _currentSuit)
{
this._tableNo = _tableNo;
this._currentSuit = _currentSuit;
}
public void AddPlayer(Player _player)
{
players.Add(_player);
}

public void RemovePlayer(Player _player)
{
players.Remove(_player);
}

public string currentSuit
{
get { return _currentSuit; }
set
{
_currentSuit = value;
Notify();
}
}

public void Notify()
{
foreach (Player _player in players)
{
_player.Update(this);
}
}
}

class ReadyTable : Table
{
public ReadyTable(int _tableNo, string _currentSuit) : base(_tableNo, _currentSuit)
{ }
}



And the Main()

class Program
{
static void Main(string[] args)
{
//Create Table
ReadyTable table = new ReadyTable(1, "Spade");
Console.WriteLine("Starting table 1 with suit spades, suit will be changing in 3 seconds");

//Create Players
List players = new List(4);
for (int i = 0; i < 4; i++)
{
players.Add(new Player(i));
table.AddPlayer(players[i]);
}

Thread.Sleep(3000);
//Change the suit and all players will be notified
table.currentSuit = "Hearts";

Thread.Sleep(6000);
table.currentSuit = "Diamonds";

Console.ReadLine();
}
}

Design Patterns - The Factory Method

Introduction


This article explains the Factory Method Pattern, which is one of the C# Design Patterns.

This pattern gives you the ability to create a factory (instance) that will instantiate many relatedobjects.



When to use the Factory Method?

  • A class can’t anticipate which kind of class of objects it must create.

  • A class uses its subclasses to specify which objects it creates.

  • You want to localize the knowledge of which class gets created.


Cooper - Introduction to Design Patterns in C#



You can think of this like if you have some different implementation for 1 parent object, and
then you have some other different creators for these instances.., so we will have a factory
that decides what creators and decide what instances does every creator instantiate.

The Pattern



Imagine we have a class called Message that sends some contents through the Send() function.

And we have some types of messages (Email, sms, .. etc.) each of which has a special implementation
of the send() function.

Now how to decide which type (instance) of message we will send if using a cell phone or a PC?

So, this means we have different machines (cell, PC, Laptop..), and each machine will instantiate
specific types of messages.


Message



  • The best way is to make an abstract class called Message and include an abstract method called Send(), So
    we can easily implement it.

    abstract class Message
    {
    abstract public void Send();
    }

  • Example of different implementations..

    class Email : Message
    {
    public override void Send()
    {
    Console.WriteLine(this.GetType().Name);
    }
    }
    class VoiceMail : Message
    {
    public override void Send()
    {
    Console.WriteLine(this.GetType().Name);
    }
    }
    class SMS : Message
    {
    public override void Send()
    {
    Console.WriteLine(this.GetType().Name);
    }
    }
    class MMS : Message
    {
    public override void Send()
    {
    Console.WriteLine(this.GetType().Name);
    }
    }

Machine


  • Now to make the machine.. Its the the factory that will decide which instances (types) of messages to instantiate,
    so if we have more than 1 machine, we can inherit from the machine and decide in the concrete factory.

    abstract class Machine
    {
    //The array of objects
    private List< Message > _messages = new List< Message >();
    public Machine()
    {
    CreateMachines();
    }

    //The function that each machine will override
    abstract public void CreateMachines();

    public List< Message > Messaages
    {
    get
    {
    return _messages;
    }
    }
    }

  • Cell Phone and PC example..

    class CellPhone : Machine
    {
    public override void CreateMachines()
    {
    //Instantiating objects
    Messaages.Add(new SMS());
    Messaages.Add(new MMS());
    }
    }

    class PC : Machine
    {
    public override void CreateMachines()
    {
    //Instantiating objects
    Messaages.Add(new Email());
    Messaages.Add(new VoiceMail());
    }
    }


  • And this how we can use the factory..

    class Program
    {
    static void Main(string[] args)
    {
    Machine[] machines = new Machine[2];
    //The constructor is the one who calls CreateMachine()
    machines[0] = new CellPhone();//A machine
    machines[1] = new PC();//Another machine..

    foreach (Machine _machine in machines)
    {
    Console.WriteLine("--" + _machine.GetType().Name);
    foreach (Message _message in _machine.Messaages)
    {
    _message.Send();
    }
    }
    }
    }




The Code



namespace Factory_Method
{
class Program
{
static void Main(string[] args)
{
Machine[] machines = new Machine[3];
machines[0] = new CellPhone();
machines[1] = new PC();
machines[2] = new Laptop();

foreach (Machine _machine in machines)
{
Console.WriteLine("--" + _machine.GetType().Name);
foreach (Message _message in _machine.Messaages)
{
_message.Send();
}
}
}
}
abstract class Message
{
abstract public void Send();
}

class Email : Message
{
public override void Send()
{
Console.WriteLine(this.GetType().Name);
}
}
class VoiceMail : Message
{
public override void Send()
{
Console.WriteLine(this.GetType().Name);
}
}
class SMS : Message
{
public override void Send()
{
Console.WriteLine(this.GetType().Name);
}
}
class MMS : Message
{
public override void Send()
{
Console.WriteLine(this.GetType().Name);
}
}

abstract class Machine
{
private List< Message > _messages = new List< Message >();
public Machine()
{
CreateMachines();
}

abstract public void CreateMachines();
public List< Message > Messaages
{
get
{
return _messages;
}
}
}

class CellPhone : Machine
{
public override void CreateMachines()
{
Messaages.Add(new SMS());
Messaages.Add(new MMS());
}
}

class PC : Machine
{
public override void CreateMachines()
{
Messaages.Add(new Email());
Messaages.Add(new VoiceMail());
}
}

class Laptop : Machine
{
public override void CreateMachines()
{
Messaages.Add(new Email());
Messaages.Add(new VoiceMail());
}
}


}

Wednesday, January 23, 2008

Design Patterns - Singleton

Introduction


This article explains the Sngileton Pattern which is one of The C# Design Patterns.

The singleton pattern is used to make a class that has always only one instance, how can this be useful?

There is times that you want to have only one instance of a specific class like for example a chat window,
you want to allow each chatter to have only one opened chat window.



The Code


This can be easily done by returning one instance of the class and allow a global access to it. How?


  • make the constructor private (or protected if you plan to inherit this class before instantiating it).


    class ChatWindow
    {
    private ChatWindow() { }
    }

  • Second make a static refrence to the class


    class ChatWindow
    {
    //this is static so we can access it
    //in the next point
    private static ChatWindow chatObject;

    private ChatWindow() { }
    }

  • Third make a static function that will check if the object has been instantiated or not,
    if not, it will instantiate a new one and assign it to chatObject.


    class ChatWindow
    {
    private static ChatWindow chatObject;
    private static object syncLock = new object();

    private ChatWindow() { }

    public static ChatWindow GetObject()
    {
    if (chatObject == null)
    {
    lock (syncLock)
    {
    if (chatObject == null)
    {
    chatObject = new ChatWindow();
    }
    }
    }
    return chatObject;
    }
    }



So I can always get only the same instance,

this is the Main..

class Program
{
static void Main(string[] args)
{
ChatWindow TheOnlyChatObject = ChatWindow.GetObject();
if (TheOnlyChatObject != null)
{ Console.WriteLine("Object instantiated"); }
ChatWindow sameObject = ChatWindow.GetObject();
if (sameObject == TheOnlyChatObject)
{ Console.WriteLine("A new object is the same object"); }
}
}

Design Patterns - Abstract Factory


Introduction:


This article explains the Abstract Factory pattern of the Design Patterns, and implements an example.
The Abstract Pattern is used to give you the ability to return one of related (grouped) objects of classes
through a factory object, The factory object can return one of a family classes and can also instantiate objects of
another family classes.



The Code


We are going to explain this on Investments, There is types of investment like stocks and bonds.
The investment itself can be raised and can fall, then the stocks investment for example can be raised and can fall.
This is done through the investment object (which is the factory).



The investment class is abstract, and has two abstract (not implemented) methods: CreateRaise(), and CreateFall() , each of which is type of
raiseInvestment and fallInvestment respectively.


abstract class invsetment
{
public abstract raiseInvestment CreateRaise();
public abstract fallInvestment CreateFall();
}

abstract class fallInvestment
{
public abstract int Minus(int current);
}

abstract class raiseInvestment
{
public abstract int Plus(int current);
}



So what I need now is to implement fallInvestment and raiseInvestment classes..



/// Beside Fall and Raise classes we can add
/// new class to calculate the interest related
/// changes for example, with a static method
/// to directly calculate the interest.

class Fall : fallInvestment
{
public override int Minus(int current)
{
return current - 1;
}
}

class Raise : raiseInvestment
{
public override int Plus(int current)
{
return current + 1;
}
}

Well, Now you have to decide what types of investments you want to make..

There can be Stocks and Bonds, each is an investment so each can inherits investment class.

To inherit investment class you have to override the CreateRaise() and CreateFall abstract
methods (which are in the investment class) and return a new instance of Raise and Fall classes.


class stocks : invsetment
{

public override raiseInvestment CreateRaise()
{
return new Raise();
}

public override fallInvestment CreateFall()
{
return new Fall();
}
}

class bonds : invsetment
{

public override raiseInvestment CreateRaise()
{
return new Raise();
}

public override fallInvestment CreateFall()
{
return new Fall();
}
}


Because here I have instantiated Raise and Fall classes they will be the most derived in the instantiated object class
thats inherited from fallInvestment or raiseInvestment, and the compiler will take the most derived (when overriding).

And actually here we have implemented fallInvestment and raiseInvestment (abstract classes) by the Fall and Raise
(concrete classes), inside stocks and\or bonds classes.



In my client level, the client is the class thats instantiates objects, call functions,..

In my client I want to make instances of raiseInvestment and fallInvestment by calling
investment.CreateRaise() or investment.CreateFall().

But how can I get the refrence of the decided investment?.. it can be passed as a parameter to the constructor
of the client when instantiating the client.

when i get these two instances of raiseInvestment and fallInvestment i can then call these fucntions
raiseInvestment.Plus() and fallInvestment.Minus() and I'll getthe overrided functions because they
have been the most derived.


class clientOnInvestment
{
private fallInvestment _fallInvestment;
private raiseInvestment _raiseInvestment;
private int currentBalance;

public clientOnInvestment(invsetment _investment, int currentBalance)
{
_fallInvestment = _investment.CreateFall();
_raiseInvestment = _investment.CreateRaise();
this.currentBalance = currentBalance;
}

public void doFall()
{
currentBalance = _fallInvestment.Minus(currentBalance);
}

public void doRaise()
{
currentBalance = _raiseInvestment.Plus(currentBalance);
}

public int Balance
{
get
{
return currentBalance;
}
}
}



and Finally, the Main


class Program
{
static void Main(string[] args)
{
Console.WriteLine("Welcome to Investments");

Console.WriteLine("Creating Stocks............................");

invsetment myStocks = new stocks();
clientOnInvestment myClientS = new
clientOnInvestment(myStocks, 0);//set starting balance to 0

Console.WriteLine("Current Balance = {0}", myClientS.Balance);
Console.WriteLine("Raising balance.........");

myClientS.doRaise();

Console.WriteLine("Current Balance = {0}", myClientS.Balance);
Console.WriteLine("Falling balance.........");

myClientS.doFall();

Console.WriteLine("Current Balance = {0}", myClientS.Balance);


Console.WriteLine("Creating Bonds.............................");

invsetment myBonds = new bonds();
clientOnInvestment myClientB = new
clientOnInvestment(myBonds, 0);//set starting balance to 0

Console.WriteLine("Current Balance = {0}", myClientB.Balance);
Console.WriteLine("Raising balance.........");

myClientB.doRaise();

Console.WriteLine("Current Balance = {0}", myClientB.Balance);
Console.WriteLine("Falling balance.........");

myClientB.doFall();

Console.WriteLine("Current Balance = {0}", myClientB.Balance);

}

}