【发布时间】:2020-12-07 16:08:59
【问题描述】:
有没有使用不适合责任链设计模式的装饰器设计模式的系统示例?
注意:我不是在寻找解释,我需要一个具体问题的示例。
【问题讨论】:
-
不,不是,我没有要求解释!我要求为我的具体问题举个例子。
标签: design-patterns decorator chain-of-responsibility
有没有使用不适合责任链设计模式的装饰器设计模式的系统示例?
注意:我不是在寻找解释,我需要一个具体问题的示例。
【问题讨论】:
标签: design-patterns decorator chain-of-responsibility
公平地说,在实际使用中,这两种模式密切相关,几乎无法区分。我通常只是指包装与 Decorators 相同类型的其他类的类。但是,如果我们必须坚持书中的定义,它们是不同的。
装饰器在之前和之后做一些事情,而责任链要么做一些事情或调用链中的下一个元素。
我最近在代码库中使用了这个小的装饰器图:
new EmailingReservationsRepository(
postOffice,
new LoggingReservationsRepository(
logger,
new SqlReservationsRepository(connStr)))
EmailingReservationsRepository、LoggingReservationsRepository 和 SqlReservationsRepository 都实现了相同的接口:
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);
}
当客户调用Create、EmailingReservationsRepository 时,首先会这样做:
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);
}
最后SqlReservationsRepository 将reservation 保存在关系数据库中。
您不能为此使用责任链,因为链中的每个元素都必须要么处理方法调用或传递它。它不能两者兼得;如果是这样,它就不再是责任链了。
在实践中,这两种模式之间的区别是模糊的,以至于我并不在乎。我只是将这些东西中的大部分称为装饰器,然后继续。
【讨论】: