目录
在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活。
命令模式可以对发送者和接收者完全解耦,发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求。这就是命令模式的模式动机
一个事件触发器,点击地图地点触发场景传送;点击资料片播放过场动画
- // 抽象接收者类 Receiver
- UCLASS()
- class DESIGNPATTERNS_API UCmdReceiver : public UObject
- {
- GENERATED_BODY()
- public:
-
- virtual void Action() { check(0 && "You must override this"); }
- };
- // 具体接收者类 Receiver —— 场景传送
- UCLASS()
- class DESIGNPATTERNS_API ULevelPortal : public UCmdReceiver
- {
- GENERATED_BODY()
- public:
- virtual void Action() override {
- UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" 传送到下一个场景"));
- }
- };
- // 具体接收者类 Receiver —— 资料片播放
- UCLASS()
- class DESIGNPATTERNS_API UCutscene : public UCmdReceiver
- {
- GENERATED_BODY()
- public:
- virtual void Action() override {
- UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" 播放剧情动画"));
- }
- };
- // 抽象命令类
- UCLASS(Abstract)
- class DESIGNPATTERNS_API UCommand : public UObject
- {
- GENERATED_BODY()
- public:
-
- void SetReceiver(UCmdReceiver* pCmdReceiver) { m_pCmdReceiver = pCmdReceiver; }
-
- // 调用接收者的 Action
- virtual void Execute() {
- if (m_pCmdReceiver)
- {
- m_pCmdReceiver->Action();
- }
- }
- // virtual void undo()
-
- protected:
- UCmdReceiver *m_pCmdReceiver;
- };
- // 具体命令类 —— 场景传送命令
- UCLASS()
- class DESIGNPATTERNS_API UPortalCommand : public UCommand
- {
- GENERATED_BODY()
- public:
-
- // 可重载做些额外的工作
- //virtual void Execute() override { }
- };
- // 具体命令类 —— 资料片播放命令
- UCLASS()
- class DESIGNPATTERNS_API UCutsceneCommand : public UCommand
- {
- GENERATED_BODY()
- public:
-
- // 可重载做些额外的工作
- //virtual void Execute() override { }
- };
- UCLASS()
- class DESIGNPATTERNS_API ACommandActor : public AActor
- {
- GENERATED_BODY()
- public:
-
- void BeginPlay() override {
-
- // 创建接收者 场景传送
- ULevelPortal* LevelPortal = NewObject
(); -
- // 创建命令对象
- UPortalCommand* PortalCommand = NewObject
(); - PortalCommand->SetReceiver(LevelPortal);
-
- // this 当做调用者 Invoker
- PortalCommand->Execute();
-
- // 创建接收者 资料片播放
- UCutscene* Cutscene = NewObject
(); -
- // 创建命令对象
- UCutsceneCommand* CutsceneCommand = NewObject
(); - CutsceneCommand->SetReceiver(Cutscene);
-
- // this 当做调用者 Invoker
- CutsceneCommand->Execute();
- }
- };
LogTemp: Warning: ULevelPortal::Action 传送到下一个场景
LogTemp: Warning: UCutscene::Action 播放剧情动画