装饰器 vs 责任链 DP

Decorator vs Chain of Responsibility DP

是否有使用不适合责任链设计模式的装饰器设计模式的系统示例?

注意:我不是在寻找解释,我需要针对我的具体问题的示例。

公平地说,在实际使用中,这两种模式密切相关,几乎无法区分。我通常只引用 类 来包装与 Decorators 相同类型的其他 类。但是,如果我们必须坚持书中的定义,它们是不同的。

装饰器在前后做一些事情,而责任链或者做一些事情或者调用链中的下一个元素。

我最近在代码库中使用了这个小装饰图:

new EmailingReservationsRepository(
    postOffice,
    new LoggingReservationsRepository(
        logger,
        new SqlReservationsRepository(connStr)))

EmailingReservationsRepositoryLoggingReservationsRepositorySqlReservationsRepository都实现了相同的接口:

public interface IReservationsRepository
{
    Task Create(int restaurantId, Reservation reservation);

    Task<IReadOnlyCollection<Reservation>> ReadReservations(
        int restaurantId, DateTime min, DateTime max);

    Task<Reservation?> ReadReservation(int restaurantId, Guid id);

    Task Update(int restaurantId, Reservation reservation);

    Task Delete(int restaurantId, Guid id);
}

当客户调用时,例如,CreateEmailingReservationsRepository 首先执行此操作:

public async Task Create(int restaurantId, Reservation reservation)
{
    await Inner.Create(restaurantId, reservation);
    await PostOffice.EmailReservationCreated(restaurantId, reservation);
}

在这种情况下,Inner 实例是 LoggingReservationsRepository 对象,它执行以下操作:

public async Task Create(int restaurantId, Reservation reservation)
{
    Logger.LogInformation(
        "{method}(restaurantId: {restaurantId}, reservation: {reservation})",
        nameof(Create),
        restaurantId,
        JsonSerializer.Serialize(reservation.ToDto()));
    await Inner.Create(restaurantId, reservation);
}

最后 SqlReservationsRepositoryreservation 保存在关系数据库中。

您不能为此使用责任链,因为链中的每个元素都必须或者处理方法调用 传下去。它不能两者兼顾;如果是,则不再是责任链。

在实践中,这两种模式之间的区别已经模糊到我不在乎的程度。我只是调用这些东西中的大部分 Decorators 然后继续。