概述
在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。
注意
优点
1、算法可以自由切换。2、避免使用多重条件判断。3、扩展性良好。
缺点
1、策略类会增多。2、所有策略类都需要对外暴露。
使用场景
1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。2、一个系统需要动态地在几种算法中选择一种。3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。
注意事项
如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。
另外,小编所有文章均是自己亲手编写验证,由于文件太多,小编就不在公众号后台一一回复列举了,若需要小编的工程代码,请关注公众号,后台回复需要的工程文件。小编看到后会第一时间回复。
介绍
意图
定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。
主要解决
在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。
何时使用
一个系统有许多许多类,而区分它们的只是他们直接的行为。
如何解决
将这些算法封装成一个一个的类,任意地替换。
关键代码
实现同一个接口。
示例
★示例向用户展示策略模式通过C语言的实现方式。
★包含演示程序基类strategy.c、strategy.h以及应用程序strategy_app.c(已验证通过)。
strategy.h
/**
* @Filename : strategy.h
* @Revision : $Revision: 1.0 $
* @Author : Feng(更多编程相关的知识和源码见微信公众号:不只会拍照的程序猿,欢迎订阅)
* @Description : 策略模式基类(C语言模拟C++)
* @Explain : 策略模式,封装一系列相似算法
**/
#ifndef __STRATEGY_H__
#define __STRATEGY_H__
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* 类操作, 带参数 */
#define CLASS_CALL(THIS,func,args...) ((THIS)->func(THIS,args))
/* 类操作, 无参数 */
#define CLASS_CALL_0(THIS,func) ((THIS)->func(THIS))
/* 策略类定义 */
struct strategy {
void (*algorithm_interface)(void); /* 算法 */
};
/* 上下文类定义 */
struct context {
struct strategy *p_strategy; /* 算法类 */
void (*context_interface)(struct context *p_context);
};
/* 创建context对象 */
struct context *new_context(struct strategy *p_strategy);
#endi
strategy.c
/**
* @Filename : strategy.c
* @Revision : $Revision: 1.0 $
* @Author : Feng(更多编程相关的知识和源码见微信公众号:不只会拍照的程序猿,欢迎订阅)
* @Description : 策略模式基类(C语言模拟C++)
* @Explain : 策略模式,封装一系列相似算法
**/
#include "strategy.h"
/**
* @上下文类接口实现
* @p_context 类
**/
static void _context_interface(struct context *p_context)
{
if ((p_context == NULL) || (p_context->p_strategy == NULL))
return;
p_context->p_strategy->algorithm_interface();
}
/**
* @创建上下文类
* @p_strategy 算法类
* @返回类
**/
struct context *new_context(struct strategy *p_strategy)
{
static struct context *p_context = NULL;
if (p_strategy == NULL)
return NULL;
if ((p_context = (struct context *)malloc(sizeof(struct context))) == NULL)
return NULL;
p_context->p_strategy = p_strategy;
p_context->context_interface = _context_interface;
}
strategy_app.c
/**
* @Filename : strategy_app.c
* @Revision : $Revision: 1.0 $
* @Author : Feng(更多编程相关的知识和源码见微信公众号:不只会拍照的程序猿,欢迎订阅)
* @Description : 策略模式应用(C语言模拟C++)
* @Explain : 策略模式,封装一系列相似算法
**/
#include "strategy.h"
/**
* @ 算法a实现
**/
static void a_algorithm(void)
{
printf("this is a algorithm...\n");
}
/**
* @ 算法b实现
**/
static void b_algorithm(void)
{
printf("this is b algorithm...\n");
}
/**
* @ 算法c实现
**/
static void c_algorithm(void)
{
printf("this is c algorithm...\n");
}
/**
* @主函数,演示代码
**/
int main(void)
{
struct context *p_context = NULL;
struct strategy strategy_a, strategy_b, strategy_c; /* 具体算法策略类定义 */
strategy_a.algorithm_interface = a_algorithm;
strategy_b.algorithm_interface = b_algorithm;
strategy_c.algorithm_interface = c_algorithm;
/* 调用算法a */
p_context = new_context(&strategy_a);
CLASS_CALL_0(p_context, context_interface);
/* 调用算法b */
p_context = new_context(&strategy_b);
CLASS_CALL_0(p_context, context_interface);
/* 调用算法c */
p_context = new_context(&strategy_c);
CLASS_CALL_0(p_context, context_interface);
return 0;
}
验证
feng@feng-vm:~/share/OOP/strategy$ gcc -o strategy strategy_app.c strategy.c
feng@feng-vm:~/share/OOP/strategy$ ./strategy
this is a algorithm...
this is b algorithm...
this is c algorithm...
feng@feng-vm:~/share/OOP/strategy$
往期 · 推荐
实时系统vxWorks - 任务(重要)
实时系统vxWorks - 加载应用程序的方法
实时系统vxWorks - 在线调试
实时系统vxWorks - 虚拟机环境搭建
实时系统vxWorks - zynq7020移植vxWorks
关注
更多精彩内容,请关注微信公众号:不只会拍照的程序猿,本人致力分享linux、设计模式、C语言、嵌入式、编程相关知识,也会抽空分享些摄影相关内容,同样也分享大量摄影、编程相关视频和源码,另外你若想要获得更多内容教程请关注公众号:不只会拍照的程序猿。