Android设计模式之“组件协作模式”:Strategy 策略模式
油油猪
8年前
<h3><strong>要解决什么问题</strong></h3> <ol> <li> <p>在软件构建过程,某些对象使用的算法可能多种多样,经常改变,如不同国家的费率,如果将这些算法都编码到对象中,将会使用对象变得异常复杂;而且有时候支持(都写在一个类)不使用的算法是一个性能负担</p> </li> <li> <p>如何在运行时根据需要透明地更改对象算法?将算法与对象本身解耦,从而避免上述问题?</p> </li> </ol> <p>也就是说,我们需要在不同情况下执行不同的方法体,结构化设计则要使用枚举、switch-case、if-else等语句进行判断,每个判断结果中都包含对应的算法,就会导致一个类中集合了许多算法,造成一个类十分复杂;而使用的可能就只有其中一个,其他算法因为都在同一个类中,会一同被加载到内存当中,造成性能负担,不必要的算法占用了内存。</p> <h3><strong>模式定义</strong></h3> <p>将一系列算法封装到各个类当中(一个算法一个类) <strong>(变化的)</strong> ,并且是他们可以互相替换 <strong>(提供统一接口)</strong> 。该模式使得算法可独立于使用它的 <strong>客户程序(稳定)</strong> 而 <strong>变化(扩展、子类化)</strong> 。</p> <p>模式结构类图</p> <p><img src="https://simg.open-open.com/show/7084b0adf95d1bc2a84efa94a55be83e.png"></p> <p>从上面的类图可以看出,这个模式,在我们的客户程序中,需要执行一个方法,例如是税率计算,但是不同国家的计算方法不一样,则会有不同的算法(具体实现的方法体),为了让客户程序可以应对日后新增的国家的计算方法,我们把具体的算法封装到不同的策略类的子类当中,通过多态(虚函数的多态调用),就可以在客户程序不改变的情况下,添加新的子类即可。这里我们通过 <strong>策略基类</strong> ,为客户程序提供了统一的接口,提高了程序的扩展性。同时,当没用到的算法,其所在的类是不会被加载到内存当中,从而将内存降低到最小。</p> <p>这个模式符合了面向对象设计8大原则中的“开闭原则 ”,后期仅需要扩展增加,不需要修改。</p> <p>为了让客户程序执行对应策略子类的方法,一般这样操作:</p> <pre> <code class="language-java">StrategyBase sb; public Client(StrategyBase sb){ this.sb = sb; } public void run(){ sb.algorithmInterface(); }</code></pre> <p>在调用该客户类时,传入具体的策略子类对象作为构造方法参数,辣么客户程序执行run方法时,就会执行我们new的子类对象的算法了。</p> <h3><strong>要点</strong></h3> <ol> <li>Strategy及其子类为组件提供了一系列可重用的算法,从而可以使得类型在运行时方便地根据需要在各个算法之间进行切换; (每个Strategy子类有一个可重用的方法,在运行时根据上下文不同,执行不同子类中的算法)</li> <li>Strategy模式提供了用判断语句以外的另一种选择(面向对象的方案),消除了条件判断语句(结构化),这是在解耦。含有许多条判断语句的代码,通常都需要通过Strategy模式进行重构;</li> <li>如果Strategy对象没有实例变量,那么各个上下文可以共享一个Strategy对象,从而节省对象开销。 <strong>?</strong></li> </ol> <h3><strong>三思</strong></h3> <p>枚举类型/ switch case / if else ---- 多态 的重构 ---- strategy模式替代</p> <p> </p> <p>来自:http://www.jianshu.com/p/e18b4b3b4eb5</p> <p> </p>