观察者模式---Observer

观察者模式—Observer

1.模式定义:

观察者模式(Observer ):定义对象间一种一对多的依赖关系,每当一个被观察对象状态改变时,则通知所有监听的观察者。

2.模式结构

  • Observer:观察者
  • ConcreteObserver:具体观察者
  • Subject:被观察者
  • ConcreteSubject、ConcreteSubjectB:具体被观察者
    观察者模式类图

3.代码分析

  • 3.1 main.cpp
#include"concrete_observer.hpp"
#include"concrete_subject.hpp"
#include<iostream>
using namespace std;


int main(int argc, const char** argv) {
    ConcreteSubject cs;
    ConcreteObserver* co = new ConcreteObserver();
    ConcreteObserverB* cob = new ConcreteObserverB();

    cout << "===========================" << endl;
    cs.Attach(co);
    cs.Attach(cob);
    cs.DoSomething();

    cout << "===========================" << endl;
    cs.Detach(cob);
    cs.DoSomething();
    cout << "===========================" << endl;

    return 0;
}
  • 3.2 观察者: observer.hpp
#ifndef OBSERVER_HPP
# define OBSERVER_HPP

// 抽象观察者接口
class Observer
{
public:
    virtual ~Observer(){}
    virtual void Update() = 0;
};

#endif // OBSERVER_HPP
  • 3.3 具体观察者: concreteObserver.hpp
#ifndef CONCRETE_OBSERVER_HPP
# define CONCRETE_OBSERVER_HPP

#include<iostream>
#include"observer.hpp"
using namespace std;

// 具体观察者
class ConcreteObserver: public Observer
{
public:
    ConcreteObserver(){}
    ~ConcreteObserver(){}

    void Update() {
        cout << "ConcreteObserver::Update" << endl;
    }
};

// 具体观察者B
class ConcreteObserverB: public Observer
{
public:
    ConcreteObserverB(){}
    ~ConcreteObserverB(){}

    void Update() {
        cout << "ConcreteObserverB::Update" << endl;
    }
};

#endif // CONCRETE_OBSERVER_HPP

  • 3.4 被观察者: subject.hpp
#ifndef SUBJECT_HPP
# define SUBJECT_HPP

#include<iostream>
#include"observer.hpp"
using namespace std;

//  抽象被观察者接口
class Subject
{
public:
    virtual ~Subject(){}
    virtual void Attach(Observer* o) = 0;
    virtual void Detach(Observer* o) = 0;
    virtual void Notify() = 0;
};

#endif // SUBJECT_HPP
  • 3.5 具体被观察者: concreteSubject.hpp
#ifndef CONCRETE_SUBJECT_HPP
# define CONCRETE_SUBJECT_HPP

#include<iostream>
#include<map>
#include"subject.hpp"
#include"observer.hpp"
using namespace std;

class ConcreteSubject: public Subject
{
private:
    map<Observer*, bool> m_observers; // 观察者
public:
    ConcreteSubject(){}

    ~ConcreteSubject(){
        for (auto iter = m_observers.begin(); iter != m_observers.end(); ++iter) {
            delete iter->first;
        }
        m_observers.clear();
    }

    void Attach(Observer* o){
        m_observers[o] = true;
    }

    void Detach(Observer* o){    
        auto it = m_observers.find(o);
        if (it != m_observers.end()) {
            m_observers.erase(it);
        }
    }

    void Notify(){
       for (auto it = m_observers.begin(); it != m_observers.end(); ++it) {
            it->first->Update();
       }
    }

    void DoSomething() {
        Notify();
    }
};

#endif // CONCRETE_SUBJECT_HPP
  • 3.6 实验结果:
===========================
ConcreteObserver::Update
ConcreteObserverB::Update
===========================
ConcreteObserver::Update
===========================

4.优缺点

  • 4.1 优点

    • 4.1.1 观察者模式可以实现表示层和数据逻辑层的分离,并定义了稳定的消息更新传递机制,抽象了更新接口,使得可以有各种各样不同的表示层作为具体观察者角色。
    • 4.1.2 观察者模式在观察目标和观察者之间建立一个抽象的耦合
    • 4.1.3 观察者模式支持广播通信。
    • 4.1.4 观察者模式符合“开闭原则”的要求。
  • 4.2 缺点

    • 4.2.1 如果一个观察目标对象有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间,设计时建议被观察者执行单一职责原则。
    • 4.2.2 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。

