使用 Map 实现策略模式

代码星冰乐

专注成就未来

首页 归档 关于

使用 Map 实现策略模式

Jan 16, 2020 | haifeiWu | Go | 阅读
文章目录
  1. 1. What?
  2. 2. Why ?
  3. 3. How ?
    1. 3.1. golang实现的”策略模式“
  4. 4. 小结
    1. 4.1. 使用 map 来实现策略模式的优点
    2. 4.2. 使用 map 来实现策略模式的缺点

作 者:haifeiWu
原文链接:https://www.hchstudio.cn/article/2020/4a72/
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。


由于版权原因,请阅读原文 --> 使用 Map 实现策略模式

关注我们

作 者:haifeiWu
原文链接:https://www.hchstudio.cn/article/2020/4a72/
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。

作 者:haifeiWu
原文链接:https://www.hchstudio.cn/article/2020/4a72/
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。

上篇文章在谈到优化代码的时候,有一部分涉及到了使用策略模式优化我们的代码,本篇文章将围绕策略模式谈谈自己的思考~

What?

总的来说,设计模式是对软件设计中普遍存在并且反复出现的各种问题,所提出的通用解决方案,是一系列编码经验的集合。

那么什么是策略模式呢?它是定义一个算法的系列,将其各个分装,并且使他们有交互性。策略模式使得算法在用户使用的时候能独立的改变。如下图所示
策略模式时区图

Why ?

  • 完成一项任务,往往可以有多种不同的方式,每一种方式称为一个策略,我们可以根据环境或者条件的不同选择不同的策略来完成该项任务。
  • 在软件开发中也常常遇到类似的情况,实现某一个功能有多个途径,此时可以使用一种设计模式来使得系统可以灵活地选择解决途径,也能够方便地增加新的解决途径。
  • 在软件系统中,有许多算法可以实现某一功能,如查找、排序等,一种常用的方法是硬编码(Hard Coding)在一个类中,如需要提供多种查找算法,可以将这些算法写到一个类中,在该类中提供多个方法,每一个方法对应一个具体的查找算法;当然也可以将这些查找算法封装在一个统一的方法中,通过if…else…等条件判断语句来进行选择。这两种实现方法我们都可以称之为硬编码,如果需要增加一种新的查找算法,需要修改封装算法类的源代码;更换查找算法,也需要修改客户端调用代码。在这个算法类中封装了大量查找算法,该类代码将较复杂,维护较为困难。
  • 除了提供专门的查找算法类之外,还可以在客户端程序中直接包含算法代码,这种做法更不可取,将导致客户端程序庞大而且难以维护,如果存在大量可供选择的算法时问题将变得更加严重。
  • 为了解决这些问题,可以定义一些独立的类来封装不同的算法,每一个类封装一个具体的算法,在这里,每一个封装算法的类我们都可以称之为策略(Strategy),为了保证这些策略的一致。

How ?

在软件编码中,实现策略模式需要我们定义各种策略类,但是在 go 中我们可以使用 map 来避免这一缺点,直接定义需要实现的策略方法即可。

一般情况下我们都是这样做,采用 if/else 来做我们的策略选择,然而当业务逻辑越来越复杂的时候,代码就会变得很臃肿,难以维护,比如这样的

1
2
3
4
5
6
7
8
if condition :
// doSomething
else if condition:
// doOtherthing
else if
// doAnOtherThing
else
// doAlotOfthing

golang实现的”策略模式“

策略模式的精髓是封装一组算法实现以供使用时的调度,golang 里面有一个很重要的语法糖就是 func() 方法变量,因此,在 golang 中实现类似策略模式的做法,不需要依赖于对象而进行,比如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package main
import (
"fmt"
)
var Strategy map[string]func(v ...interface{})
func init(){
Strategy := make(map[string]func(v ...interface{}))
Strategy["add"] = func(a int,b int) {
fmt.Println("a + b")
}
Strategy["reduce"] = func(a int,b int) {
fmt.Println("a - b")
}
Strategy["multiply"] = func(a int,b int) {
fmt.Println("a*b")
}
Strategy["divide"] = func(a int,b int) {
fmt.Println("a/b")
}
}

func main(){
Strategy["insert"]()
}

小结

使用 map 来实现策略模式的优点

策略模式的核心是封装一组算法实现特别是相似的算法实现,所以我们可以通过 map 来进行 KV 的约束,key 是客户端传进来的对应策略,用具体的算法实现 fun() 作为 value,这样无论是算法的封装还是调度都从业务场景中解耦了。

使用 map 来实现策略模式的缺点

当然,缺点就是如果需要扩展策略,就要到增加一个 Entry<K,V>,没有传统的实现方式中直接扩展一个实现了策略接口的对象那么方便,这两个还得看具体的项目取舍,一句老话,没有好坏,只有合适不合适,好的软件实现都是考虑到各种情况的折中。

关注我们

作 者:haifeiWu
原文链接:https://www.hchstudio.cn/article/2020/4a72/
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。

分享
MapReduce 的简单实现使用 Go 优化我们的接口
微信关注我们
分类
  • Android8
  • Go4
  • Java59
  • Kafka,Java1
  • Kotlin2
  • Linux1
  • MapReduce1
  • Python2
  • Raft1
  • Redis1
  • ThreadPoolExecutor1
  • go1
  • 工具1
  • 总结8
  • 旅游日记1
标签
Nginx ChanghuiN haifeiWu Android Java 设计模式 hexo Kotlin 算法 MySQL 源码解析 Python Redis golang web Kafka 配置中心 总结 性能优化 旅游日记 Shell Go 问题排查 译文 Docker Spring Boot 工具 学习笔记 WebFlux 性能测试 go 散列表 源码 netty Raft
最近文章
  • Kafka的日志复制机制
  • 从20到21
  • go 并发编程
  • 【译】了解Linux CPU负载-您何时应该担心?
  • Zookeeper 与分布式锁
  • 基于Redis的分布式锁到底安全吗?
  • 【译】Raft 学生指南
  • ThreadPoolExecutor 的简单梳理
  • MapReduce 的简单实现
  • 使用 Map 实现策略模式
福利专区
    免费SSL证书
      阿里云红包
        腾讯云专属福利
        Copyright © 2021 代码星冰乐. Powered by ChanghuiN. 版权所有 晋ICP备15001365号
        特别感谢: 云服务器服务商 、 CDN 服务商