由来与目的

在软件构建过程中,我们需要为某些对象建立一种通知依赖关系一个目标对象的状态发生变化。所有的依赖对象都将得到通知。如果这样的依赖关系过于紧密,将使软件不能很好的抵御变化。使用面向对象技术。可以将这种依赖关系弱化,并形成一种稳定的依赖关系。从而实现软件体系结构的松耦合。这种技术就是观察者模式。

这模式的定义就是定义对象间的一种一对多变化的依赖关系。你便当一个对象的状态发生变化时,所有依赖于他的对象都得到通知并自动更新。

观察者模式(Observer Pattern)是一种设计模式,它允许对象之间建立一种发布-订阅关系,一个对象的状态发生改变时,所有依赖它的对象都会自动收到通知并更新。这种模式的产生和使用主要是为了实现对象之间的解耦和高内聚低耦合的设计原则。

由来

观察者模式的由来可以追溯到软件开发中对模块化和解耦的需求。以下是观察者模式产生的一些背景和动机:

  1. 事件驱动的需求
    在许多应用中,需要根据某些事件的发生来执行特定的操作。例如,用户界面(UI)组件的状态变化需要通知其他组件以进行更新。这就需要一种机制来自动化这些通知过程。

  2. 解耦
    在软件系统中,模块之间的依赖关系过于紧密会导致代码难以维护和扩展。如果一个模块的变化需要手动修改所有依赖它的模块,那么代码将变得非常脆弱和难以管理。观察者模式通过引入一个发布者和多个订阅者的关系,可以减少模块之间的耦合度。

  3. 灵活性和扩展性
    观察者模式使系统具有更好的灵活性和可扩展性。当需要增加新的观察者时,无需修改发布者的代码,只需增加新的观察者即可。这种模式提供了一种在不修改已有代码的情况下扩展系统行为的方法。

目的

观察者模式的主要目的是:

  1. 解耦对象之间的依赖关系
    发布者(或称为被观察者)不需要了解具体的观察者是谁,只需维护一个观察者列表。当状态发生变化时,发布者只需通知观察者,而不需要了解观察者如何处理这些通知。

  2. 提高系统的灵活性和可扩展性
    新的观察者可以在运行时动态地添加或移除,而不影响发布者的代码。这样可以很容易地扩展系统的功能。

  3. 实现事件驱动的编程模型
    观察者模式可以很好地实现事件驱动的编程模型,使得当某个事件发生时,所有依赖这个事件的对象都能自动得到通知并作出相应的处理。

观察者模式的结构

在这里插入图片描述

观察者模式主要包括以下角色:

  1. Subject(发布者)
    维护一系列观察者对象的引用。它提供了注册(attach)、移除(detach)和通知(notify)观察者的方法。

  2. Observer(观察者)
    为那些在发布者状态改变时需要得到通知的对象定义一个更新接口。

  3. ConcreteSubject(具体发布者)
    具体的发布者对象,当它的状态发生变化时,会通知所有注册的观察者。

  4. ConcreteObserver(具体观察者)
    具体的观察者对象,它们在接收到通知后,会执行一些具体的更新操作。

示例

以下是一个简单的观察者模式的示例:

class Subject:
    def __init__(self):
        self._observers = []

    def attach(self, observer):
        if observer not in self._observers:
            self._observers.append(observer)

    def detach(self, observer):
        try:
            self._observers.remove(observer)
        except ValueError:
            pass

    def notify(self):
        for observer in self._observers:
            observer.update(self)

class Observer:
    def update(self, subject):
        pass

class ConcreteSubject(Subject):
    def __init__(self):
        super().__init__()
        self._state = None

    @property
    def state(self):
        return self._state

    @state.setter
    def state(self, value):
        self._state = value
        self.notify()

class ConcreteObserver(Observer):
    def update(self, subject):
        print(f"Observer: Subject's state has been updated to {subject.state}")

# 示例使用
subject = ConcreteSubject()
observer1 = ConcreteObserver()
observer2 = ConcreteObserver()

subject.attach(observer1)
subject.attach(observer2)

subject.state = 'New State'

在这个示例中,ConcreteSubject 是具体的发布者,当它的状态发生变化时,会通知所有注册的 ConcreteObserver。观察者在接收到通知后,会执行相应的更新操作。这样就实现了对象之间的解耦,提升了系统的灵活性和可扩展性。

