策略模式-关于策略模式的定义网上到处都有。但是,这里我想说一下自己结合脑子中有的应用场景的理解。策略模式的核心就是应对“变”(其实,我感觉有好多模式都是应对“变”的,所以这里只是目前的初步理解)。这里的“变”指的是类内部的有些“部件”(我感觉应该是方法,因为别的没什么可以通过模式来“变”的,好像说的是废话,好吧,我基础差)。而这种改变主要是为了应对不同的应用:例如,鸭子类中的Fly方法和quack方法,针对不同的鸭子(活生生的鸭子,木头鸭子,橡皮玩具鸭子等),这种方法需要针对特定的目标做出不同的反应(注1);又比如你需要做一个界面,这种界面可以通过用户的选择处理不同源的数据(每种数据的数据格式不同,解析方法当然也不同)
==============分割线==============
又复习了一遍,又有了新的认识。其实,上述的描述只是一个类似于结论的东西,我们很有必要把原因也搞明白。其实,对于“变”的应对策略很多,例如使用抽象类,子类继承抽象类后进行针对于子类本身的特殊化改造也是一种应对“变”的策略,为什么不采用这种方法应对变而是要采用策略模式呢?
原因是这样的:有时候“继承不如组合”。
例如:我们抽象除了一个Duck的超类,可以在这个超类中定义好抽象函数fly()和quack()方法,然后每个子类实现这两个方法就可以了,也可以应对变。或者,在超类中定义virtual函数fly()和quack()方法,在需要覆盖父类方法的时候进行覆盖就可以了,这样既达到了某种程度的代码复用,又使得每个子类可以按照本身的特点去进行私人订制。相对于上一种,这种方式增加了复用这一优点。但是,如果有100个不同的子类,而且这100个不同的子类的功能只有大概10种左右(也就是子类功能少于类的数目)。这样写子类的话太累了,class2的fly方法和class50的fly方法是一样的,但是这两者都不同于父类中的fly方法的代码,我们就需要在这两个不同的类中书写同样的代码,而如果有49个这样的类呢?是不是太麻烦了。
那么策略模式的好处就显现出来了。在父类中我们定义了一个关于fly方法和quack方法的接口来分别进行功能类的引用。而不同功能的10种方法我们定义为10中fly类和quack类。那么对于上例的问题就很容易了。对于不同的子类,我们只需要从10中方法中找到对应的类,然后将引用传到子类中,子类就可以具备功能了,这样既保证了灵活性,也最大程度的加强了函数功能的复用。
这种模式对于会生成多个不同类型的子类,同时,各个子类的功能又不尽相同(甚至可以达到排列组合程度的变化类型)的情况下特别有用。
注1:这里的做出不同的反应,我感觉和简单工厂模式中的针对不同的选择生产不同的产品不太一样,简单工厂模式是作为主人翁类,提供变化的产品;而策略模式的主人翁是类自己,我自己选择不同的方法(也是一种产品)来使用。更通俗一点,鸭子类的Fly方法和quack方法是各个子类自己使用;而不是提供给别的去用。简单工厂模式是把这种变化集中处理,自己这个类当做“枢纽”,这个方法要是瘫痪,那就会瘫痪一大片;策略模式是配备给每个类自己的工具,是一种分散式的策略。
P.S.:我自己也是菜鸟,这是我的理解,如果有不对的,希望大家积极给予指正,非常欢迎大家互相讨论:)。