views:

47

answers:

1

I am learning delegates.I am very curious to apply delegates to the following chain-of-responsibility pattern.

Kindly help me the way to apply delegates to the following piece.

Thanks in advance.Thanks for your effort.

#region Chain of Responsibility Pattern
namespace Chain
{
    public class Player
    {
        public string Name { get; set; }
        public int Score { get; set; }
    }

    public abstract class PlayerHandler
    {
        protected PlayerHandler _Successor = null;

        public abstract void HandlePlayer(Player _player);

        public void SetupHandler(PlayerHandler _handler)
        {
            _Successor = _handler;
        }
    }

    public class Employee : PlayerHandler
    {
        public override void HandlePlayer(Player _player)
        {
            if (_player.Score <= 100)
            {
                MessageBox.Show(string.Format("{0} is greeted 
                                by Employee", _player.Name));
            }
            else
            {
                _Successor.HandlePlayer(_player);
            }
        }
    }

    public class Supervisor : PlayerHandler
    {
        public override void HandlePlayer(Player _player)
        {
            if (_player.Score >100 && _player.Score<=200)
            {
                MessageBox.Show(string.Format("{0} is greeted
                                by Supervisor", _player.Name));
            }
            else
            {
                _Successor.HandlePlayer(_player);
            }
        }
    }

    public class Manager : PlayerHandler
    {
        public override void HandlePlayer(Player _player)
        {
            if (_player.Score > 200)
            {
                MessageBox.Show(string.Format("{0} is
                                 greeted by Manager", _player.Name));
            }
            else
            {
                MessageBox.Show(string.Format("{0} got low score",
                                 _player.Name));
            }
        }
    }

}
#endregion

#region Main()

void Main()
{

        Chain.Player p1 = new Chain.Player();
        p1.Name = "Jon";
        p1.Score = 100;

        Chain.Player p2 = new Chain.Player();
        p2.Name = "William";
        p2.Score = 170;

        Chain.Player p3 = new Chain.Player();
        p3.Name = "Robert";
        p3.Score = 300;

        Chain.Employee emp = new Chain.Employee();
        Chain.Manager mgr = new Chain.Manager();
        Chain.Supervisor sup = new Chain.Supervisor();
        emp.SetupHandler(sup);
        sup.SetupHandler(mgr);

        emp.HandlePlayer(p1);
        emp.HandlePlayer(p2);
        emp.HandlePlayer(p3);  

}

#endregion
+1  A: 

Consider following sample:

public class Player
{
    private readonly string _name;
    private readonly string _surname;
    private readonly int _score;
    private string _nickName = "";


    public Player(string name, string surname, int score)
    {
        _name = name;
        _surname = surname;
        _score = score;
    }

    public string FullName
    {
        get
        {
            if (string.IsNullOrEmpty(_nickName)) return string.Format("{0} {1}", _name, _surname);
            else return string.Format("{0} \"{1}\" {2}", _name, _nickName, _surname);
        }
    }

    public int Score
    {
        get { return _score; }
    }


    public string NickName
    {
        get { return _nickName; }
        set { _nickName = value; }
    }
}

public delegate bool PlayerHandlerDelegate(Player player);

public class HandlersChain
{
    private readonly List<PlayerHandlerDelegate> _chain = new List<PlayerHandlerDelegate>();

    public void AddHandler(PlayerHandlerDelegate handler)
    {
        _chain.Add(handler);
    }

    public void HandlePlayer(Player player)
    {
        foreach (PlayerHandlerDelegate handler in _chain)
        {
            if (handler(player)) break;
        }
    }
}




class Program
{
    static PlayerHandlerDelegate CreateHandlerDelegate(string position, int minScore)
    {
        return delegate(Player p)
                {
                    if (p.Score > minScore)
                    {
                        //MessageBox.Show(string.Format("{0} is greeted by {1}", p.FullName, position));
                        Console.WriteLine(string.Format("{0} is greeted by {1}", p.FullName, position));
                        return true;
                    }
                    return false;
                };
    }

    static void Main(string[] args)
    {
        Player p1 = new Player("John", "Smith", 100);
        Player p2 = new Player("William", "Brown", 170);
        Player p3 = new Player("Robert", "Johns", 500);

        HandlersChain chain = new HandlersChain();
        chain.AddHandler(delegate(Player p)
                            {
                                if (p.Score > 400)
                                {
                                    p.NickName = "The Hero";
                                }
                                return false;
                            });
        chain.AddHandler(CreateHandlerDelegate("Manager", 300));
        chain.AddHandler(CreateHandlerDelegate("Supervisor", 200));
        chain.AddHandler(CreateHandlerDelegate("Employee", 100));

        chain.AddHandler(delegate(Player p)
            {
                if (p.Score <= 100)
                {
                    //MessageBox.Show(string.Format("{0} got low score", p.FullName));
                    Console.WriteLine(string.Format("{0} got low score", p.FullName));
                    return true;
                }
                return false;
            });


        chain.HandlePlayer(p1);
        chain.HandlePlayer(p2);
        chain.HandlePlayer(p3);
    }
}

I used Console application so MessageBox is changed to Console.

Here original design was slightly changed. Now there is a chain object that holds collection of handlers. Handlers don't know about each other. Chain calls them in order of adding. Each handler returns true if player was "fully handled" i.e. if further handlers in chain shouldn't be called. Theoretically it is not required that handler should return true (i.e. stop handling) if it did some work. It depends on the underlying logic. Also you can see that all "typical" delegates are created by a special method using closure (see http://en.wikipedia.org/wiki/Closure_(computer_science) unfortunately link with "(" seems to be broken if added as link).

P.S. I'm still using VS 2005, so there is no funky stuff such as lambda's in my sample. Sorry.

iPhone beginner