观察者模式-源码剖析

1.观察者模式的类图

在这里插入图片描述

1.1 发布者

发布者提供了观察者订阅(注册)以及取消订阅(取消注册)的接口,当事件来临时,发布者会遍历每个订阅者对象,并以此调用每一个订阅者的update通知方法。

1.2 订阅者

该接口通常仅包含一个update方法

2. 示例代码

#include <iostream>
#include <list>
#include <string>
/**
 * 定义抽象观察者类,仅包含一个update方法
 */
class IObserver {
 public:
  virtual ~IObserver(){};
  virtual void Update(const std::string &message_from_subject) = 0;
};
/**
 * 定义抽象subject基类
 */
class ISubject {
 public:
  virtual ~ISubject(){};
  virtual void Attach(IObserver *observer) = 0;
  virtual void Detach(IObserver *observer) = 0;
  virtual void Notify() = 0;
};

/**
 * The Subject owns some important state and notifies observers when the state
 * changes.
 * 此类为Subject类,当状态改变时,通知每一个观察者
 */

class Subject : public ISubject {
 public:
  virtual ~Subject() {
    std::cout << "Goodbye, I was the Subject.\n";
  }

  /**
   * The subscription management methods.
   * 注册观察者
   */
  void Attach(IObserver *observer) override {
    list_observer_.push_back(observer);
  }
  /**
   * 删除观察者
   */
  void Detach(IObserver *observer) override {
    list_observer_.remove(observer);
  }
  /**
   * 遍历观察者,通知每一个观察者,并将信息传递给每一个observer
   */
  void Notify() override {
    std::list<IObserver *>::iterator iterator = list_observer_.begin();
    HowManyObserver();
    while (iterator != list_observer_.end()) {
      (*iterator)->Update(message_);
      ++iterator;
    }
  }
 /**
   * 发布者的状态改变,即创建了一条信息,通知每一个观察者
   */
  void CreateMessage(std::string message = "Empty") {
    this->message_ = message;
    Notify();
  }
  /**
   * 统计观察者的数量
   */
  void HowManyObserver() {
    std::cout << "There are " << list_observer_.size() << " observers in the list.\n";
  }

  /**
   * Usually, the subscription logic is only a fraction of what a Subject can
   * really do. Subjects commonly hold some important business logic, that
   * triggers a notification method whenever something important is about to
   * happen (or after it).
   */
  void SomeBusinessLogic() {
    this->message_ = "change message message";
    Notify();
    std::cout << "I'm about to do some thing important\n";
  }

 private:
  std::list<IObserver *> list_observer_;
  std::string message_;
};
/**
   * 构造函数将发布者注册到观察者内部
   */
class Observer : public IObserver {
 public:
  Observer(Subject &subject) : subject_(subject) {
    this->subject_.Attach(this);
    std::cout << "Hi, I'm the Observer \"" << ++Observer::static_number_ << "\".\n";
    this->number_ = Observer::static_number_;
  }
  virtual ~Observer() {
    std::cout << "Goodbye, I was the Observer \"" << this->number_ << "\".\n";
  }

  void Update(const std::string &message_from_subject) override {
    message_from_subject_ = message_from_subject;
    PrintInfo();
  }
  /**
   * 观察者也有权限从发布者中取消订阅,同时更新发布者的观察者数目
   */
  void RemoveMeFromTheList() {
    subject_.Detach(this);
    std::cout << "Observer \"" << number_ << "\" removed from the list.\n";
  }
  void PrintInfo() {
    std::cout << "Observer \"" << this->number_ << "\": a new message is available --> " << this->message_from_subject_ << "\n";
  }

 private:
  std::string message_from_subject_;
  Subject &subject_;
  static int static_number_;
  int number_;
};

int Observer::static_number_ = 0;
/**
   * 客户端创建了一个发布者,5个观察者
   */
void ClientCode() {
  Subject *subject = new Subject;
  Observer *observer1 = new Observer(*subject);
  Observer *observer2 = new Observer(*subject);
  Observer *observer3 = new Observer(*subject);
  Observer *observer4;
  Observer *observer5;

  subject->CreateMessage("Hello World! :D");
  observer3->RemoveMeFromTheList();

  subject->CreateMessage("The weather is hot today! :p");
  observer4 = new Observer(*subject);

  observer2->RemoveMeFromTheList();
  observer5 = new Observer(*subject);

  subject->CreateMessage("My new car is great! ;)");
  observer5->RemoveMeFromTheList();

  observer4->RemoveMeFromTheList();
  observer1->RemoveMeFromTheList();

  delete observer5;
  delete observer4;
  delete observer3;
  delete observer2;
  delete observer1;
  delete subject;
}

int main() {
  ClientCode();
  return 0;
}

3. 项目源代码剖析

3.1 观察者抽象基类

该抽象基类仅有一个OnValueChanged的接口

class ValueChangeObserver : public virtual AceType {
    DECLARE_ACE_TYPE(ValueChangeObserver, AceType);

public:
    virtual void OnValueChanged(bool needFireChangeEvent = true, bool needFireSelectChangeEvent = true) = 0;

protected:
    ValueChangeObserver() = default;
    ~ValueChangeObserver() override = default;

    ACE_DISALLOW_COPY_AND_MOVE(ValueChangeObserver);
};

3.2 发布者类基类:模板类

该类提供了AddObserver,RemoveObserver的接口;SetValue用于判断传入的值是否发生改变,如果改变调用Notify接口:即通知每一个观察者调用OnValueChanged接口。
观察者用链表observers_进行存储。

template<class U>
class ValueChangeNotifier : public virtual AceType {
    DECLARE_ACE_TYPE(ValueChangeNotifier<U>, AceType);

public:
    void AddObserver(const WeakPtr<ValueChangeObserver>& observer)
    {
        observers_.emplace_back(observer);
    }

    void RemoveObserver(const WeakPtr<ValueChangeObserver>& observer)
    {
        observers_.remove(observer);
    }

    void SetValue(U&& newValue, bool needFireChangeEvent = true)
    {
        if (newValue == value_) {
            return;
        }

        preValue_ = value_;
        value_ = std::move(newValue);
        Notify(needFireChangeEvent);
    }

    void SetValue(const U& newValue, bool needFireChangeEvent = true)
    {
        if (newValue == value_) {
            return;
        }

        preValue_ = value_;
        value_ = newValue;
        Notify(needFireChangeEvent);
    }

    const U& GetValue() const
    {
        return value_;
    }

    const U& GetPreValue() const
    {
        return preValue_;
    }

private:
    void Notify(bool needFireChangeEvent = true)
    {
        auto iter = observers_.begin();
        while (iter != observers_.end()) {
            const auto& observer = iter->Upgrade();
            if (observer) {
                observer->OnValueChanged(needFireChangeEvent);
                iter++;
            } else {
                iter = observers_.erase(iter);
            }
        }
    }

    std::list<WeakPtr<ValueChangeObserver>> observers_;

    U value_;
    U preValue_;
};

3.3 ConCrete观察者类:RenderTextField

该类为具体的观察者类,继承了观察者基类。

在这里插入图片描述

拥有成员TextEditController ,通过该具体发布者类,注册观察者类以及当数据更新时通知注册的观察者类。

在这里插入图片描述

判断组件的值是否变化时IsValueUpdated,调用发布者的SetText,通知观察者进行更新数据。

在这里插入图片描述

观察者具体需要更新的事情是:
1.对输入框中的文本进行格式化
2.更新光标所选的文本区域
3.触发相应的回调事件

在这里插入图片描述

3.4 ConCrete发布者类:TextEditController

该类指定了发布者类的模板T为:TextEditingValue

class TextEditController : public ValueChangeNotifier<TextEditingValue> {
public:
    void SetText(const std::string& newText, bool needFireChangeEvent = true)
    {
        auto value = GetValue();
        value.text = newText;
        // Default set selection to the end of text is more consistent with the intuition of user.
        value.selection.Update(value.GetWideText().length());
        SetValue(std::move(value), needFireChangeEvent);
    }

    void SetHint(const std::string& hint)
    {
        auto value = GetValue();
        value.hint = hint;
        SetValue(std::move(value));
    }

    void SetSelection(const TextSelection& selection)
    {
        auto value = GetValue();
        value.selection = selection;
        SetValue(std::move(value));
    }

    void Clear()
    {
        SetValue(TextEditingValue());
    }

    const std::string& GetText() const
    {
        return GetValue().text;
    }

    const TextSelection& GetSelection() const
    {
        return GetValue().selection;
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
1) 优秀的程序应该是这样的:阅读时,感觉很优雅;新增功能时,感觉很轻松;运行时,感觉很快速,这就需要设计模式支撑。2) 设计模式包含了大量的编程思想,讲授和真正掌握并不容易,网上的设计模式课程不少,大多讲解的比较晦涩,没有真实的应用场景和框架码支撑,学习后,只知其形,不知其神。就会造成这样结果: 知道各种设计模式,但是不知道怎么使用到真实项目。本课程针对上述问题,有针对性的进行了升级 (1) 授课方式采用 图解+框架码分析的方式,让课程生动有趣好理解 (2) 系统全面的讲解了设计模式,包括 设计模式七大原则、UML类图-类的六大关系、23种设计模式及其分类,比如 单例模式的8种实现方式、工厂模式的3种实现方式、适配器模式的3种实现、代理模式的3种方式、深拷贝等3) 如果你想写出规范、漂亮的程序,就花时间来学习下设计模式吧课程内容和目标本课程是使用Java来讲解设计模式,考虑到设计模式比较抽象,授课采用 图解+框架码分析的方式1) 内容包括: 设计模式七大原则(单一职责、接口隔离、依赖倒转、里氏替换、开闭原则、迪米特法则、合成复用)、UML类图(类的依赖、泛化和实现、类的关联、聚合和组合) 23种设计模式包括:创建型模式:单例模式(8种实现)、抽象工厂模式、原型模式、建造者模式、工厂模式。结构型模式:适配器模式(3种实现)、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式(3种实现)。行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式)2) 学习目标:通过学习,学员能掌握主流设计模式,规范编程风格,提高优化程序结构和效率的能力。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Alex1_Code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值