策略模式(Strategy pattern)【使用频率:★★★★☆】

1. 概述

定义一系列算法类,将每一个算法封装起来,并让它们可以相互替换,策略模式让算法独立于使用它的客户而变化。与状态模式是如此的相似,就犹如一对双胞胎一样。只不过状态模式是通过改变对象内部的状态来帮助对象控制自己的行为,而策略模式则是围绕可以互换的算法来创建成功业务。

2. 模式中的角色

2.1 Context(上下文类):上下文类是使用算法的角色,它在解决某个问题(即实现某个方法)时可以采用多种策略。在上下文类中维持一个对抽象策略类的引用实例,用于定义所采用的策略。

2.2 Strategy(抽象策略类):它为所支持的算法声明了抽象方法,是所有策略类的父类,它可以是抽象类或具体类,也可以是接口。环境类通过抽象策略类中声明的方法在运行时调用具体策略类中实现的算法。

2.3 ConcreteStrategy(具体策略类):它实现了在抽象策略类中声明的算法,在运行时,具体策略类将覆盖在环境类中定义的抽象策略类对象,使用一种具体的算法实现某个业务处理。

3. 模式解读

3.1 模式的类图

C#设计模式读书笔记之策略模式(Strategy pattern)_状态模式

3.2 代码实现

using System;

namespace ConsoleApp2
{
class Class2
{
static void Main(string[] args)
{
MovieTicket mt = new MovieTicket();
double originalPrice = 60.0;
double currentPrice;

mt.SetPrice(originalPrice);
Console.WriteLine("原始价为:" + originalPrice);
Console.WriteLine("---------------------------------");

Discount discount = new StudentDiscount();
mt.SetDiscount(discount); //注入折扣对象

currentPrice = mt.GetPrice();
Console.WriteLine("折后价为:" + currentPrice);

Console.ReadLine();
}
}

//电影票类:环境类
class MovieTicket
{
private double price;
private Discount discount; //维持一个对抽象折扣类的引用

public void SetPrice(double price)
{
this.price = price;
}

//注入一个折扣类对象
public void SetDiscount(Discount discount)
{
this.discount = discount;
}

public double GetPrice()
{
//调用折扣类的折扣价计算方法
return discount.Calculate(this.price);
}
}

//折扣类:抽象策略类
interface Discount
{
double Calculate(double price);
}

//学生票折扣类:具体策略类
class StudentDiscount : Discount
{
public double Calculate(double price)
{
Console.WriteLine("学生票:");
return price * 0.8;
}
}

//儿童票折扣类:具体策略类
class ChildrenDiscount : Discount
{
public double Calculate(double price)
{
Console.WriteLine("儿童票:");
return price - 10;
}
}

//VIP会员票折扣类:具体策略类
class VIPDiscount : Discount
{
public double Calculate(double price)
{
Console.WriteLine("VIP票:");
Console.WriteLine("增加积分!");
return price * 0.5;
}
}

}

5. 模式优缺点

  5.1 优点

  • 策略模式提供了对“开闭原则”的完美支持,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为。
  • 使用策略模式可以避免使用多重条件转移语句。

  5.2 缺点

    策略模式将造成产生很多策略类

 

6. 适用场景

  • 一个系统需要动态地在几种算法中选择一种。
  • 如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为