头图

本篇文章将介绍一种行为模式-策略模式,该模式在开发中也非常的常见。下边将介绍三个问题:

  • 什么是策略模式?
  • 使用策略模式的场景?
  • 如何实现策略模式?

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.

TimeWtr
1 声望0 粉丝

引用和评论

0 条评论