CH16-行为型-策略
模式动机
- 完成一项任务,往往可以有多种不同的方式,每种方式称为一个策略,我们可以根据环境、条件的不同选择不同的策略来完成该项任务。
- 在软件开发中也常常遇到类似的情况,实现某一功能有多个途径,此时可以使用一种设计模式来使得系统可以灵活的选择解决途径,也能够方便的增加新的解决途径。
- 在软件系统中,有许多算法可以实现某一功能,如查找、排序等,一种常用的方法是硬编码在一个类中,如需要提供多种查询算法,可以将这些算法写到一个类中,在该类中提供多个方法,每个方法对应一种算法;或者将所有的算法封装在一个方法中,通过
if-else
语句来进行选择。这些方法都可以称为硬编码,如果需要增加一种新的算法,则需要修改封装算法类的源代码;修改、更换算法时,仍然需要修改客户端调用代码。这种方式使封装算法的类过于庞大、逻辑复杂,难以维护。 - 除了提供专门的查找算法外,还可以在客户端程序中直接包含算法代码,这种做法更不可取,将导致客户端程序庞大而难以维护,如果存在大量可供选择的代码则将家中问题的严重性。
- 为了解决这个问题,可以定义一些独立的类来封装不同的算法,每一个类封装一个具体的算法,每一个封装算法的类我们都可以称之为策略(Strategy),为了保证这些策略的一致性,一般会使用一个抽象的策略类来做算法的定义,而具体每种算法则应对应于一个具体的策略类。
模式定义
策略模式(Strategy Pattern):定义一系列算法,将每一个算法封装起来,并让他们可以互相替换。该模式实现算法能够独立于使用它的客户端而独立变化,或称政策模式(Policy)。
模式结构
包含 3 种角色:
- Context:环境类
- Strategy:抽象策略类
- ConcreteStrategy:具体策略类
类图
时序图
模式分析
- 策略模式是一个比较容易理解和使用的模式,就是对算法的封装,它把算法的责任和算法本身分割开,委派给不同的对象管理。策略模式通常把一个系列的算法封装到一系列的策略类里面,作为一个抽象策略类的子类。即:准备一组算法,并将每一个算法封装起来,使得他们可以互换。
- 在该模式中,应当有客户端自己决定何时、选择哪个具体策略。
- 该模式仅仅是封装算法,提供新算法插入到已有系统中,以及老算法从系统中移除。策略模式并不觉得在何时使用哪种算法,这些由客户端类决定。在一定程度上提升了灵活性,但是客户端需要理解所有具体策略之间的区别,以便选择合适的算法,这也是该模式的缺点,一定程度上增加了客户端的使用难度。
优点
- 提供了对开闭原则的支持,用户可以在不修改原有系统的基础上选择、增减算法或行为。
- 提供了管理相关算法族的办法。
- 提供了可以替换继承关系的办法。
- 可以避免使用多重条件语句。
缺点
- 客户端必须知道所有的策略类,并自行决定使用哪个策略。
- 将会产生很多策略类,可以通过使用享元模式在一定程度上减少对象的数量。
适用场景
- 如果一个系统中有很多类,他们之间的区别仅在于他们的行为,这时使用策略模式就可以动态的让一个对象在许多行为中选择一个。
- 系统需要动态地在几种算法中选择一种。
- 如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句实现。
- 不希望客户端知道复杂的、与算法相关的数据结构,在具体策略类中封装算法和相关的数据结构,提高算法的保密性与安全性。
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.