1. 概述
命令模式(Command)將類的業(yè)務(wù)行為以對(duì)象的方式封裝,以便實(shí)現(xiàn)行為的參數(shù)化、撤銷或重做等需求。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-729552.html
- 非命令模式的困惑:
類的行為在運(yùn)行時(shí)是以實(shí)例方法的形式調(diào)用的,當(dāng)方法執(zhí)行完畢并返回后,方法棧將會(huì)消除;方法的運(yùn)行狀態(tài)(主要指局部變量)保存在棧幀中,它會(huì)隨著方法棧的銷毀而丟失。當(dāng)方法的運(yùn)行狀態(tài)丟失時(shí),撤銷、重做等類似操作就很難順利實(shí)現(xiàn)。- 命令模式的優(yōu)勢(shì):
命令模式將目標(biāo)類的業(yè)務(wù)行為分離出去,并用單獨(dú)的對(duì)象類(稱為命令類)封裝。在程序運(yùn)行時(shí),被分離的業(yè)務(wù)行為作為一個(gè)獨(dú)立的對(duì)象存在,可以被存儲(chǔ)或參數(shù)化(作為參數(shù)在不同對(duì)象間傳遞),為實(shí)現(xiàn)該行為的撤銷、重做等提供支持。
1.1 角色
- Command(抽象命令):一般定義為接口,用來(lái)定義執(zhí)行的命令。
- ConcreteCommand(具體命令):通常會(huì)持有接收者對(duì)象,并調(diào)用接收者對(duì)象的相應(yīng)功能來(lái)完成命令要執(zhí)行的操作。
- Receiver(接收者):真正執(zhí)行命令的對(duì)象。任何類都可能成為接收者,只要它能夠?qū)崿F(xiàn)命令要求實(shí)現(xiàn)的相應(yīng)功能。
- Invoker(調(diào)用者):要求命令對(duì)象執(zhí)行請(qǐng)求,通常會(huì)持有命令對(duì)象,可以持有很多的命令對(duì)象。這個(gè)是客戶端真正觸發(fā)命令并要求命令執(zhí)行相應(yīng)操作的地方,也就是說(shuō)相當(dāng)于使用命令對(duì)象的入口。
- Client:創(chuàng)建具體的命令對(duì)象,并且設(shè)置命令對(duì)象的接收者。
1.2 類圖
2. 代碼示例
2.1 設(shè)計(jì)
- 定義一個(gè)抽象命令
Command
- 定義兩個(gè)具體命令
Start
和Stop
- 它實(shí)現(xiàn)了抽象命令
Command
- 它繼承了接收者
Service
- 它實(shí)現(xiàn)了抽象命令
- 定義一個(gè)接收者
Service
- 它有
Start()
和Stop()
兩個(gè)方法分別對(duì)應(yīng)它的啟動(dòng)和停止操作
- 它有
- 定義一個(gè)調(diào)用者
- 它是
Command
的聚合 - 它的AddCommand()方法將
Command
加入調(diào)用者 - 它的
Option()
方法執(zhí)行了加入它的命令
- 它是
- 調(diào)用
- 實(shí)例化一個(gè)接收者
- 實(shí)例化兩個(gè)具體命令
- 實(shí)例化一個(gè)執(zhí)行者,各命令加入執(zhí)行者
- 執(zhí)行執(zhí)行者的
Option()
方法 - 驗(yàn)證接收者狀態(tài)
2.2 代碼
- 代碼
package main
import "fmt"
// 創(chuàng)建抽象命令
type Command interface {
execute()
}
// 創(chuàng)建具體命令start
type Start struct {
Status bool
Service *Service
}
func (s *Start) execute() {
err := s.Service.start()
if err != nil {
s.Status = true
}
s.Status = false
}
// 定義具體命令Stop
type Stop struct {
Status bool
Service *Service
}
func (s *Stop) execute() {
err := s.Service.stop()
if err != nil {
s.Status = true
}
s.Status = false
}
// 定義接收者
type Service struct {
status string
}
func (s *Service) start() (err error) {
fmt.Println("執(zhí)行啟動(dòng)操作") //假裝執(zhí)行了操作,實(shí)際操作中如果有錯(cuò)這里會(huì)拋出
s.status = "Running"
return nil
}
func (s *Service) stop() (err error) {
fmt.Println("執(zhí)行停止操作") //假裝執(zhí)行了停止,實(shí)際操作中如果有錯(cuò)這里會(huì)拋出
s.status = "Exited"
return nil
}
func (s *Service) GetStatus() {
fmt.Printf("服務(wù)狀態(tài):%+v", s.status)
}
// 調(diào)用者
type Invoker struct {
commands []Command
}
func (i *Invoker) AddCommand(command ...Command) {
i.commands = append(i.commands, command...)
}
func (i *Invoker) option() {
for _, command := range i.commands {
command.execute()
}
}
func main() {
//實(shí)例化一個(gè)接收者
myService := &Service{}
//實(shí)例化一個(gè)具體命令
start := &Start{
Service: myService,
}
//實(shí)例化另一個(gè)具體命令
stop := &Stop{
Service: myService,
}
//實(shí)例化一個(gè)調(diào)用者
invoker := &Invoker{}
//將剛才實(shí)例化的命令加入調(diào)用者
invoker.AddCommand(stop, start)
//執(zhí)行操作
invoker.option()
//驗(yàn)證接受者狀態(tài)
myService.GetStatus()
}
- 輸出
執(zhí)行停止操作
執(zhí)行啟動(dòng)操作
服務(wù)狀態(tài):Running
2.3 類圖
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-729552.html
到了這里,關(guān)于《golang設(shè)計(jì)模式》第三部分·行為型模式-02-命令模式(Command)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!