好久没有更新博客了。近期也是在忙着充电,今天这篇博客開始,我们来了解一下设计模式。

设计模式

那什么是设计模式呢?首先来看看我从百科上copy下来的概念吧。

设计模式/软件设计模式(Design pattern)是一套被重复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更easy被他人理解、保证代码可靠性。

恩。大概的意思就是在撸码界由码神们总结的、能够解决软件设计中重复出现的问题的、由大多数人不论什么的设计方式,也能够说是一种编码规则。

初始编码我们总是依照自己的套路来写代码。等项目的代码量庞大了,需求又要改了,突然发现尼玛这个改起来好麻烦,好多文件要动,为了适合新的需求改动这个文件可能会对其它的业务逻辑产生影响,改动这个文件会不会引入bug?一系列的问题摆在了我们眼前,头疼、迷茫,有木有一种又一次写一遍的冲动?好了,假如你遇到了这样的情况。设计模式可能会解救你一部分。

但。对于设计模式还有非常多人很多其它沉迷于设计模式中,每写几行代码,都要考虑考虑-这里是不是须要个啥模式! 记住。模式是为了方便我们解决这个问题而总结出来的一套编码规则。并非我们不用设计模式代码的扩展性就一定差。选择使用模式还是要谨慎,大多数情况下还是要依靠需求的情景来考虑需不须要这样的模式,在决定使用之前一定要考虑好为什么要用这样的模式。

策略模式

好了,扯了这么多蛋,以下開始进入主题,进来我们首先来介绍一下策略模式。首先来看一下定义,

定义一系列算法,将每个算法封装起来。并让它们能够相互替换。策略模式让算法独立于使用它的客户而变化。

恩。这个定义看起来还是能够的,不像一些定义非得整的人看不懂才叫定义,随便还算好理解。只是我们还是要引入一个结构图来更加清晰的认识它。

看到这个结构图,大概可能或许会恍然大悟了。这不就是让我们针对接口编程了。恩是的,差点儿相同全部的设计模式都是要遵循针对接口编程这个规则,并且我们细致想一下,这里面还体现出了对扩展开发,对改动关闭(开闭原则) ,假设我们要添加一些规则,全然不用改动主业务流程。仅仅须要添加几个策略就ok,当然了。这些策略要遵循我们的接口规范。

代码实现

以下我们就開始以代码的形式来展示一下策略模式吧,代码非常easy,我们用一个加减乘除法来模拟。

首先,我们看到的将会是策略接口和一系列的策略,这些策略不要依赖高层模块的实现。

package strategy
/**
* 策略接口
*/
type Strategier interface {
Compute(num1, num2 int) int
}

非常easy的一个接口,定义了一个方法Compute。接受两个參数。返回一个int类型的值,非常easy理解。我们要实现的策略将会将两个參数的计算值返回。

接下来,我们来看一个我们实现的策略,

package strategy
import "fmt" type Division struct {} func (p Division) Compute(num1, num2 int) int {
defer func() {
if f := recover(); f != nil {
fmt.Println(f)
return
}
}() if num2 == 0 {
panic("num2 must not be 0!")
} return num1 / num2
}

为什么要拿除法作为代表呢?由于除法特殊嘛,被除数不能为0,其它的加减乘基本都是一行代码搞定,除法我们须要推断被除数是否为0,假设是0则直接抛出异常。

ok,主要的策略定义好了。我们还须要一个工厂方法,依据不用的type来返回不同的策略。这个type我们准备从命令好输入。

func NewStrategy(t string) (res Strategier) {
switch t {
case "s": // 减法
res = Subtraction{}
case "m": // 乘法
res = Multiplication{}
case "d": // 除法
res = Division{}
case "a": // 加法
fallthrough
default:
res = Addition{}
} return
}

这个工厂方法会依据不用的类型来返回不同的策略实现。当然。哪天我们须要新增新的策略,我们仅仅须要在这个函数中添加相应的类型推断就ok。

如今策略貌似已经完毕了。接下来我们来看看主流程代码。一个Computer,

package compute

import (
"fmt"
s "../strategy"
) type Computer struct {
Num1, Num2 int
strate s.Strategier
} func (p *Computer) SetStrategy(strate s.Strategier) {
p.strate = strate
} func (p Computer) Do() int {
defer func() {
if f := recover(); f != nil {
fmt.Println(f)
}
}() if p.strate == nil {
panic("Strategier is null")
} return p.strate.Compute(p.Num1, p.Num2)
}

这个Computer中有三个參数,Num1Num2当然是我们要操作的数了。strate是我们要设置的策略,可能是上面介绍的Division,也有可能是其它的,在main函数中我们会调用SetStrategy方法来设置要使用的策略,Do方法会运行运算,最后返回运算的结果,能够看到在Do中我们将计算的功能托付给了Strategier

貌似一切准备就绪,我们就来编写main的代码吧。

package main

import (
"fmt"
"flag"
c "./computer"
s "./strategy"
) var stra *string = flag.String("type", "a", "input the strategy")
var num1 *int = flag.Int("num1", 1, "input num1")
var num2 *int = flag.Int("num2", 1, "input num2") func init() {
flag.Parse()
} func main() {
com := c.Computer{Num1: *num1, Num2: *num2}
strate := s.NewStrategy(*stra) com.SetStrategy(strate)
fmt.Println(com.Do())
}

首先我们要从命令行读取要使用的策略类型和两个操作数。在main函数中,我们初始化Computer这个结构体,并将输入的操作数赋值给ComputerNum1Num2,接下来我们依据策略类型通过调用NewStrategy函数来获取一个策略,并调用ComputerSetStrategy方法给Computer设置上面获取到的策略。最后运行Do方法计算结果,最后打印。

就是这么简单。如今我们在命令行定位到main.go所在的文件夹。并运行一下命令来编译文件

go build main.go

继续运行命令

main -type d -num1 4 -num2 2

来尝试一下使用加法策略操作4和2这两个数,来看看结果怎样,

结果非常正确。换一个策略试试。来个乘法吧,运行命令

main -type m -num1 4 -num2 2

结果也是正确的。

总结

策略模式还是算比較easy理解的。策略模式的核心就是将easy变动的代码从主逻辑中分离出来,通过一个接口来规范它们的形式。在主逻辑中将任务托付给策略。这样做既降低了我们对主逻辑代码改动的可能性,也添加了系统的可扩展性。

一定要记得哦。我们的代码要往对扩展开发,对改动关闭这条设计原则上努力!

最后是本文的实例代码下载:http://download.csdn.net/detail/qibin0506/9415084

设计模式-策略模式(Go语言描写叙述)的更多相关文章

  1. 设计模式-适配器模式(Go语言描写叙述)

    在上一篇博客设计模式-策略模式(Go语言描写叙述)中我们用最简单的代码用go语言描写叙述了设计模式中的策略模式,用最简单的实例来描写叙述相信能够让刚開始学习的人能够非常轻松的掌握各种设计模式.继上篇博 ...

  2. 15. 星际争霸之php设计模式--策略模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  3. [.net 面向对象程序设计深入](24)实战设计模式——策略模式(行为型)

    [.net 面向对象程序设计深入](24)实战设计模式——策略模式(行为型) 1,策略模式定义 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它 ...

  4. linkin大话设计模式--策略模式

    linkin大话设计模式--策略模式 Strategy [ˈstrætədʒi]  策略 策略模式用于封装系列的算法,这些算法通常被封装在一个称为Context的类中,客户端程序可以自由的选择任何一种 ...

  5. [.net 面向对象程序设计深入](26)实战设计模式——策略模式 Strategy (行为型)

    [.net 面向对象程序设计深入](26)实战设计模式——策略模式 Strategy (行为型) 1,策略模式定义 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模 ...

  6. JS设计模式——策略模式

    设计模式高大上,业务代码用不上...平时用不上我们就可以忽略了吗? 非也,就像面试造火箭,工作拧螺丝一样.万一我们公司哪天要造火箭了,你得立马能上手. 同时,有些复杂的业务代码也可以用设计模式的思想去 ...

  7. 设计模式-策略模式(Strategy Model)

    1.概述     在开发过程中常常会遇到类似问题,实现一个功能的时候往往有多种算法/方法(策略),我们可以根据环境的不同来使用不同的算法或策略来实现这一功能.     如在人物比较排序的实现中,我们有 ...

  8. java设计模式 策略模式Strategy

    本章讲述java设计模式中,策略模式相关的知识点. 1.策略模式定义 策略模式,又叫算法簇模式,就是定义了不同的算法族,并且之间可以互相替换,此模式让算法的变化独立于使用算法的客户.策略模式属于对象的 ...

  9. [Head First设计模式]策略模式

    系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...

随机推荐

  1. Struts2SpringHibernate整合示例,一个HelloWorld版的在线书店(项目源码+详尽注释+单元测试)

    Struts2,Spring,Hibernate是Java Web开发中最为常见的3种框架,掌握这3种框架是每个Java Web开发人员的基本功. 然而,很多初学者在集成这3个框架的时候,总是会遇到各 ...

  2. java静态方法

    静态方法(全局方法)不能访问this(当前对象)它和类没有关系,会有逻辑错误,当调用静态方法的时候不需要创建对象 可以直接为boolean result = MyTest.isPrime();直接访问 ...

  3. NYIST 677 碟战

    碟战时间限制:2000 ms | 内存限制:65535 KB难度:4 描述知己知彼,百战不殆!在战争中如果被敌人掌握了自己的机密,失败是必然的.K国在一场战争中屡屡失败,就想到自己的某些城市可能会有敌 ...

  4. Unsupported major.minor version 51.0问题的解决

    在java编程的过程中,当用myeclipse软件打开别人写的代码时,遇到Unsupported major.minor version 51.0此类问题,实在是令人痛苦不堪.弄了整整一晚才搞清楚,我 ...

  5. windows编译ffmpeg出现gcc is unable to create an executable file 的普通情况

    近期有个朋友在编译ffmpeg的时候出现这个问题,他非常郁闷. 我就说,为什么我弄的时候就没问题呢??直接./configure +加上后面的參数 安全度过. 然后,我就想了,预计他的gcc的系统变量 ...

  6. google 搜索不跳中间页

    Array.prototype.slice.call(document.links,0).forEach(function(link){link.onmousedown = null}) 插件总失效 ...

  7. Android解决ScrollView视图导致其底部的布局栏被推到上边的问题

    近期有个xml布局文件,我说下大概意思: <ScrollView> ...... </ScrollView> <RelativeLayout> ...... < ...

  8. [JZOJ 5875] [NOIP2018提高组模拟9.20] 听我说,海蜗牛 解题报告(BFS+二分)

    题目链接: http://172.16.0.132/senior/#main/show/5875 题目: 题解: 注意这题只能经过开放的港口 我们考虑用vector存下每个点不能到的点,并把并让vec ...

  9. sql 跟踪

    目录 1 sql跟踪 1.1 alter session 1.2 DBMS_MONITOR 1.3 DBMS_SESSION 1.4 oradebug模式 1.5 触发器的模式启用sql 跟踪 1.6 ...

  10. Devexpress控件使用二:barManager

    1.拖放控件 2.两种按钮显示形式 1)上面是大图标,下面是说明 a.Add → Largebutton 注:勾选 Show DesignTime enancements 才会出现Add b.添加图片 ...