目录
定义对象之间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象都得到通知并更新。
观察者模式又称

不适用UE4中的委托代理,自己实现一个消息通知
做一个核辐射检测和救援人员受影响的例子
- // 抽象观察者类
- UCLASS(Abstract)
- class DESIGNPATTERNS_API UObserver : public UObject
- {
- GENERATED_BODY()
- public:
-
- virtual void Update() PURE_VIRTUAL(UObserver::IsValid, );
- };
- // 具体观察者类 —— 工作人员
- UCLASS(Blueprintable, BlueprintType)
- class DESIGNPATTERNS_API UWorker : public UObserver
- {
- GENERATED_BODY()
- public:
-
- // 设置核辐射监测对象
- void SetNuclearRadiation(UNuclearRadiation* pNuclearRadiation) {
- m_pNuclearRadiation = pNuclearRadiation;
- }
-
- virtual void Update() override {
- if (m_pNuclearRadiation)
- {
- int32 CurrentLevel = m_pNuclearRadiation->GetRadiationDegree();
- if (CurrentLevel < 1)
- {
- UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" %s报告: 生命体征正常"), *this->GetName());
- }
- else if (CurrentLevel < 2)
- {
- UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" %s报告: 轻级损伤"), *this->GetName());
- }
- else if (CurrentLevel < 4)
- {
- UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" %s报告: 中级损伤"), *this->GetName());
- }
- else if (CurrentLevel < 6)
- {
- UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" %s报告: 重级损伤"), *this->GetName());
- }
- else if (CurrentLevel < 8)
- {
- UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" %s报告: 极重级损伤"), *this->GetName());
- }
- else
- {
- UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" %s已无生命体征"), *this->GetName());
- this->ConditionalBeginDestroy();
- // 不要在此处取消订阅,否则影响TArray遍历
- }
- }
- }
-
- private:
- UNuclearRadiation* m_pNuclearRadiation;
- };
- // 抽象目标类
- UCLASS(Abstract)
- class DESIGNPATTERNS_API USubject : public UObject
- {
- GENERATED_BODY()
- public:
-
- // 添加订阅者
- virtual void BindNotify(UObserver* Observer) {
- if (!ObserverList.Contains(Observer)) {
- ObserverList.Add(Observer);
- UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" %s 已订阅"), *Observer->GetName());
- // 第一次绑定 获取当前数据
- Observer->Update();
- }
- }
-
- // 移除订阅者
- virtual void UnbindNotify(UObserver* Observer) {
- if (ObserverList.Contains(Observer)) {
- UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" %s 已取消订阅"), *Observer->GetName());
- ObserverList.Remove(Observer);
- }
- }
-
- // 通知
- virtual void Notify() {
- for (auto It = ObserverList.CreateConstIterator(); It; It++)
- {
- if (IsValid(*It))
- {
- (*It)->Update();
- }
- }
- }
-
- protected:
- TArray
ObserverList; - };
- // 具体目标类 —— 辐射地带、辐射监测
- UCLASS(Blueprintable, BlueprintType)
- class DESIGNPATTERNS_API UNuclearRadiation : public USubject
- {
- GENERATED_BODY()
- public:
- // 更新辐射程度
- void UpdateRadiationDegree(int32 pLevel) {
- m_pLevel = pLevel;
- Notify();
- }
-
- // 获取辐射程度
- int32 GetRadiationDegree() {
- return m_pLevel;
- }
-
- private:
- // 辐射程度 1-9级
- int32 m_pLevel;
- };
测试
- // 调用测试用的Actor
- UCLASS()
- class DESIGNPATTERNS_API AObserverActor : public AActor
- {
- GENERATED_BODY()
- public:
-
- void BeginPlay() override {
-
- // 创建核辐射监测
- UNuclearRadiation* NuclearRadiation = NewObject
(); -
- // 创建救援人员、监测核辐射程度
- UWorker* Worker0 = NewObject
(); - Worker0->SetNuclearRadiation(NuclearRadiation);
- NuclearRadiation->BindNotify(Worker0);
-
- UWorker* Worker1 = NewObject
(); - Worker1->SetNuclearRadiation(NuclearRadiation);
- NuclearRadiation->BindNotify(Worker1);
-
- UWorker* Worker2 = NewObject
(); - Worker2->SetNuclearRadiation(NuclearRadiation);
- NuclearRadiation->BindNotify(Worker2);
-
- // 核辐射升级
- NuclearRadiation->UpdateRadiationDegree(1);
- NuclearRadiation->UpdateRadiationDegree(2);
- NuclearRadiation->UpdateRadiationDegree(3);
-
- // 有人先出来了,取消核辐射继续影响
- NuclearRadiation->UnbindNotify(Worker2);
-
- // 核辐射继续升级
- NuclearRadiation->UpdateRadiationDegree(5);
- NuclearRadiation->UpdateRadiationDegree(7);
- NuclearRadiation->UpdateRadiationDegree(9);
-
- GEngine->ForceGarbageCollection(true);
- }
- };
LogTemp: Warning: USubject::BindNotify Worker_0 已订阅
LogTemp: Warning: UWorker::Update Worker_0报告: 生命体征正常LogTemp: Warning: USubject::BindNotify Worker_1 已订阅
LogTemp: Warning: UWorker::Update Worker_1报告: 生命体征正常LogTemp: Warning: USubject::BindNotify Worker_2 已订阅
LogTemp: Warning: UWorker::Update Worker_2报告: 生命体征正常LogTemp: Warning: UWorker::Update Worker_0报告: 轻级损伤
LogTemp: Warning: UWorker::Update Worker_1报告: 轻级损伤
LogTemp: Warning: UWorker::Update Worker_2报告: 轻级损伤LogTemp: Warning: UWorker::Update Worker_0报告: 中级损伤
LogTemp: Warning: UWorker::Update Worker_1报告: 中级损伤
LogTemp: Warning: UWorker::Update Worker_2报告: 中级损伤LogTemp: Warning: UWorker::Update Worker_0报告: 中级损伤
LogTemp: Warning: UWorker::Update Worker_1报告: 中级损伤
LogTemp: Warning: UWorker::Update Worker_2报告: 中级损伤LogTemp: Warning: USubject::UnbindNotify Worker_2 已取消订阅
LogTemp: Warning: UWorker::Update Worker_0报告: 重级损伤
LogTemp: Warning: UWorker::Update Worker_1报告: 重级损伤LogTemp: Warning: UWorker::Update Worker_0报告: 极重级损伤
LogTemp: Warning: UWorker::Update Worker_1报告: 极重级损伤LogTemp: Warning: UWorker::Update Worker_0已无生命体征
LogTemp: Warning: UWorker::Update Worker_1已无生命体征