定义
策略模式定义一系列算法,把它们一个个封装起来,并且使它们可互相替换,该模式使得算法可独立于使用它的客户而变化。
动机
在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂;而且有时候支持不使用的算法也是一个性能负担。如何在运行时根据需要透明地更改对象的算法?将算法与对象本身解耦,从而避免上述问题?看下面的策略者模式的结构图和基本代码,策略者模式比较简单,下面只是给出基本的代码实现。
策略者模式结构图:
策略模式的定义说的实在太抽象了,可能你读过去的时候捉不住他的要点。在大话设计模式里这么说的,更好理解一些:策略模式是一种定义了一系列算法的方法,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。
我们可以试着紧紧捉住这一句:所有这些算法完成的都是相同的工作,只是实现不同。
当有这种情况的有时候我们可以考虑一下使用策略模式。当然策略模式的使用是在需要实现比较大的,具有比较多的完成相同的工作,只是实现不同的情况下使用。如果只是一个或者两个的相同工作,实现算法不同的情况,那我想大多数人都只是改一下方法名就可以了。
这次通过两段代码来对策略模式了解
1、第一个例子是策略者模式的经典实现,类似于一个模型代码那样,百度一下你都能找到。
View Code
namespace 策略模式 { class Program { static void Main(string[] args) { Context ct = null; ct = new Context(new ConcretestrategyA()); ct.ContextInterface(); ct = new Context(new ConcretestrategyB()); ct.ContextInterface(); Console.ReadLine(); } } /// <summary> /// 抽象算法类 /// </summary> public abstract class Strategy { public abstract void AlgorithmInterface(); } /// <summary> /// 算法A的实现 /// </summary> public class ConcretestrategyA : Strategy { public override void AlgorithmInterface() { Console.WriteLine("算法A的实现"); } } /// <summary> /// 算法B的实现 /// </summary> public class ConcretestrategyB : Strategy { public override void AlgorithmInterface() { Console.WriteLine("算法B的实现"); } } /// <summary> /// 上下文 /// </summary> public class Context { private Strategy st; public Context(Strategy st) { this.st = st; } public void ContextInterface() { st.AlgorithmInterface(); } } }
2、第二个例子是新闻分页的,我们有两种分页的算法,一种使用的SQL语句是TOP的,另一种使用的是ROW_NUMBER。他们返回的分页结果相同,但是算法不同。
(只是大概的实现,具体代码的实现细节不去考虑)
View Code
namespace 策略模式 { class Program { static void Main(string[] args) { Context ct = null; ct = new Context(new ConcretestrategyA()); ct.ContextInterface(1,5); Console.WriteLine("----------------------------------------------"); ct = new Context(new ConcretestrategyB()); ct.ContextInterface(1,5); Console.ReadLine(); } } /// <summary> /// 抽象算法类 /// </summary> public abstract class Strategy { public abstract void GetPage(int pageIndex, int PageSize); } /// <summary> /// 算法A的实现 /// </summary> public class ConcretestrategyA : Strategy { public override void GetPage(int pageIndex, int PageSize) { using (SqlConnection conn = new SqlConnection("server=.;database=test;uid=sa;pwd=123456")) { conn.Open(); string strSql = @"SELECT TOP " + PageSize + " * FROM Customer WHERE id NOT IN(SELECT TOP " + PageSize * (pageIndex - 1) + " id FROM Customer ORDER BY id) ORDER BY id"; using (SqlCommand cmd = new SqlCommand(strSql, conn)) { SqlDataReader dr = cmd.ExecuteReader(); while (dr.Read()) { Console.WriteLine(string.Format("姓名:{0} 电话{1}", dr["cName"].ToString(), dr["cPhone"].ToString())); } } } } } /// <summary> /// 算法B的实现 /// </summary> public class ConcretestrategyB : Strategy { public override void GetPage(int pageIndex, int PageSize) { using (SqlConnection conn = new SqlConnection("server=.;database=test;uid=sa;pwd=123456")) { conn.Open(); string strSql = @"select * from (select ROW_NUMBER() over(order by id) as RowNumer,* from Customer)t where t.RowNumer>" + (pageIndex - 1) * PageSize + " and t.RowNumer<=" + pageIndex * PageSize; using (SqlCommand cmd = new SqlCommand(strSql, conn)) { SqlDataReader dr = cmd.ExecuteReader(); while (dr.Read()) { Console.WriteLine(string.Format("姓名:{0} 电话{1}", dr["cName"].ToString(), dr["cPhone"].ToString())); } } } } } /// <summary> /// 上下文 /// </summary> public class Context { private Strategy st; public Context(Strategy st) { this.st = st; } public void ContextInterface(int pageIndex,int pageSize) { st.GetPage(pageIndex, pageSize); } } }