设计模式-策略模式详解
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
1. 背景
在现实生活中常常遇到实现某种目标存在多种策略可供选择的情况例如出行旅游可以乘坐飞机、乘坐火车、骑自行车或自己开私家车等超市促销可以釆用打折、送商品、送积分等方法。
在软件开发中也常常遇到类似的情况当实现某一个功能存在多种算法或者策略我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能如数据排序策略有冒泡排序、选择排序、插入排序、二叉树排序等。如果使用多重条件转移语句实现即硬编码不但使条件语句变得很复杂而且增加、删除或更换算法要修改原代码不易维护违背开闭原则。如果采用策略模式就能很好解决该问题。
2. 定义和特点
(1) 定义该模式定义了一系列算法并将每个算法封装起来使它们可以相互替换且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式它通过对算法进行封装把使用算法的责任和算法的实现分割开来并委派给不同的对象对这些算法进行管理。
(2) 优点
A. 多重条件语句不易维护而使用策略模式可以避免使用多重条件语句。
B. 策略模式提供了一系列的可供重用的算法族恰当使用继承可以把算法族的公共代码转移到父类里面从而避免重复的代码。
C. 策略模式可以提供相同行为的不同实现客户可以根据不同时间或空间要求选择不同的。
D. 策略模式提供了对开闭原则的完美支持可以在不修改原代码的情况下灵活增加新算法。
E. 策略模式把算法的使用放到环境类中而算法的实现移到具体策略类中实现了二者的分离。
(3) 缺点
A. 客户端必须理解所有策略算法的区别以便适时选择恰当的算法类。
B. 策略模式造成很多的策略类。
3.具体实现
(1) 模式的结构
策略模式是准备一组算法并将这组算法封装到一系列的策略类里面作为一个抽象策略类的子类。策略模式的重心不是如何实现算法而是如何组织这些算法从而让程序结构更加灵活具有更好的维护性和扩展性。
A. 抽象策略Strategy类定义了一个公共接口各种不同的算法以不同的方式实现这个接口环境角色使用这个接口调用不同的算法一般使用接口或抽象类实现。
B. 具体策略Concrete Strategy类实现了抽象策略定义的接口提供具体的算法实现。
C. 环境Context类持有一个策略类的引用最终给客户端调用。
结构图
(2) 应用场景
不同场景下需要对两个数进行运算(加减乘除)这个时候就可以使用策略模式。首先声明一个策略接口IStrategy用于定义策略的计算方法 然后声明具体的策略类(加减乘除)均实现这个IStrategy策略接口最后声明一个Context策略选择类用户客户端调用执行。
更多C++后台开发技术点知识内容包括C/C++LinuxNginxZeroMQMySQLRedisMongoDBZK流媒体音视频开发Linux内核TCP/IP协程DPDK多个高级知识点。
C/C++Linux服务器开发高级架构师/C++后台开发架构师免费学习地址
【文章福利】另外还整理一些C++后台开发架构师 相关学习资料面试题教学视频以及学习路线图免费分享有需要的可以点击领取
(3) 代码实操
策略接口和具体的策略类
/// <summary>
/// 抽象策略结构
/// </summary>
public interface IStrategy
{
/// <summary>
/// 策略计算方法
/// </summary>
/// <param name="num1"></param>
/// <param name="num2"></param>
/// <returns></returns>
public int DoOperation(int num1, int num2);
}
/// <summary>
/// 1、加法策略
/// </summary>
public class OperationAdd : IStrategy
{
public int DoOperation(int num1, int num2)
{
return num1 + num2;
}
}
/// <summary>
/// 2、减法策略
/// </summary>
public class OperationSubtract : IStrategy
{
public int DoOperation(int num1, int num2)
{
return num1 - num2;
}
}
/// <summary>
/// 3、乘法策略
/// </summary>
public class OperationMultiply : IStrategy
{
public int DoOperation(int num1, int num2)
{
return num1 * num2;
}
}
/// <summary>
/// 4、除法策略
/// </summary>
public class OperationDivision : IStrategy
{
public int DoOperation(int num1, int num2)
{
return num1 / num2;
}
}
策略选择类
/// <summary>
/// 策略选择类
/// </summary>
public class Context
{
private IStrategy strategy;
public Context(IStrategy strategy)
{
this.strategy = strategy;
}
public int executeStrategy(int num1, int num2)
{
return strategy.DoOperation(num1, num2);
}
}
测试
{
Context context = new Context(new OperationAdd());
Console.WriteLine("10 + 5 = " + context.executeStrategy(10, 5));
context = new Context(new OperationSubtract());
Console.WriteLine("10 - 5 = " + context.executeStrategy(10, 5));
context = new Context(new OperationMultiply());
Console.WriteLine("10 * 5 = " + context.executeStrategy(10, 5));
context = new Context(new OperationDivision());
Console.WriteLine("10 / 5 = " + context.executeStrategy(10, 5));
}
运行结果
4. 适用场景分析
A. 一个系统需要动态地在几种算法中选择一种时可将每个算法封装到策略类中。
B. 一个类定义了多种行为并且这些行为在这个类的操作中以多个条件语句的形式出现可将每个条件分支移入它们各自的策略类中以代替这些条件语句。
C. 系统中各算法彼此完全独立且要求对客户隐藏具体算法的实现细节时。
D. 系统要求使用算法的客户不应该知道其操作的数据时可使用策略模式来隐藏与算法相关的数据结构。
E. 多个类只区别在表现行为不同可以使用策略模式在运行时动态选择具体要执行的行为。
原文链接https://www.cnblogs.com/yaopengfei/p/13444014.html