Quantcast
Channel: CSDN博客推荐文章
Viewing all articles
Browse latest Browse all 35570

设计模式之行为型模式三

$
0
0

行为型模式:


策略模式

    它定义了算法家族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客户。


简单工厂模式的不足:

    由于工厂本身包括了所有的收费方式,商场是可能经常性的更改打折额度和返利额度,每次维护或扩展收费方法都要改动这个工厂,以致代码需重新编译部署,很麻烦


方法:

         1,定义一个所有支持的算法的公共接口

         2,将所有具体算法或行为封装在一起

         3,维护对公共接口的引用

        客户端代码是将所有的算法实例化

 

这个模式涉及到三个角色:

        

     环境(Context)角色:持有一个Strategy类的引用。

     抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。

     具体策略(ConcreteStrategy)角色:包装了相关的算法或行为

 

优点:

     使用策略模式可以把行为和环境分割开来。环境类负责维持和查询行为类,各种算法则在具体策略类(ConcreteStrategy)中提供。由于算法和环境独立开来,算法的增减、修改都不会影响环境和客户端。当出现新的促销折扣或现有的折扣政策出现变化时,只需要实现新的策略类,并在客户端登记即可。策略模式相当于"可插入式(Pluggable)的算法"

 

个人理解:


     策略模式与工厂模式

        工厂模式是将需要实例化的所有对象放到一个类中,然后在客户端直接使用工厂的方法,实现不同对象的不同操作

策略模式是将工厂中的方法提取出来,然后将需要实例化的对象都放到了客户端去实例。当我需要添加不同的策略时,只在客户端添加它的实例即可,然后将对象作为参数传到策略模式中即可

 

策略模式结构图:

      

课本实例:商场打折

 

代码如下:

 class cashcontext
 		    {
 			//基类类型的对像
 		        private CashSuper cs;     
 			//初始化时(构造函数),传入具体的对象
 		        public cashcontext(CashSuper csuper)
 		        {
 		            this.cs = csuper;           
                     //将csuper赋给cs,然后计算cs对象的收到的现金数
 		       //通过传入参数的不同,计算不同方式的收到现金数
 		        }
 		        public double getresult(double money)
 		         //根据具体的策略对象,调用其算法的方法
 		        {
 		            return cs.acceptCash(money);       
 		
 		        }
 		    }
 


备忘录模式

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

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

 

课本实例:游戏的状态保存

 

代码如下:

//一个发起人类:有攻击力,生命力,还有创建备忘和恢复备忘的功能等
 	class GameRole
 	        { 
 	            //生命力
 	            private int vit;
 	            public int Vitality
 	            {
 	                get { return vit; }
 	                set { vit = value; }
 	            }
 	            //攻击力
 	            private int atk;
 	            public int Attack
 	            {
 	                get { return atk ; }
 	                set { atk  = value; }
 	            }
 	            //防御类
 	            private int def;
 	            public int Defense
 	            {
 	                get { return def ; }
 	                set { def  = value; }
 	            }
 	            //状态显示
 	            public void StateDisplay()
 	            {
 	                Console.WriteLine("角色当前状态:");
 	                Console.WriteLine("体力:{0}", this.vit);
 	                Console.WriteLine("攻击力:{0}", this.atk);
 	                Console.WriteLine("防御类:{0}", this.def);
 	                Console.WriteLine("");
 	            }
 	            //获得初始状态
 	            public void GetInitState()
 	            {
 	                this.vit = 100;
 	                this.atk = 100;
 	                this.def = 100;
 	            }
 	            //战斗
 	            public void Fight()
 	            {
 	                this.vit = 0;
 	                this.atk = 0;
 	                this.def = 0;
 	            }
 	            //保存角色状态
 	            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; }
 		            }
 		        }
 		
 	//客户端:
 		          //大战前
 		            GameRole hejingyuan = new GameRole();
 		            hejingyuan.GetInitState();
 		            hejingyuan.StateDisplay();
 		
 		            //保存进度
 		            RoleStateCaretaker stateAdmin = new RoleStateCaretaker();
 		            stateAdmin.Memento = hejingyuan.SaveState();
 		            //大战时,损耗严重
 		            hejingyuan.Fight();
 		            hejingyuan.StateDisplay();
 		            //恢复之前状态
 		            hejingyuan.RecoveryState(stateAdmin.Memento);
 		            hejingyuan.StateDisplay();
 		            Console.Read();
 

个人理解:

    备忘录模式:当我要保存备忘时,再发起人(游戏角色)这个类中就创建备忘录,备忘录这个类中具有要备忘的一些内容(属性和方法)等,管理者是对备忘录进行包装,在客户端将发起人备忘赋给管理者这个对象,这样客户端的人就不需要知道我备忘的是什么内容了。

 

迭代器模式

    提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。

当你需要访问一个聚集对象,而且不管这些对象是什么都需要遍历的时候,你就应该考虑用迭代器模式

 

应用:

    当你需要对聚集有多种方法遍历时,可以考虑用迭代器模式                  

    总的来说,迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据.

 

课本实例:乘车买票

 

代码如下:

//Iterator迭代器抽象类
 	        abstract class Iterator
 	        {
 	            public abstract object First();
 	            public abstract object Next();
 	            public abstract object IsDone();
 	            public abstract object CurrentItem();
 	        }
 	//迭代器就是对一个聚集对象遍历
 	
 	//ConcreteIterator具体迭代器类,继承Iterator
 	        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 object IsDone()
 	            {
 	                return current >= aggregate.Count ? true : false;
 	            }
 	            public override object CurrentItem()
 	            {
 	                return aggregate[current];
 	            }
 	        }
 	//具体迭代器就是对具体聚集对象的操作,也是对抽象迭代器的重写
 	
 	//Aggregate
 	        abstract class Aggregate
 	        {
 	            public abstract Iterator CreateIterator();
 	        }
 	//抽象聚集类就是要创建迭代器
 	
 	 //ConcreteAggregate具体聚集类 继承Aggregate
 	        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);
 	                }
 	
 	            }
 	        }
 //具体聚集类中有用于存放聚合对象的变量,对抽象聚集类重写,还有聚集总数,和声明一个索引器
 



作者:hejingyuan6 发表于2013-1-11 15:00:50 原文链接
阅读:57 评论:0 查看评论

Viewing all articles
Browse latest Browse all 35570

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>