设计模式-观察者模式-C实现(已亲测)

代码展示了如何在C语言中实现观察者模式,包括创建观察者和被观察者接口,以及具体观察者的实现。主要功能有添加、删除观察者和通知观察者状态变化。在main函数中,创建并测试了该模式。

观察者模式是一种常见的设计模式,它允许对象在状态改变时自动通知它们的观察者。下面是一个使用 C 语言实现观察者模式的示例:

#include <stdio.h>
#include <stdlib.h>

// 观察者接口
typedef struct Observer {
    void (*update)(struct Observer*, int);
} Observer;

// 被观察者接口
typedef struct Subject {
    Observer** observers;
    int num_observers;
    void (*attach)(struct Subject*, Observer*);
    void (*detach)(struct Subject*, Observer*);
    void (*notify)(struct Subject*, int);
} Subject;

// 创建一个观察者
Observer* create_observer() {
    Observer* observer = malloc(sizeof(Observer));
    observer->update = NULL;
    return observer;
}

// 创建一个被观察者
Subject* create_subject() {
    Subject* subject = malloc(sizeof(Subject));
    subject->observers = NULL;
    subject->num_observers = 0;
    subject->attach = NULL;
    subject->detach = NULL;
    subject->notify = NULL;
    return subject;
}

// 将观察者添加到被观察者的观察者列表中
void attach(Subject* subject, Observer* observer) {
    subject->observers = realloc(subject->observers, (subject->num_observers + 1) * sizeof(Observer*));
    subject->observers[subject->num_observers++] = observer;
}

// 将观察者从被观察者的观察者列表中移除
void detach(Subject* subject, Observer* observer) {
    for (int i = 0; i < subject->num_observers; i++) {
        if (subject->observers[i] == observer) {
            for (int j = i; j < subject->num_observers - 1; j++) {
                subject->observers[j] = subject->observers[j + 1];
            }
            subject->num_observers--;
            subject->observers = realloc(subject->observers, subject->num_observers * sizeof(Observer*));
            break;
        }
    }
}

// 通知被观察者的所有观察者状态发生了改变
void notify(Subject* subject, int data) {
    for (int i = 0; i < subject->num_observers; i++) {
        subject->observers[i]->update(subject->observers[i], data);
    }
}

// 实现观察者接口的具体观察者
typedef struct ConcreteObserver {
    Observer base;
    int data;
} ConcreteObserver;

// 实现观察者接口的具体观察者的更新方法
void update(Observer* observer, int data) {
    ConcreteObserver* concrete_observer = (ConcreteObserver*)observer;
    concrete_observer->data = data;
    printf("Observer %p received data: %d\n", observer, data);
}

int main() {
    Subject* subject = create_subject();
    subject->attach = attach;
    subject->detach = detach;
    subject->notify = notify;

    Observer* observer1 = create_observer();
    observer1->update = update;
    ConcreteObserver concrete_observer1 = { *observer1, 0 };
    subject->attach(subject, (Observer*)&concrete_observer1);

    Observer* observer2 = create_observer();
    observer2->update = update;
    ConcreteObserver concrete_observer2 = { *observer2, 0 };
    subject->attach(subject, (Observer*)&concrete_observer2);

    subject->notify(subject, 123);

    subject->detach(subject, observer2);
    subject->notify(subject, 456);

    free(observer1);
    free(observer2);
    free(subject->observers);
    free(subject);

    return 0;
}


在上面的代码中,我们定义了一个 Observer 接口和一个 Subject 接口,然后实现了它们的具体实现。Observer 接口只有一个 update 方法,用于接收被观察者状态改变的通知。Subject 接口包括一个观察者列表和三个方法:attach 用于将观察者添加到列表中,detach 用于将观察者从列表中移除,notify 用于通知所有观察者状态发生了改变。我们还实现了一个具体的观察者 ConcreteObserver,它包含一个 Observer 成员和一个数据成员,用于存储被观察者状态的值。在 main 函数中,我们创建了一个被观察者和两个观察者,然后将这两个观察者添加到被观察者的观察者列表中。接着,我们调用了被观察者的 notify 方法,通知所有观察者状态发生了改变,并输出了观察者接收到的数据。最后,我们将一个观察者从列表中移除,再次调用 notify 方法,观察到只有一个观察者接收到了数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值