十二、行为型模式之中介者、访问者、备忘录-----《大话设计模式》

一、中介者模式

    用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互;中介者负责控制和协调一组对象之间的交互,充当一个中介以使组中的对象不再相互显式引用。

优点:Mediator的出现减少了各个Colleague的耦合,使得可以独立地改变和复用各个Colleague类和mediator;由于把对象如何协作进行了抽象,将中介作为一个独立的概念并将其封装在一个对象中,这样关注的对象就从对象各自本身的行为转移到它们之间的交互上来,也就是站在更宏观的角度去看待系统。

适用:中介者模式一般应用于一组对象以定义良好但是复杂的方式进行通信的场合;以及想定制一个分布在多个类中的行为,而又不想生成太多的子类的场合。

    由于ConcreteMediator控制了集中化,于是就把交互复杂性变为了中介者的复杂性,这就使得中介者会变得比任何一个ConcreteColleague都复杂。

image

//定义一个抽象的发送消息方法,得到同事对象和发送消息 
    abstract class Mediator
    {
        public abstract void Send(string message, Colleague colleague);
    }

   class ConcreteMediator : Mediator
    { 
        //需要了解所有的具体同事对象
         private ConcreteColleague1 colleague1;
        private ConcreteColleague2 colleague2;

        public ConcreteColleague1 Colleague1
        {
            set { colleague1 = value; }
        }

        public ConcreteColleague2 Colleague2
        {
            set { colleague2 = value; }
        }

        public override void Send(string message, Colleague colleague)
        {
            //重写发送消息的方法,根据对象做出选择判断,通知对象
            if (colleague == colleague1)
            {
                colleague2.Notify(message);
            }
            else
            {
                colleague1.Notify(message);
            }
        }
    }
//抽象同事类
    abstract class Colleague
    {
        protected Mediator mediator;
        
       构造方法,得到中介对象
        public Colleague(Mediator mediator)
        {
            this.mediator = mediator;
        }
    }

    class ConcreteColleague1 : Colleague
    {
        public ConcreteColleague1(Mediator mediator)
            : base(mediator)
        {

        }
        
       将消息发送给中介者
        public void Send(string message)
        {
            mediator.Send(message, this);
        }

        public void Notify(string message)
        {
            Console.WriteLine("同事1得到信息:" + message);
        }
    }

    class ConcreteColleague2 : Colleague
    {
        public ConcreteColleague2(Mediator mediator)
            : base(mediator)
        {
        }

        public void Send(string message)
        {
            mediator.Send(message, this);
        }

        public void Notify(string message)
        {
            Console.WriteLine("同事2得到信息:" + message);
        }
    }
static void Main(string[] args)
        {
            ConcreteMediator m = new ConcreteMediator();

            ConcreteColleague1 c1 = new ConcreteColleague1(m);
            ConcreteColleague2 c2 = new ConcreteColleague2(m);

            m.Colleague1 = c1;
            m.Colleague2 = c2;

            c1.Send("吃过饭了吗?");
            c2.Send("没有呢,你打算请客?");

            Console.Read();
        }

二、访问者模式

    表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

优点:增加新的操作很容易,因为增加新的操作意味着增加一个新的访问者,访问者模式将有关的行为集中到一个访问者对象中。

缺点:使增加新的数据结构变得困难了。

适用:访问者模式适用于数据结构相对稳定的系统,把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由的演化。

image

abstract class Visitor
    {
        public abstract void VisitConcreteElementA(ConcreteElementA concreteElementA);

        public abstract void VisitConcreteElementB(ConcreteElementB concreteElementB);
    }
    //具体访问者
    class ConcreteVisitor1 : Visitor
    {
        public override void VisitConcreteElementA(ConcreteElementA concreteElementA)
        {
            Console.WriteLine("{0}被{1}访问", concreteElementA.GetType().Name, this.GetType().Name);
        }

        public override void VisitConcreteElementB(ConcreteElementB concreteElementB)
        {
            Console.WriteLine("{0}被{1}访问", concreteElementB.GetType().Name, this.GetType().Name);
        }
    }

    class ConcreteVisitor2 : Visitor
    {
        public override void VisitConcreteElementA(ConcreteElementA concreteElementA)
        {
            Console.WriteLine("{0}被{1}访问", concreteElementA.GetType().Name, this.GetType().Name);
        }

        public override void VisitConcreteElementB(ConcreteElementB concreteElementB)
        {
            Console.WriteLine("{0}被{1}访问", concreteElementB.GetType().Name, this.GetType().Name);
        }
    }
abstract class Element
    {
        public abstract void Accept(Visitor visitor);
    }

    //具体元素
    class ConcreteElementA : Element
    {
       //利用双分派技术,实现处理与数据结构的分离
        public override void Accept(Visitor visitor)
        {
            visitor.VisitConcreteElementA(this);
        }

        public void OperationA()
        { }
    }

    class ConcreteElementB : Element
    {
        public override void Accept(Visitor visitor)
        {
            visitor.VisitConcreteElementB(this);
        }

        public void OperationB()
        { }
    }
    class ObjectStructure
    {
        private IList<Element> elements = new List<Element>();

        public void Attach(Element element)
        {
            elements.Add(element);
        }

        public void Detach(Element element)
        {
            elements.Remove(element);
        }

        public void Accept(Visitor visitor)
        {
            foreach (Element e in elements)
            {
                e.Accept(visitor);
            }
        }
    }
        static void Main(string[] args)
        {
            ObjectStructure o = new ObjectStructure();
            o.Attach(new ConcreteElementA());
            o.Attach(new ConcreteElementB());

            ConcreteVisitor1 v1 = new ConcreteVisitor1();
            ConcreteVisitor2 v2 = new ConcreteVisitor2();

            o.Accept(v1);
            o.Accept(v2);

            Console.Read();
        }

三、备忘录模式

    在不破坏封装性的前提下,捕获一个对象的内部状态人,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

适用:适用于功能比较复杂的,但需要维护或记录属性历史的类;或者需要保存的属性只是众多属性中的一小部分时,Originator可以根据保存的Memento信息还原到前一状态。

image

    //发起人类    
     class Originator
    {
        //需要保存的属性,可能有多个
         private string state;
        public string State
        {
            get { return state; }
            set { state = value; }
        }

        //创建备忘录,将当前需要保存的信息导入并实例化出一个Memento对象
         public Memento CreateMemento()
        {
            return (new Memento(state));
        }
        
        //恢复备忘录,将Memento导入并将相关数据恢复
         public void SetMemento(Memento memento)
        {
            state = memento.State;
        }

        public void Show()
        {
            Console.WriteLine("State=" + state);
        }
    }

    class Memento
    {
        private string state;

        //将相关数据导入
         public Memento(string state)
        {
            this.state = state;
        }
    
        public string State
        {
            get { return state; }
        }
    }

    class Caretaker
    {
        private Memento memento;
        

        //得到或设置备忘录
          public Memento Memento
        {
            get { return memento; }
            set { memento = value; }
        }
    }
       static void Main(string[] args)
        {
            //Originator初始状态,状态属性为“On”
              Originator o = new Originator();
            o.State = "On";
            o.Show();

            //保存状态时,由于有了很好的封装,可以隐藏Originator的实现细节
              Caretaker c = new Caretaker();
            c.Memento = o.CreateMemento();

            o.State = "Off";
            o.Show();

            //恢复初始状态
              o.SetMemento(c.Memento);
            o.Show();

            Console.Read();

        }
原文地址:https://www.cnblogs.com/shanymen/p/4841358.html