设计模式(5)——行为型模式2

本文深入探讨了设计模式中的中介者模式、访问者模式、策略模式等概念,详细解释了每种模式的工作原理、UML图和关键代码实现,帮助开发者理解如何在实际项目中应用这些模式以提高代码的灵活性和可维护性。



       本篇博客我们接着上篇博客(设计模式(4)一——行为型模式1)我们继续。


  19.中介者模式

        用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变他们之间的交互。其实将对象之间的交互封装起来就是中介者。使对象之间没有交互,只需将对象自己的通知和中介者交互即可。与外观模式有类似的地方。(举个例子:在公司领导就是下级的中介者,下级有问题不能解决不用在下级之间来回的问,直接去找领导(中介者)就可以快速的解决问题)


UML图:



代码:

namespace 中介者模式
{
    class Program
    {
        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();
        }
    }

    abstract class Mediator   //抽象中介者
    {
        public abstract void Send(string message, Colleague colleague);
    }
    abstract class Colleague     //抽象同事
    {
        protected Mediator mediator;
        public Colleague(Mediator mediator)
        {
            this.mediator = mediator;
        }
    }
    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 );
            }
        }
    }

    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 );
        }
    }

}



20. 访问者模式

        表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。适用于数据结构相对稳定的系统,目的是把处理从数据结构中分离出来,增加新的操作(访问者)很容易,访问者模式就是将有关的行为集中到一个访问者对象中。增加新的数据结构比较困难。(举个例子:北京动物园有很多景点供游客(访问者)参观,不同的访问者看了不同的景点之后有不同的反应,我看了猴子之后感觉挺好,你看了之后感觉可能不好;我看了大象表演之后可能感觉想吐,你看了之后还津津有味的)


UML图:



代码:

namespace 访问者模式
{
    class Class2
    {
        static void Main(string[] args)
        {
            ObjectStructure1 o = new ObjectStructure1();
            o.Attach(new ConcreteElementA());
            o.Attach(new ConcreteElementB());

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

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

            Console.Read();
        }
    }
    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}访问1",concreteElementA.GetType().Name ,this.GetType().Name );
        }

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

        public override void VisitConcreteElementB(ConcreteElementB concreteElementB)
        {
            Console.WriteLine("{0}被{1}访问2", 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 OperationA()  //其他相关函数
        { }

    }


    class ObjectStructure1
    {
        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);
            }
        }
    }
}


21. 策略模式

       定义了算法家族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客户。策略模式是一种定义一系列算法的方法,简化了单元测试,每个算法都有自己的类,可以通过自己的接口单独测试。简单的说策略模式就是用来封装算法的,是算法的实现细节得到隐藏。(举个例子:在我们刚刚试航成功的瓦良格号航空母舰上配有最新的近程防空系统,在这个系统中可以放很多导弹,你可以放“X-29”、“X-15”、“KH-101”等不同型号)


UML图:



代码:

// 策略模式:定义算法家族,分别封装起来,让他们之间可以互相替换(父类和子类继承),此模式让算法的变化,不会影响到使用算法的客户
// 再使用另一个类通过参数的传递引用策略类
namespace 策略模式
{
    class Class1
    {
        static void Main(string[] args)
        {
            Context context;
            context=new Context(new ConcreateStrategyA());
            context.ContextInterface();

            context=new Context(new ConcreateStrategyB());
            context.ContextInterface();

            context=new Context(new ConcreateStrategyC());
            context.ContextInterface();

            Console.Read();
        }
    }

    abstract class Strategy        //策略类,抽象算法类
    {
        public abstract void AlgorithmInterface();
    }
    class ConcreateStrategyA : Strategy  //具体算法A
    {
        public override void AlgorithmInterface()
        {
            Console.WriteLine("算法A的实现");
        }
    }
    class ConcreateStrategyB : Strategy  //具体算法B
    {
        public override void AlgorithmInterface()
        {
            Console.WriteLine("算法B的实现");
        }
    }
    class ConcreateStrategyC : Strategy  //具体算法C
    {
        public override void AlgorithmInterface()
        {
            Console.WriteLine("算法C的实现");
        }
    }

    class Context      //维护一个对Strategy对象的引用
    {
        Strategy strategy;
        public Context(Strategy strategy)
        {
            this.strategy = strategy;
        }
        public void ContextInterface()
        {
            strategy.AlgorithmInterface();
        }
    }

}



22. 备忘录模式

       在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原来保存的状态。这种模式比较适合于功能比较复杂,但是需要维护或记录属性历史的类。(举个例子:玩游戏的时候,自己死了都希望回到前一段时间的状态,只要保存好一个时间点的状态,就可以恢复到这个时间的状态)


UML图:



代码:

