医药网站模板2007年怎么做网站

当前位置: 首页 > news >正文

医药网站模板,2007年怎么做网站,建站自学,湖州做网站公司有那几家1. 引言 在 C 软件与设计系列课程中#xff0c;观察者模式是一个重要的设计模式。本系列课程旨在深入探讨该模式的实现与优化。在之前的课程里#xff0c;我们已对观察者模式有了初步认识#xff0c;本次将在前两次课程的基础上#xff0c;进一步深入研究#xff0c;着重…

  1. 引言 在 C 软件与设计系列课程中观察者模式是一个重要的设计模式。本系列课程旨在深入探讨该模式的实现与优化。在之前的课程里我们已对观察者模式有了初步认识本次将在前两次课程的基础上进一步深入研究着重解决观察者生命周期问题提升代码的安全性、灵活性、可维护性和扩展性。
  2. 观察者模式基础回顾 2.1 基本概念 观察者模式包含主题Subject和观察者Observer两个核心概念。主题负责管理观察者列表当主题发生有趣的事情时会通知列表中的所有观察者。观察者则关注主题的状态变化当收到通知时会做出相应的反应。 2.2 首次实现 首次实现中我们创建了主题和观察者类。主题类可以添加、移除观察者并在状态变化时通知所有观察者。使用 std::forward_list 存储观察者指针通过遍历列表调用每个观察者的 notify 函数。示例代码创建了一个主题和三个观察者展示了添加、通知和移除观察者的过程。 #include iostream #include forward_list// 观察者类 class Observer { public:virtual void notify() 0;virtual ~Observer() default; };// 主题类 class Subject { private:std::forward_listObserver* observers; public:void addObserver(Observer* observer) {observers.push_front(observer);}void removeObserver(Observer* observer) {observers.remove(observer);}void notifyAll() {for (auto observer : observers) {observer-notify();}} };// 具体观察者类 class ConcreteObserver : public Observer { public:void notify() override {std::cout ConcreteObserver notified. std::endl;} };2.3 首次实现的优缺点 优点是基本实现了观察者模式的功能逻辑较为清晰。缺点是灵活性不足若要创建更多的观察者和主题需要创建不同的具体类缺乏扩展性。
  3. 改进实现添加接口提升扩展性 3.1 改进思路 为了提高代码的灵活性和可扩展性第二次实现为主题和观察者添加了接口。在 C 中通过创建基类类似抽象类来实现接口的功能。 3.2 主题接口ISubject和观察者接口IObserver // 观察者接口 class IObserver { public:virtual void onNotify() 0;virtual ~IObserver() default; };// 主题接口 class ISubject { public:virtual void attach(IObserver* observer) 0;virtual void detach(IObserver* observer) 0;virtual void notifyAll() 0;virtual ~ISubject() default; };3.3 具体实现类 3.3.1 具体观察者类Watcher #include iostream #include stringclass Watcher : public IObserver { private:std::string m_name; public:explicit Watcher(const std::string name) : m_name(name) {}void onNotify() override {std::cout Watcher - m_name std::endl;} };3.3.2 具体主题类SomeSubject #include forward_listclass SomeSubject : public ISubject { private:std::forward_listIObserver* m_observers; public:void attach(IObserver* observer) override {m_observers.push_front(observer);}void detach(IObserver* observer) override {m_observers.remove(observer);}void notifyAll() override {for (auto observer : m_observers) {observer-onNotify();}} };3.4 测试代码 int main() {SomeSubject subject;Watcher watcher1(Watcher-1);Watcher watcher2(Watcher-2);Watcher watcher3(Watcher-3);subject.attach(watcher1);subject.attach(watcher2);subject.attach(watcher3);subject.notifyAll();subject.detach(watcher3);std::cout std::endl;subject.notifyAll();return 0; }3.5 改进后的优点 通过使用接口现在可以创建不同类型的主题和观察者类只要它们继承自相应的接口并实现必要的函数。这使得代码更加灵活可以轻松扩展以适应不同的需求。同时接口的引入使得代码结构更加清晰不同的功能被封装在不同的类中提高了可维护性。
  4. 解决观察者生命周期问题利用 RAII 技术 4.1 问题提出 在现有代码中若一个观察者超出作用域被销毁但仍存在于主题的观察者列表中当主题调用 notifyAll 时会尝试访问已销毁的对象从而导致运行时错误。 4.2 利用 RAII 解决问题 4.2.1 思路 RAII 是 C 的重要特性通过对象的构造和析构自动管理资源。我们可以利用这一特性在 Watcher 的构造函数中自动将其注册到主题在析构函数中自动从主题移除避免手动管理带来的遗漏和错误。 4.2.2 代码实现 #include string #include ISubject.hclass Watcher : public IObserver { private:std::string m_name;ISubject m_subject; public:explicit Watcher(const std::string name, ISubject subject) : m_name(name), m_subject(subject) {m_subject.attach(this);}~Watcher() {m_subject.detach(this);}void onNotify() override {std::cout Watcher - m_name std::endl;} };4.2.3 修改测试代码 #include ISubject.h #include IObserver.h #include Watcher.h #include iostreamint main() {SomeSubject subject;Watcher watcher1(Watcher-1, subject);Watcher watcher2(Watcher-2, subject);{Watcher watcher3(Watcher-3, subject);} // watcher3 自动从主题移除subject.notifyAll();return 0; }4.3 项目文件分离 在实现过程中可能会遇到“不完整类型”的编译错误。为解决这个问题我们将项目分离为不同的头文件和实现文件。将 IObserver、Watcher、ISubject 和 SomeSubject 分别拆分为 .hpp 头文件和 .cpp 实现文件。在 main 函数中包含相应的头文件确保编译器能够获取完整的类型信息。 4.4 测试改进后的代码 修改后的代码编译时不再报错运行时也能正常工作。即使 Watcher 3 在新的作用域内创建和销毁主题在通知时也不会出现运行时错误因为 Watcher 3 已自动从主题的观察者列表中移除。
  5. 总结与展望 5.1 总结 通过本次课程我们从基础的观察者模式实现逐步优化添加接口提升了代码的灵活性和可维护性利用 RAII 技术解决了观察者生命周期问题提高了代码的安全性。关键在于理解观察者模式的核心概念掌握接口的使用和 RAII 技术的应用。 5.2 展望 当前代码使用了原始指针可考虑使用智能指针如 std::unique_ptr进一步优化避免内存泄漏。后续课程将继续为观察者模式添加更多功能完善该设计模式的实现。希望大家能将这些知识应用到实际项目中提升代码质量。