বুধবার, ২০ নভেম্বর, ২০১৩

Memento Pattern



·         KL‡bv KL‡bv GKwU object Gi wewfbœ c‡q‡›Ui internal state capture Kivi cÖ‡qvRb c‡o Ges cieZ©x‡Z D³ state restore Ki‡Z nq|
·         Error wKsev failure Gi †ÿ‡Î Bnv LyeB Kvh©Kix|

Intent

  • Memento pattern Gi g~j intent  n‡”Q Bnv encapsulation violate bv K‡i GKwU object Gi internal state capture K‡i Ges cÖ‡qvRbvbyhvqx D³ state restore K‡i|

Non Software Example:

  • Microsoft Ward e¨envi K‡i document prepare Kiv nq|
  • GB document preparation Gi mgq Microsoft Ward GKwU specific session Gi  user KZ…©K type K…Z ward I sentences সমূহ internally capture K‡i iv‡L|
  • session G user Zvi cÖ‡qvRbvbyhvqx Zvi typed document undo/Redo Ki‡Z cv‡i|

UML Diagram:




Memento:
  • Originator Object Gi internal state store K‡i|
Originator
  • Memento create K‡i  hvnv Originator  Gi current internal state Gi GKwU snapshot contain K‡i|
  • cÖ‡qvRbvbyhvqx Memento ‡_‡K wb‡Ri c~e©eZ©x  internal state restore K‡i|
Caretaker:

  • Memento object mg~n store K‡i| G‡ÿ‡Î actual objects details m¤ú‡K© Rvbvi cÖ‡qvRb c‡o bv|
 
Code Example:
  • cÖ_‡g IOriginator bv‡g GKwU Interface create Kwi Ges Dnv‡K ICloneable interface Øviv inherit Kwi|
public interface IOriginator:ICloneable
{
   
}
  • AZtci Av‡iKwU Interface create Kwi Dnvi bvg IMemento. Bnv GKwU generic interface. Gi definition wb¤œiƒc-
public interface IMemento<T> where T:IOriginator
{
}
  • Then IOriginator Interface modify Kwi wb¤œiƒ‡c-
public interface IOriginator:ICloneable
    {
        IMemento<IOriginator> CreateMemento();
        void RestoreMemento(IMemento<IOriginator> memento);
    }
  • Then ICaretaker Interface create Kwi
public interface ICaretaker
{
        void AddMemento<TOriginator>(TOriginator originator)
            where TOriginator : IOriginator;

        TOriginator GetMemento<TOriginator>(MementoType type)
            where TOriginator : IOriginator;
}


  • Then Memento class define Kwi| G‡ÿ‡Î Memento class IMemento interface ‡K implement Ki‡e (Bnv GKwU generic class)-
public class Memento<T>:IMemento<T> where T:IOriginator
   {
        public T State { get; private set; }

        public Memento(T originator)
        {
            State = (T)originator.Clone();
        }
   }
  •  GLb Avgiv IOriginator interface ‡K implement K‡i Originator class create Ki‡ev wb¤œiƒ‡c-
    public abstract class Originator:IOriginator
    {
        public abstract object Clone();

        public abstract void RestoreMemento(IMemento<IOriginator> memento);

        public IMemento<IOriginator> CreateMemento()
        {
            return new Memento<IOriginator>(this);
        }
    }
  • GLb Avgiv MementoType bv‡g GKwU enum create Ki‡ev wb¤œiƒ‡c-
public enum MementoType
{
   Undo,
   Redo
}
  • GB ch©v‡q Avgiv ICaretaker interface implement K‡i Caretaker class create Ki‡ev wb¤œiƒ‡c
public class Caretaker:ICaretaker
{
        public IDictionary<Type, Stack<IOriginator>> _redoItems = new Dictionary<Type, Stack<IOriginator>>();
        public IDictionary<Type, Stack<IOriginator>> _undoItems = new Dictionary<Type, Stack<IOriginator>>();

        public void AddMemento<TOriginator>(TOriginator originator)
            where TOriginator : IOriginator
        {
            Stack<IOriginator> currentStack = GetStack<TOriginator>(MementoType.Undo);
            GetStack<TOriginator>(MementoType.Redo).Clear();
            currentStack.Push(originator);
        }

        public TOriginator GetMemento<TOriginator>(MementoType type)
            where TOriginator : IOriginator
        {
            Stack<IOriginator> currentStack = GetStack<TOriginator>(type);

            if (currentStack.Count == 0)
            {
                throw new KeyNotFoundException(
                    string.Format("The memento was not found in the dictionary, {0}", typeof(TOriginator).FullName));
            }

            IOriginator current = currentStack.Pop();
            GetOppositeStack<TOriginator>(type).Push(current);

            return (TOriginator)current;
        }

        private Stack<IOriginator> GetStack<TOriginator>(MementoType type)
            where TOriginator : IOriginator
        {
            IDictionary<Type, Stack<IOriginator>> currentMapping = GetMapping(type);

            return GetStack(currentMapping, typeof(TOriginator));
        }

        private IDictionary<Type, Stack<IOriginator>> GetMapping(MementoType type)
        {
            IDictionary<Type, Stack<IOriginator>> currentMapping = null;
            switch (type)
            {
                case MementoType.Undo:
                    currentMapping = _undoItems;
                    break;
                case MementoType.Redo:
                    currentMapping = _redoItems;
                    break;
            }

            return currentMapping;
        }

        private Stack<IOriginator> GetOppositeStack<TOriginator>(MementoType type)
            where TOriginator : IOriginator
        {
            return GetStack(GetMapping(GetOppositeType(type)), typeof(TOriginator));
        }

        private MementoType GetOppositeType(MementoType type)
        {
            MementoType oppositeType;
            switch (type)
            {
                case MementoType.Undo:
                    oppositeType = MementoType.Redo;
                    break;
                case MementoType.Redo:
                    oppositeType = MementoType.Undo;
                    break;
                default:
                    throw new NotImplementedException();
            }

            return oppositeType;
        }

        private Stack<IOriginator> GetStack(IDictionary<Type, Stack<IOriginator>> mapping, Type mementoType)
        {
            Stack<IOriginator> currentStack = null;
            if (mapping.ContainsKey(mementoType))
            {
                currentStack = mapping[mementoType];
            }
            else
            {
                currentStack = new Stack<IOriginator>();
                mapping.Add(mementoType, currentStack);
            }

            return currentStack;
        }
}

কোন মন্তব্য নেই:

একটি মন্তব্য পোস্ট করুন