namespace 备忘录模式
{
    class Class2
    {
        static void Main(string[] args)
        {
            //大战前
            GameRole1 lixiaoyao = new GameRole1();
            lixiaoyao.GetInitState();
            lixiaoyao.StateDisplay();

            //保存进度
            RoleStateCaretaker stateAdmin = new RoleStateCaretaker();
            stateAdmin.Memento = lixiaoyao.SaveState();

            //大战时,损失严重
            lixiaoyao.Fight();
            lixiaoyao.StateDisplay();

            //恢复之前的状态
            lixiaoyao.RecoveryState(stateAdmin.Memento);
            lixiaoyao.StateDisplay();

            Console.Read();
            
        }
    }
    class GameRole1:GameRole  //游戏角色
    {
        //保存角色状态
        public RoleStateMemento SaveState()
        {
            return (new RoleStateMemento(vit,atk,def ) );
        }

        //恢复角色状态
        public void RecoveryState(RoleStateMemento memento)
        {
            this.vit = memento.Vitality;
            this.atk = memento.Attack;
            this.def = memento.Defense;
        }
    }
    class RoleStateMemento  //角色状态存储箱
    {
        private int vit;
        private int atk;
        private int def;
        public RoleStateMemento(int vit,int atk,int def)
        {
            this.vit=vit ;
            this.atk=atk ;
            this.def =def;
        }
        public int Vitality //生命力
        {
            get{return vit ;}
            set{vit =value ;}
        }
        public int Attack  //攻击力
        {
            get{return atk;}
            set{atk=value ;}
        }
        public int Defense
        {
            get{return def;}
            set{def=value ;}
        }
    }

    class RoleStateCaretaker  //角色状态管理者
    {
        private RoleStateMemento memento;
        public RoleStateMemento Memento
        {
            get{return memento;}
            set{memento =value ;}
        }
    }
}



23. 迭代器模式

提供一种方法顺序访问一个聚合对象中各个元素,而不是暴露该对象的内部表示。一个聚集对象,不管这些对象时什么都需要遍历的时候,就应该考虑使用迭代器模式。,为遍历不同的聚集结构提供开始、下一个、是否结束、当前是那一项等。(举个例子:我们去火车站到候车厅的时候,每个人的行李都会被门口的那个东东(迭代器)检测一遍,防止我们带雷管、炸药、自杀性武器等)


UML图:



代码:

//20.3 迭代器的实现
namespace 迭代器模式
{
    class Program
    {
        static void Main(string[] args)
        {
            ConcreteAggregate a = new ConcreteAggregate();

            a[0] = "大鸟";
            a[1] = "小菜";
            a[2] = "行李";
            a[3] = "老外";
            a[4] = "公交内部员工";
            a[5] = "小偷";

            //Iterator i = new ConcreteIterator(a);
            Iterator i = new ConcreteIteratorDesc(a);
            object item = i.First();
            while (!i.IsDone())
            {
                Console.WriteLine("{0}请买票下车",i.CurrentItem());
                i.Next();
            }
            Console.Read();
        }
    }

    abstract class Iterator      //迭代器抽象类
    {
        public abstract object First();
        public abstract object Next();
        public abstract bool  IsDone();
        public abstract object CurrentItem();
    }
    abstract class Aggregate //聚集抽象类
    {
        public abstract Iterator CreateIterator();  //创建迭代器
    }
    class ConcreteIterator : Iterator  //具体的迭代器类——售票员,从头到尾
    {
        private ConcreteAggregate aggregate;
        private int current = 0;

        public ConcreteIterator(ConcreteAggregate aggregate)
        {
            this.aggregate = aggregate;
        }
        public override object First()
        {
            return aggregate[0];
        }
        public override object Next()
        {
            object ret = null;
            current++;
            if (current < aggregate.Count)
            {
                ret = aggregate[current];
            }
            return ret;
        }

        public override bool IsDone()
        {
            return current >= aggregate.Count ? true : false;
        }
        public override object CurrentItem()
        {
            return aggregate[current ];
        }
    }
    class ConcreteAggregate:Aggregate //具体的聚集类——公交车上所有的人
    {
        private IList<object >items=new List<object >();
        public override Iterator  CreateIterator()
        {
 	        return new ConcreteIterator(this);
        }
        public int Count
        {
            get{return items.Count ;}
        }
        public object this[int index]
        {
            get{return items[index ];}
            set{items.Insert(index,value );}
        }
    }

    //可以使用多种方式遍历的迭代器模式 
    class ConcreteIteratorDesc : Iterator       //从后向前
    {
        private ConcreteAggregate aggregate;
        private int current = 0;

        public ConcreteIteratorDesc(ConcreteAggregate aggregate)
        {
            this.aggregate = aggregate;
            current = aggregate.Count - 1;
        }


        public override object First()
        {
            return aggregate[aggregate.Count - 1];
        }

        public override object Next()
        {
            object ret = null;
            current--;
            if (current >= 0)
            {
                ret = aggregate[current];
            }
            return ret;
        }

        public override bool IsDone()
        {
            return current < 0 ? true : false;
        }

        public override object CurrentItem()
        {
            return aggregate[current ];
        }
    }
}








评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值