总结

  • 使用面向对象的抽象观察者模式使得我们可以独立的改变目标与观察者,从而使二者之间的依赖关系达到松耦合。
  • 目标发送通知时无需指定观察者。通知可以携带通知信息作为参数会自动传播。
  • 观察着自己决定是否需要订阅通知目标对象对此一无所知。
  • 观察者模式是基于事件的UI框架中非常常用的设计模式。也是MVC模式的一个重要组成部分。

补充:

MVC(Model-View-Controller)模式是一种常用的软件设计模式,主要用于分离应用程序的不同关注点。它通过将应用程序划分为三个核心组件:模型(Model)、视图(View)和控制器(Controller),来提高应用程序的可维护性和可扩展性。下面将详细介绍MVC模式,并举例说明其应用。

MVC模式的组成

  1. Model(模型)

    • 功能:模型代表应用程序的核心数据和业务逻辑。它直接管理数据、逻辑和规则。
    • 职责:模型负责数据的获取、存储、处理和更新,并向视图和控制器提供数据。
    • 示例:在一个电商应用中,订单、产品、用户等都可以作为模型。
  2. View(视图)

    • 功能:视图负责呈现数据。它获取模型中的数据,并显示给用户。
    • 职责:视图只关心如何展示数据,而不涉及数据的处理逻辑。
    • 示例:在一个电商应用中,产品列表页面、订单详情页面等都可以作为视图。
  3. Controller(控制器)

    • 功能:控制器是模型和视图之间的中介。它接收用户输入,处理用户交互,并更新模型和视图。
    • 职责:控制器负责将用户的输入转换为模型的操作,并决定使用哪个视图来展示数据。
    • 示例:在一个电商应用中,处理用户下单操作的控制器、处理用户登录操作的控制器等都可以作为控制器。

MVC模式的工作流程

  1. 用户通过视图与应用程序交互,触发控制器中的操作。
  2. 控制器接收用户输入,处理业务逻辑,并可能对模型进行修改。
  3. 模型更新其状态后,通知视图进行更新。
  4. 视图获取模型的最新数据,并将其展示给用户。

这种分离使得开发者可以独立地开发、测试和维护每个组件,增强了代码的可读性和可维护性。

MVC模式的示例

下面是一个简单的Python MVC示例,模拟一个学生信息管理系统:

# Model
class Student:
    def __init__(self, roll_no, name):
        self.roll_no = roll_no
        self.name = name

# View
class StudentView:
    @staticmethod
    def print_student_details(student):
        print(f"Student Roll No: {student.roll_no}, Name: {student.name}")

# Controller
class StudentController:
    def __init__(self, model, view):
        self.model = model
        self.view = view

    def set_student_name(self, name):
        self.model.name = name

    def get_student_name(self):
        return self.model.name

    def set_student_roll_no(self, roll_no):
        self.model.roll_no = roll_no

    def get_student_roll_no(self):
        return self.model.roll_no

    def update_view(self):
        self.view.print_student_details(self.model)

# 使用示例
model = Student("1", "John Doe")
view = StudentView()
controller = StudentController(model, view)

controller.update_view()
controller.set_student_name("Jane Doe")
controller.update_view()

在这个示例中:

  • Student 类是模型,包含学生的基本信息。
  • StudentView 类是视图,负责展示学生的信息。
  • StudentController 类是控制器,处理对学生信息的修改,并更新视图。

MVC模式的优点

  1. 分离关注点:通过将数据、业务逻辑和显示分离,可以使每个部分更加清晰和独立,便于开发和维护。
  2. 可复用性:视图和模型可以被不同的控制器重用,从而提高代码的复用性。
  3. 可测试性:由于模型、视图和控制器是分开的,可以对它们进行独立的单元测试,提高了测试的效率和覆盖率。

MVC模式的应用场景

MVC模式广泛应用于桌面应用程序、Web应用程序和移动应用程序的开发。例如:

  • 在Web开发中,常见的框架如Django、Rails和ASP.NET都采用了MVC模式。
  • 在移动开发中,Android应用中的Activity/Fragment(视图)、ViewModel(控制器)和Model(模型)也遵循了MVC的思想。

MVC模式是软件开发中一种非常重要的设计模式,通过将应用程序的不同关注点分离,能够显著提高应用程序的可维护性、可扩展性和复用性。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