聊一聊策略模式和状态模式
前言
在行为型设计模式中,策略模式和状态模式在结构上非常的类似,并且在逻辑简化,去耦合上都是一个很好的解决方案。
有些小伙伴经常会分不清两者的区别,本文将来聊聊这两种模式。
本章节用 typescript
进行书写。
相同点
本质上,策略模式和状态模式都是干同一个事情,那就是去耦合。换句话说,就是把关注点进行分离,干什么以及怎么干分别放在不同的地方实现,从而减少我们逻辑上的耦合,也让我们的程序不用陷入 if...else..
地狱中去。
策略模式
策略模式,就是用什么策略干什么事情。简单来说,策略模式就是我们定义了一系列的算法,算法间彼此独立可切换。而关于如何使用这些策略,则由上层调用者来进行实现,非常灵活。
举个栗子
我们知道每个人的职责是不同的,比方说,学生的工作就是学习,农民的工作就是务农,医生的工作就是救死扶伤。那么,对于不同的身份,我们可以赋予不同的策略算法。
策略
首先,我们需要定义一批策略方法。
interface Istrategies { [key: string]: () => any } const strategies: Istrategies = { student: function () { console.log('我在读书') }, doctor: function () { console.log('我在治病') }, farmer: function () { console.log('我在干农活') } }
我们使用了对象来模拟一些列的策略类,并实现了 Istrategies
接口。其次,我们要实现一个环境类,对外提供调用接口。
对外接口
interface IstrategiesCtx { work:(name: string) => void; } const strategiesCtx: IstrategiesCtx = (function () { return { work: function (name: string) { strategies[name] && strategies[name].call(this) } } })()
环境我们使用即时执行函数来模拟,导出接口。这样,我们就可以在任何地方随意切换使用了。
调用
strategiesCtx.work('student') strategiesCtx.work('farmer') strategiesCtx.work('doctor')
结果
状态模式
使用策略模式,我们想怎么切换怎么调用都行,强调了一个自主性。现在,我们希望自己维护一些状态,然后不再关心如何去调用了,也就是说我们把自主权转移给了第三方,而自己并不关心。
还是上面那个例子,我们分别对应着学生、医生和农民三个身份,不同身份状态下,我们都可以工作,只不过工作的东西就不一样了。
有限状态机
首先,我们实现一下我们的几种状态,内部维护状态,并且提供切换状态以及工作的接口。
interface IprofessionState { change(val: string): void work(): void } interface Ijob { work (): void } interface Istate { [key: string]: Ijob } const professionState: IprofessionState = (function() { let state = 'student' const _state: Istate = { student: { work: function () { console.log('我正在读书') } }, farmer: { work: function () { console.log('我正在干农活') } }, doctor: { work: function () { console.log('我在治病') } } } return { change: function (val) { state = val }, work: function () { _state[state] && _state[state].work.call(this) } } })()
其中,我们分别定义了三种状态,并且每一种状态都提供和一个 work
方法。其次,对外的 change
方法可以切换状态, 而 work
则是当前状态的工作方法。
调用
关于调用,我们可以实现一个 Person 类。
class Person { private role: any constructor (role) { this.role = role } change (roleName) { this.role.change(roleName) } handleWork () { this.role.work() } } const xiaoming = new Person(professionState) xiaoming.handleWork() xiaoming.change('doctor') xiaoming.handleWork() xiaoming.change('farmer') xiaoming.handleWork()
Person
内部持有 role
,持有状态。当我们调用 change
赋予不同的角色时,handleWork
会有不同的表现。
结果
总结
总的来说,策略模式和状态模式还是有很多的相似之处,它们在结构上有很多类似的地方,同时都是去耦合的绝佳方式。在我们日常开发中,善用这两种模式都能够很好的分离关注点,也可以避免很多 if
分支的使用。
不同的是,策略模式讲究一批策略算法可以灵活切换,并且彼此独立。在调用方式上也都是主观程序控制,主动调用不同的策略来实现不同的功能,不需要维护一个状态。
而状态模式最大不同在于,状态模式会维护一个状态,并且不关心当前使用了哪一个算法,只需要切换到不同的状态,行为自然不同。这里敲黑板,切换状态,改变行为。
在线直通车
共同学习,写下你的评论
评论加载中...
作者其他优质文章