本篇文章将介绍一种行为模式-策略模式,该模式在开发中也非常的常见。下边将介绍三个问题:
- 什么是策略模式?
- 使用策略模式的场景?
- 如何实现策略模式?
1. 什么是策略模式?
策略模式是一种行为模式,用于解决在程序运行过程中算法/行为动态调整变化的问题。这种模式需要提前定义好程序运行过程中需要用到的算法/行为,比如报表导出时格式的选择,算法之间可以相互的替换,算法的实现完全独立于业务代码,无需在业务代码中实现每一种算法,可以很大程度上简化代码,提高可读性。具有如下特点:
- 定义公共的抽象策略接口:接口定义抽象的算法方法;
- 定义具体的算法实现:不同的算法都要完全实现公共抽象策略接口;
- 定义上下文配置:接收一个策略参数,真正执行策实现;
- 客户端策略选择:客户端初始化制定的策略,并传递策略实例給上下文配置;
UML类图如下:
2. 使用策略模式的场景?
- 多种算法的变体:当需要使用多种算法变体,但每一种算法实现的功能基本一致时,例如:输出不同格式的报表、支持不同厂商实现短信发送功能、支持不同算法实现加解密、失败重试策略等。
- if-else分支过多:当判断条件过多的时候,可以使用策略模式实现重构。
- 访问控制:根据不同的用户实现不同的访问策略,支持不同的访问权限。
- 缓存策略:根据不同的场景使用响应的缓存策略,比如:LRU、LFU等。
- 排序算法:实现排序功能,支持堆排序、归并排序、快排等。
3. 策略模式实现
- Go代码实现
package main
import "fmt"
type Strategy interface {
Algorithm(filename string) error
}
type Json struct{}
func (j *Json) Algorithm(filename string) error {
file := filename + ".json"
fmt.Println("filename: ", file)
fmt.Println("json execute.")
return nil
}
type Text struct{}
func (t *Text) Algorithm(filename string) error {
file := filename + ".txt"
fmt.Println("filename: ", file)
fmt.Println("text execute.")
return nil
}
type Word struct{}
func (w *Word) Algorithm(filename string) error {
file := filename + ".word"
fmt.Println("filename: ", file)
fmt.Println("word execute.")
return nil
}
type Format struct {
filename string
}
func (f *Format) format(strategy Strategy) error {
return strategy.Algorithm(f.filename)
}
func main() {
fm := Format{
filename: "tt",
}
text := Text{}
err := fm.format(&text)
if err != nil {
return
}
fmt.Printf("\n")
json := Json{}
err = fm.format(&json)
if err != nil {
return
}
fmt.Printf("\n")
word := Word{}
err = fm.format(&word)
if err != nil {
return
}
fmt.Printf("\n")
}
结果输出:
filename: tt.txt
text execute.
filename: tt.json
json execute.
filename: tt.word
word execute.
- c++代码实现
c++中没有interface的概念,所以实现上和Go不太一样,需要使用纯虚函数来实现抽象接口的功能,策略子类需要重写/实现策略类的纯虚函数。
strategy.h
#include <iostream>
#ifndef LIVE_BROADCAST_STRATEGY_H
#define LIVE_BROADCAST_STRATEGY_H
namespace lb {
namespace pattern {
class Strategy {
public:
~Strategy() = default;
virtual void Algorithm() = 0;
};
class Text:public Strategy {
public:
void Algorithm() override {
std::cout << "text algorithm execute." << std::endl;
}
};
class Json:public Strategy {
public:
void Algorithm() override {
std::cout << "Json algorithm execute." << std::endl;
}
};
class Word:public Strategy {
public:
void Algorithm() override {
std::cout << "Word algorithm execute." << std::endl;
}
};
}
}
namespace lb {
namespace pattern {
class Formater {
public:
Formater(const std::shared_ptr<Strategy>& strategy): m_strategy(strategy) {};
~Formater() = default;
void format(std::string filename) {
m_strategy->Algorithm();
}
private:
std::shared_ptr<Strategy> m_strategy;
};
}
}
#endif //LIVE_BROADCAST_STRATEGY_H
strategy.cpp
#include "Strategy.h"
using namespace lb::pattern;
int main(int argc, const char** argv) {
Formater formaterText = *new Formater(static_cast<const std::shared_ptr<Strategy>>(new Text()));
formaterText.format("re");
Formater formaterJson = *new Formater(static_cast<const std::shared_ptr<Strategy>>(new Json()));
formaterJson.format("re");
Formater formaterWord = *new Formater(static_cast<const std::shared_ptr<Strategy>>(new Word()));
formaterWord.format("re");
}
结果输出:
text algorithm execute.
Json algorithm execute.
Word algorithm execute.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。