5.模式分析

  • 5.1 观察者模式是将观察者和被观察者分离,并抽象出两个抽象类,使它们之间建立一种抽象耦合关系,使观察者扩展容易,以满足设计原则之开闭原则;

  • 5.2 观察者模式又名订阅发布模式,具体被观察者实现了订阅的设置与取消,客户端可以动态灵活的开启和关闭订阅;

  • 5.3 观察者模式是解决的一种一对多的关系,一(被观察者)变话,多(观察者)接受到变化通知。

6.实例:各种斯监视韩非子(go代码实现)

  • 类图:
    在这里插入图片描述

  • 6.0: main.go

package main

import (
	"fmt"
	"./observer"
)

func test_observer() {
	fmt.Println("==================")
	hanfeizi := observer.NewHanFeiZi()
	lisi := observer.NewLiSi()
	liusi := observer.NewLiuSi()
	wangsi := observer.NewWangSi()
	hanfeizi.AddObserver(lisi)
	hanfeizi.AddObserver(liusi)
	hanfeizi.HaveBreakfase()
	fmt.Println("==================")
	hanfeizi.DeleteObserver(liusi)
	hanfeizi.AddObserver(wangsi)
	hanfeizi.HaveFun()
	fmt.Println("==================")
}

func main() {
	test_observer()
}
  • 6.1:被观察者韩非子接口:ihanfeizi.go
package observer

// 被观察者韩非子接口
type IHanFeiZi interface {
	HaveBreakfast()
	HaveFun()
}

// 被观察者接口
type IObservable interface {
	AddObserver(observer IObserver)
	DeleteObserver(observer IObserver)
	NotifyObservers(context string)
}

  • 6.2: 被观察者-韩非子:hanfeizi.go
package observer

import "fmt"

// 被观察者-韩非子
type HanFeiZi struct {
	Observers map[IObserver]bool // 观察者
}

func NewHanFeiZi() *HanFeiZi {
	return &HanFeiZi{
		Observers: map[IObserver]bool{},
	}
}

func (hfz *HanFeiZi) HaveBreakfase() {
	fmt.Println("HanFeiZi::HaveBreakfase")
	hfz.NotifyObservers("HanFeiZi::HaveBreakfase")
}

func (hfz *HanFeiZi) HaveFun() {
	fmt.Println("HanFeiZi::HaveFun")
	hfz.NotifyObservers("HanFeiZi::HaveFun")
}

func (hfz *HanFeiZi) AddObserver(observer IObserver) {
	hfz.Observers[observer] = true
}

func (hfz *HanFeiZi) DeleteObserver(observer IObserver) {
	delete(hfz.Observers, observer)
}

func (hfz *HanFeiZi) NotifyObservers(context string) {
	for observer := range hfz.Observers {
		observer.Update(context)
	}
}

  • 6.3: 观察者接口:iobserver.go
package observer

// 观察者接口
type IObserver interface {
	Update(context string)
}

  • 6.4: 真实观察者:observer.go
package observer

import "fmt"

// 真实的观察者-李斯
type LiSi struct {
}

func NewLiSi() *LiSi {
	return &LiSi{}
}

func (ls *LiSi) Update(context string) {
	fmt.Println("LiSi::Update ", context)
}

// 真实观察者-刘斯
type LiuSi struct {
}

func NewLiuSi() *LiuSi {
	return &LiuSi{}
}

func (ls *LiuSi) Update(context string) {
	fmt.Println("LiuSi::Update ", context)
}

// 真实观察者-王斯
type WangSi struct {
}

func NewWangSi() *WangSi {
	return &WangSi{}
}

func (ls *WangSi) Update(context string) {
	fmt.Println("WangSi::Update ", context)
}
  • 6.5 执行结果:
==================
HanFeiZi::HaveBreakfase
LiSi::Update  HanFeiZi::HaveBreakfase 
LiuSi::Update  HanFeiZi::HaveBreakfase
==================
HanFeiZi::HaveFun
LiSi::Update  HanFeiZi::HaveFun       
WangSi::Update  HanFeiZi::HaveFun     
==================

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值