首页 > 代码库 > 策略模式Strategy——回家乘什么车?

策略模式Strategy——回家乘什么车?

1.问题与模式

时间:2014年6月       学校:廊坊师范        家:石家庄       人物:学生

       又快到期末考试了,回家的节奏也奔上日程,无聊之余就想想这次回家的事儿。对我来说回家主要有两种交通方式:1.汽车,2.火车。像飞机、高铁了什么的咱就不考虑了一个是资金匮乏、条件不允许(廊坊没飞机场吧?)外,廊坊到石家庄这么近搞那么多花样也太伤神经了(尤其对一路痴来说)。现在来一一分析下这两种方式:

       1.汽车  方便省事,不用在学生大部队回家的时候担心抢不到火车票而郁闷,但是对于晕车的人来说4h的车程还是蛮煎熬的,或者来个高速紧急事件把你放高速上几个小时还是有可能的。不得不提的一点就是从大一到现在廊坊~石家庄的汽车票价已经涨三次了,第四次貌似也正在筹备中。。。

       2.火车  “回家之难,难于一票解千愁”,学生的好处就是出去玩啦寒暑假回家的时候手里有一张踏踏实实的学生证,能半价的半价不半价也能来个七五折,比坐汽车回家划算多了。但是我们也不能忽略这便宜背后隐藏的真相,各种抢票各种半夜蹲点,整得有时候回家就得像个夜猫子一样。

       相比较而言,对于学生的我来说,回家的方式莫过于火车为主、汽车为辅,火车行不通了再买张汽车票吧。如果哪一天手上有了大把的闲钱,科技再发达点,没准儿我就乘UFO回家了。呃,想多了,那会儿应该人就不在廊坊了

2.结构:UML图

3.模式组成

     1)环境角色(Context):持有一个对Strategy的引用,最终给客户端调用。用一个ConcreteStrategy对象来配置,可定义一个接口来让Strategy访问它的数据。

     2)抽象策略角色(Strategy):策略类,通常由一个接口或者抽象类实现。定义了一个公共接口,各种不同的算法以不同的方式实现这个接口。Context使用这个接口来调用某ConcreteStrategy定义的算法。

     3)具体策略角色(ConcreteStrategy):包装了相关的算法和行为,实现了Strategy定义的接口,提供具体算法的实现。

4.应用

     1)多个类只区别在表现行为的不同,在运行时动态选择具体要执行的行为。

     2)需要在不同情况下使用不同的策略,或者策略还可能在未来用其它方式实现。

     3)对客户隐藏具体策略的实现细节,以避免暴露复杂的、与算法相关的数据结构。

     4)一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。

5.优点

     1)算法系列:Strategy类层次为Context定义了一系列的可供重用的算法或行为。继承有助于析取出这些算法中的公共功能。

     2)简化了单元测试:每个算法都有自己的类,可以通过自己的接口单独测试。每个算法可保证它没有错误,修改其中任一个时也不会影响其他的算法。

     3)消除了一些条件语句:当不同的行为堆砌在一个类中时,就很难避免使用条件语句来选择合适的行为。将这些行为封装在一个个独立的Strategy类中,可以在使用这些行为的类中消除条件语句。

     4)提供了可以替换继承关系的办法:继承可以处理多重算法或行为,但它也使得动态改变算法或行为变得不可能。

   缺点

     1)客户端必须知道所有的策略类,并自行决定使用哪一个策略类。

     2)造成很多策略类的产生,可以通过使用享元模式在一定程度上减少对象的数量。

6.模式实现

    UML图

 

代码实现

    //客户端代码
    static void Main(string[] args)
    {
        PersonContext person;
        //实例化不同的交通工具,最终得到的回家方式不同
        person = new PersonContext(new TrainStrategy());
        person.PersonInterface();

        person = new PersonContext(new AutomobileStrategy());
        person.PersonInterface();

        Console.Read();
    }
    //PersonContext类
    class PersonContext
    {
        //声明一个GoHomeStrategy对象
        private GoHomeStrategy gh;

        //通过构造方法,传入具体的回家交通策略
        public PersonContext(GoHomeStrategy gh)
        {
            this.gh = gh;
        }
        public void PersonInterface()
        {
            gh.transportation();
        }
    }
    //抽象算法类,定义所有回家的交通方式
    abstract class GoHomeStrategy
    {
        //算法方法
        public abstract void transportation();
    }
    //具体交通方式,火车类
    class TrainStrategy:GoHomeStrategy 
    {
        public override void transportation()
        {
            Console.WriteLine("乘火车回家");
        }
    }
    //具体交通方式,汽车类
    class AutomobileStrategy:GoHomeStrategy
    {
        public override void transportation()
        {
            Console.WriteLine("乘汽车回家");
        }
    }

7.其它相关模式

     状态模式、简单工厂模式

8.总结

     策略模式: 它定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

     在这个模式的运用中,很多时候采用与简单工厂模式和反射方法结合的方式,从而更好的实现OCP原则。

 

PS:策略模式中的算法并不是单纯的指数学上一个计算的步骤,而是指实现某项功能的一种方式方法。