设计模式- 策略模式

定义

策略模式定义一系列算法,把它们一个个封装起来,并且使它们可互相替换该模式使得算法可独立于使用它的客户而变化。

 

动机

 在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂;而且有时候支持不使用的算法也是一个性能负担。如何在运行时根据需要透明地更改对象的算法?将算法与对象本身解耦,从而避免上述问题?看下面的策略者模式的结构图和基本代码,策略者模式比较简单,下面只是给出基本的代码实现。

 

策略者模式结构图:

 

 

策略模式的定义说的实在太抽象了,可能你读过去的时候捉不住他的要点。在大话设计模式里这么说的,更好理解一些:策略模式是一种定义了一系列算法的方法,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。

我们可以试着紧紧捉住这一句:所有这些算法完成的都是相同的工作,只是实现不同。

当有这种情况的有时候我们可以考虑一下使用策略模式。当然策略模式的使用是在需要实现比较大的,具有比较多的完成相同的工作,只是实现不同的情况下使用。如果只是一个或者两个的相同工作,实现算法不同的情况,那我想大多数人都只是改一下方法名就可以了。

 

这次通过两段代码来对策略模式了解

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

 

 

 

posted @ 2012-08-29 12:59  春天又来了  阅读(935)  评论(0编辑  收藏  举报