sobota, 14 lipca 2012

[Wzorce projektowe] Mediator

Analogia z życia:

Chyba każdy internauta korzystał kiedyś z forów internetowych. Służą one do wymiany informacji na różne tematy między uczestnikami. Każdy użytkownik (nie licząc administracji) ma takie same prawa i także dotyczą go te same obowiązki. Każdy z każdym może się wymieniać informacjami na dowolny temat, a miejscem, gdzie ta wymiana danych się dokonuje jest temat w odpowiednim dziale na forum.




Zastosowanie:

Wzorzec Mediatora okazuje się przydatny, gdy mamy do czynienia z grupą obiektów o podobnych cechach, które mają się ze sobą w pewien sposób komunikować. Wprowadza się zatem dodatkowy, scentralizowany obiekt mediatora, który zbiera informacje od zwykłych obiektów, zwanych kolegami i rozprowadza je zgodnie z pewną logiką, na przykład tylko do uprawnionych obiektów.

Zasada działania:

Wprowadza się pewną klasę bazową z której dziedziczą obiekty zwane kolegami. Każdy obiekt będzie miał w sobie zaszytą logikę przekazywania wiadomości do instancji klasy mediatora. Mediator natomiast zajmuje się rozprowadzeniem wiadomości po wszystkich obiektach - kolegach, którzy są taką wiadomością w jakiś sposób zainteresowani.

Przykład implementacyjny:

public abstract class Warship
    {
        private readonly IWarshipsController _controller;

        protected Warship(bool isActive, IWarshipsController controller)
        {
            _controller = controller;
            IsActive = isActive;
            _controller.RegisterWarship(this);
        }

        public virtual int Range { get; set; }
        public bool IsActive { get; set; }

        private int _lattitude;
        public int Lattitude
        {
            get { return _lattitude; }
            set
            {
                _lattitude = value;
                _controller.ReceiveCoordinatesNotification(this);
            }
        }

        private int _longitude;
        public int Longitude
        {
            get { return _longitude; }
            set
            {
                _longitude = value;
                _controller.ReceiveCoordinatesNotification(this);
            }
        }

        public void InformAboutFellows()
        {
            Console.WriteLine(this.GetType().Name.ToString() + " Acknowledged");
        }
    }

    public class Cruiser : Warship
    {
        public Cruiser(bool i, IWarshipsController c) : base(i,c)
        {
            
        }

        public override int Range
        {
            get
            {
                return 100;
            }
        }
    }

    public class Destroyer : Warship
    {
        public Destroyer(bool i, IWarshipsController c) : base(i,c)
        {
            
        }

        public override int Range
        {
            get
            {
                return 50;
            }
        }
    }
 public interface IWarshipsController
    {
        void ReceiveCoordinatesNotification(Warship sender);
        void RegisterWarship(Warship warship);
    }

    public class MarinaryGovernment : IWarshipsController
    {
        private List<Warship> _ships = new List<Warship>();

        public void ReceiveCoordinatesNotification(Warship sender)
        {
            foreach (Warship warship in _ships.Where(x => x!=sender))
            {
                if(warship.Lattitude - sender.Lattitude < warship.Range
                    || warship.Longitude - sender.Longitude < warship.Range)
                {
                    warship.InformAboutFellows();
                }

            }
        }

        public void RegisterWarship(Warship warship)
        {
            if(!_ships.Contains(warship))
            {
                _ships.Add(warship);
            }
        }
    }
class Program
    {
        static void Main(string[] args)
        {
            MarinaryGovernment gov = new MarinaryGovernment();
            Warship c1 = new Cruiser(true, gov);
            Warship c2 = new Cruiser(true, gov);
            Warship c3 = new Cruiser(true, gov);

            Warship d1 = new Destroyer(true, gov);
            Warship d2 = new Destroyer(true, gov);
            Warship d3 = new Destroyer(true, gov);

            c1.Longitude = 150;
            c2.Longitude = 125;
            c3.Longitude = 50;

            d1.Lattitude = 75;
            d2.Lattitude = 100;
            d3.Lattitude = 130;

            Console.ReadKey(true);

        }
    }

Brak komentarzy:

Prześlij komentarz