策略模式(对比工厂模式)

作者: 激情的狼王 | 来源:发表于2017-12-12 16:06 被阅读0次

    从策略一词来看,策略模式是种倾向于行为的模式.有点类似打仗时的做战方案,一般司令员在做战前都会根据实际情况做出几套不同的方案,如果当时情况有变,就会根据相应的条件来判定用哪一套方案来替换原定方案。但无论如何替换,替换多少次,仗还是要打的。

    策略模式的UML图

    710c8ab5-6559-3c00-b1d1-774babbcea2f.png
    策略模式与工厂模式从uml图上来说,基本一致。只是强调的封装不同。我们以工厂模式和策略模式的比较来讲解策略模式。
    工厂模式在这篇文章里有详细解释简单工厂、工厂方法模式、抽象工厂模式,我们来回顾一下
    工厂模式我们可以做如下理解:假设有Audi的公司生产汽车,它掌握一项核心的技术就是生产汽车,另一方面,它生产的汽车是有不同型号的,并且在不同的生产线上进行组装。当客户通过销售部门进行预定后,Audi公司将在指定的生产线上为客户生产出它所需要的汽车。
    //工厂模式
    //抽象产品  
    abstract class AudiCar{  
        private String name;  
          
        public abstract void makeCar();  
          
        public String getName() {  
            return name;  
        }  
        public void setName(String name) {  
            this.name = name;  
        }  
    }  
    //具体产品  
    class AudiA6 extends AudiCar{  
        public void makeCar(){  
            System.out.println(this.getName()+"----go-----------------------");  
        }  
    }  
    class AudiA4 extends AudiCar{  
        public void makeCar(){  
            System.out.println(this.getName()+"----go-----------------------");  
        }  
    }  
      
    //简单工厂---销售部门----服务端  
    class CarFactroy{  
        public static AudiCar createCar(String car){  
            AudiCar c = null;  
            if("A6".equalsIgnoreCase(car))  
                c = new AudiA6();  
            else if("A4".equalsIgnoreCase(car))  
                c = new AudiA4();  
            return c;  
        }  
    }  
      
    //客户----客户端(这个客户是外行,什么都不懂,只要随便描述下车,销售部门才能知道他要那款车,所以销售部门比较牛)  
    public class SimplyFactoryAndStrategy {  
      
        public static void main(String[] args) throws IOException {  
              
            System.out.print("请输入您要坐的车:(A6、A4)");  
            String carName = new BufferedReader(new InputStreamReader(System.in)).readLine();  
              
            //客户说我要什么什么样子的车子,销售人员才知道他要什么样子的车子  
            AudiCar car = CarFactroy.createCar(carName);  
            car.setName(carName);  
            car.makeCar();    
        }  
    }  
    

    策略(Strategy)模式在结构上与工厂模式类似,唯一的区别是工厂模式实例化一个产品的操作是在服务端来做的,换句话说客户端传达给服务端的只是某种标识,服务端根据该标识实例化一个对象。而策略模式的客户端传达给服务端的是一个实例,服务端只是将该实例拿过去在服务端的环境里执行该实例的方法。

    //策略模式
    //抽象产品  
    abstract class AudiCar{  
        private String name;  
          
        public abstract void makeCar();  
          
        public String getName() {  
            return name;  
        }  
        public void setName(String name) {  
            this.name = name;  
        }  
    }  
    //具体产品  
    class AudiA6 extends AudiCar{  
        public void makeCar(){  
            System.out.println(this.getName()+"----go-----------------------");  
        }  
    }  
    class AudiA4 extends AudiCar{  
        public void makeCar(){  
            System.out.println(this.getName()+"----go-----------------------");  
        }  
    }  
      
    //销售部门----服务端  
    class CarContext {  
        AudiCar audiCar = null;  
      
        public CarContext(AudiCar audiCar) {  
            this.audiCar = audiCar;  
        }  
          
        public void orderCar(){  
            this.audiCar.makeCar();  
        }  
    }  
      
    //客户----客户端(这个客户是内行,什么都懂,他说我要A6,销售部门立刻给他a6,所以销售部门不用很懂)  
    public class SimplyFactoryAndStrategy2 {  
      
        public static void main(String[] args) throws IOException {  
              
            //客户说我要什么什么样子的车子,销售人员才知道他要什么样子的车子  
            AudiCar car = new AudiA6();  
            car.setName("a6");  
              
            CarContext context = new CarContext(car);  
            context.orderCar();  
        }  
    }  
    

    工厂模式和策略模式的区别在于实例化一个对象的位置不同,对工厂模式而言,实例化对象是放在服务端的,即放在了工厂类里面;
    而策略模式实例化对象的操作在客户端,服务端的“销售部门”只负责传递该对象,并在服务端的环境里执行特定的操作。
    工厂模式要求服务端的销售部门足够灵敏,而策略模式由于对策略进行了封装,所以他的销售部门比较傻,需要客户提供足够能区分使用哪种策略的参数,而这最好的就是该策略的实例了。
    策略模式的优缺点

    策略模式的主要优点有:

    1.策略类之间可以自由切换,由于策略类实现自同一个抽象,所以他们之间可以自由切换。
    2.易于扩展,增加一个新的策略对策略模式来说非常容易,基本上可以在不改变原有代码的基础上进行扩展。
    3.避免使用多重条件,如果不使用策略模式,对于所有的算法,必须使用条件语句进行连接,通过条件判断来决定使用哪一种算法,在上一篇文章中我们已经提到,使用多重条件判断是非常不容易维护的。

    策略模式的缺点主要有两个:

    1.维护各个策略类会给开发带来额外开销,可能大家在这方面都有经验:一般来说,策略类的数量超过5个,就比较令人头疼了。
    2.必须对 客户端(调用者)暴露所有的策略类,因为使用哪种策略是由客户端来决定的,因此,客户端应该知道有什么策略,并且了解各种策略之间的区别,否则,后果很严 重。例如,有一个排序算法的策略模式,提供了快速排序、冒泡排序、选择排序这三种算法,客户端在使用这些算法之前,是不是先要明白这三种算法的适用情况? 再比如,客户端要使用一个容器,有链表实现的,也有数组实现的,客户端是不是也要明白链表和数组有什么区别?就这一点来说是有悖于迪米特法则的。

    适用场景

    做面向对象设计的,对策略模式一定很熟悉,因为它实质上就是面向对象中的继承和多态,在看完策略模式的通用代码后,我想,即使之前从来没有听说过策略模式,在开发过程中也一定使用过它吧?

    至少在在以下两种情况下,大家可以考虑使用策略模式,

    几个类的主要逻辑相同,只在部分逻辑的算法和行为上稍有区别的情况。
    有几种相似的行为,或者说算法,客户端需要动态地决定使用哪一种,那么可以使用策略模式,将这些算法封装起来供客户端调用。
    策略模式是一种简单常用的模式,我们在进行开发的时候,会经常有意无意地使用它,一般来说,策略模式不会单独使用,跟模版方法模式、工厂模式等混合使用的情况比较多。

    相关文章

      网友评论

        本文标题:策略模式(对比工厂模式)

        本文链接:https://www.haomeiwen.com/subject/xvrnixtx.html