本文,从无到有,一点点改进,最终为观察者模式。
版本一:原始代码
#include <iostream>
using namespace std;
//公众号
class Subscription {
public:
void publish() {
cout << "发布消息" << endl;
}
};
//普通用户
class User {
public:
};
int main()
{
User user;
Subscription subscription();
subscription.publish();
return 0;
}
版本二:实现公众号发布消息,自动通知用户,做某事。
#include <iostream>
using namespace std;
//普通用户
class User {
public:
//新增函数
void doSomething() {
cout << "User 做了一些事情" << endl;
}
};
//公众号
class Subscription {
public:
//修改构造函数
Subscription(User *user) : user(user) {}
//修改函数
void publish() {
cout << "发布消息" << endl;
user->doSomething();
}
private:
User *user;
};
int main()
{
User user;
Subscription subscription(&user);
subscription.publish();
return 0;
}
版本三:有很多User可以订阅公众号
#include <iostream>
#include <list>
using namespace std;
//普通用户
class User {
public:
void doSomething() {
cout << "User 做了一些事情" << endl;
}
};
//公众号
class Subscription {
public:
//新增增加删除方法
void insert(User *user) {
userList.push_back(user);
}
void remove(User *user) {
userList.remove(user);
}
//修改函数
void publish() {
cout << "发布消息" << endl;
for (auto &user : userList)
user->doSomething();
}
private:
list<User*> userList;
};
int main()
{
User user1, user2;
Subscription subscription;
subscription.insert(&user1);
subscription.insert(&user2);
subscription.publish();
return 0;
}
版本四:另一个类User2
也可以订阅Subscription
。
#include <iostream>
#include <list>
using namespace std;
//提取接口类
class IObserver {
public:
virtual void doSomething() = 0;
};
//普通用户
class User : public IObserver {
public:
void doSomething() override {
cout << "User 做了一些事情" << endl;
}
};
//新类
class User2 : public IObserver {
public:
void doSomething() override {
cout << "User2 做了一些事情" << endl;
}
};
//公众号
class Subscription {
public:
//入参改为接口类
void insert(IObserver *user) {
userList.push_back(user);
}
void remove(IObserver *user) {
userList.remove(user);
}
void publish() {
cout << "发布消息" << endl;
for (auto &user : userList)
user->doSomething();
}
private:
list<IObserver*> userList; //存放接口类
};
int main()
{
User user1;
User2 user2;
Subscription subscription;
subscription.insert(&user1);
subscription.insert(&user2);
subscription.publish();
return 0;
}
版本五:提取发布者的抽象部分
#include <iostream>
#include <list>
using namespace std;
//提取接口类
class IObserver {
public:
virtual void doSomething() = 0;
};
//普通用户
class User : public IObserver {
public:
void doSomething() override {
cout << "User 做了一些事情" << endl;
}
};
//新类
class User2 : public IObserver {
public:
void doSomething() override {
cout << "User2 做了一些事情" << endl;
}
};
//提取接口类
class IPublisher {
public:
virtual void insert(IObserver*) = 0;
virtual void remove(IObserver*) = 0;
virtual ~IPublisher() {}
protected:
virtual void notify() = 0;
};
//公众号
class Subscription : public IPublisher {
public:
//入参改为接口类
void insert(IObserver *user) override {
userList.push_back(user);
}
void remove(IObserver *user) override {
userList.remove(user);
}
void publish() {
cout << "发布消息" << endl;
notify();
}
protected:
void notify() override {
for (auto &user : userList)
user->doSomething();
}
private:
list<IObserver*> userList;
};
int main()
{
User user1;
User2 user2;
Subscription subscription;
subscription.insert(&user1);
subscription.insert(&user2);
subscription.publish();
return 0;
}
观察者模式要求:稳定部分:IObserver/IPublisher
,易变部分:User/User2/Subscription
。
版本三及以前,违背了依赖倒置原则,具体类Subscription
依赖具体类User
,而具体类和抽象类都要以来抽象类符合依赖倒置原则。
类图: