一、定义
它定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的用户。
二、特点
- 封装了变化
- 策略模式的Strategy类层次为Context定义了一系列可供重用的算法或行为。继承有助于析取出这些算法中的公共功能
三、优缺点
优点
- 简化了单元测试,每个算法都有自己的类,,可以通过自己的接口单独测试
- 减少了算法类和使用算法类之间的耦合,一个算法一个类
缺点
在基本的策略模式中,所具有具体实现的职责由客户端对象承担,并转给策略模式的Context对象。
什么时候用
多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。
五、实例
策略模式
Strategy类,定义所有支持的算法的公共接口
//抽象算法类 abstract class Strategy { //算法方法 public abstract void AlgorithmInterface(); }
ConcreteStrategy类:封装了具体的算法或行为,继承于Strategy
//具体算法A class ConcreteStrategyA:Strategy { public override void AlgorithmInterface { Console.writeline("算法实现"); } } //具体算法B class ConcreteStrategyB:Strategy { //算法吧B实现方法 public override void AlgorithmInterface() { Console.WriteLine("算法B实现"); } } //具体算法C class ConcreteStrategyC:Strategy { //算法C实现方法 public override void AlgorithmInterface() { console.writeline("算法C实现); } }
Context类:用一个ConcreteStrategy来配置,维护一个对Strategy对象的引用。
class Context { //初始化时,传入具体的策略对象 Strategy strategy; public Context(Strategy strategy) { this.strategy=strategy;// } //上下文接口 public void ContextInterface() { strategy.AlgorithmInterface(); } }
客户端代码
static void Main(string [] args) //由于实例化不同的策略,所以最终在调用context.ContextInterface();时所获得的结果就不相同 //声明Context 类型变量 Context context; context= new Context(new ConcreteStrategyA()); context.ContextInterface(); context= new Context(new ConcreteStrategyB()); context.ContextInterface(); context= new Context(new ConcreteStrategyA()); context.ContextInterface(); Console.Read();
类图关系代码表示
六、涉及知识点
1.构造方法
对类进行初始化,
与类同名
无返回值,无void
与类同名,在new的时候使用
所有类都有构造方法,如果不编码则系统默认生成空的构造方法,若你有定义的构造方法那么默认的构造方法就会失效。
2.访问修饰符
public:公有的 表示所修饰的类成员可以允许其他任何类来访问
private:私有的 表示只能在同一个类的成员访问
3.关系
本模式中涉及到的关系
聚合:表示一种弱的拥有关系,整体和个体的关系,个体可以脱离整体单独存在
实现:成员变量,作为参数传入到整体的构造方法
图形:空心菱形+实线箭头
继承:类与类,类与接口之间的关系,。子类继承父类所有非private的方法
实现:子类继承父类用:表示
图形:空心三角形+实线
4.抽象类
用abstract关键字修饰
抽象类代表一个抽象的概念,他提供一个继承的出发点,当设计一个新的抽象类时,一定是用来继承的,在一个以继承关系形成的等级结构里面,树叶节点应当是具体类,而树叶节点均应是抽象类。
5.特点
- 抽象类不能实例化
- 抽象方法时必须被子类重写的
- 如果类中包含抽象方法,那么类必须定义为抽象类,不论是否还包含其他一般方法
- 一个类可以支持多个接口,一个类只能继承一个类。