1.观察者模式的类图
1.1 发布者
发布者提供了观察者订阅(注册)以及取消订阅(取消注册)的接口,当事件来临时,发布者会遍历每个订阅者对象,并以此调用每一个订阅者的update通知方法。
1.2 订阅者
该接口通常仅包含一个update方法
2. 示例代码
#include <iostream>
#include <list>
#include <string>
class IObserver {
public:
virtual ~IObserver(){};
virtual void Update(const std::string &message_from_subject) = 0;
};
class ISubject {
public:
virtual ~ISubject(){};
virtual void Attach(IObserver *observer) = 0;
virtual void Detach(IObserver *observer) = 0;
virtual void Notify() = 0;
};
class Subject : public ISubject {
public:
virtual ~Subject() {
std::cout << "Goodbye, I was the Subject.\n";
}
void Attach(IObserver *observer) override {
list_observer_.push_back(observer);
}
void Detach(IObserver *observer) override {
list_observer_.remove(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";
}
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;
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;
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;
}
};
|