谁能给出一个结合使用设计模式 Composite 和 Chain of Responsibility 的实际例子?
谢谢
谁能给出一个结合使用设计模式 Composite 和 Chain of Responsibility 的实际例子?
谢谢
一个非常实际的例子是 GUI 设计,例如使用 Qt 框架。
QObject 可以是单个对象或多个对象的组合。QObject(理想情况下)知道它们的父 QObject,因此它们也形成了责任链。
示例:主窗口有一个对话框(一个 QObject)。该对话框有一个输入行和一个布局框(所有 QObjects)。布局框有 2 个按钮(所有 QObjects)。
按钮的事件(例如单击)将通过责任链传递,直到 QObject 可以处理该事件。
另一个方向也有效(由于复合设计)。对话框的 show() 将被传递给子对象,因此输入行和布局框以及按钮也将变得可见。
此示例结合了责任链、命令和复合,并利用了Try*
.NET 熟悉的方法样式。
给定命令和处理程序类型:
public interface IResults { }
public interface ICommand { }
public interface IHandler
{
Boolean TryHandle(ICommand command, out IResults results);
}
给定一些IHandler
实现:
public class FooHandler : IHandler
{
public Boolean TryHandle(ICommand command, out IResults results)
{
// ...
}
}
public class BarHandler : IHandler
{
public Boolean TryHandle(ICommand command, out IResults results)
{
// ...
}
}
和一个复合 IHandler
实现:
public class CompositeHandler : IHandler
{
public IList<IHandler> Handlers { get; } = new List<IHandler>();
public Boolean TryHandle(ICommand command, out IResults results)
{
foreach (var handler in this.Handlers) {
if (handler.TryHandle(command, out results)) {
return true;
}
}
results = null;
return false;
}
}
并在客户端代码中使用它:
var command = /* ... */;
var handler = new CompositeHandler();
handler.Handlers.Add(new FooHandler());
handler.Handlers.Add(new BarHandler());
IResults results;
if (handler.TryHandle(command, out results)) {
// handled
}
else {
// not handled
}
通过使用泛型,类型参数化/约束也可以确保一定程度的安全:
public interface IResults { }
public interface ICommand<TResults>
where TResults : IResults
{
// ...
}
public interface IHandler<TCommand, TResults>
where TCommand : ICommand<TResults>
where TResults : IResults
{
// ...
}
一个实际的答案可能是不可能的,但我可以看到你会有责任链的组合。这是一个pythonish示例:
>>> class DevelopmentPerformanceMonitor():
... def getPerformanceMonitorHandlers():
... return []
...
>>> class ProductionPerformanceMonitor():
... def getPerformanceMonitorHandlers():
... return [check_cpu_under_load, check_available_hd]
...
>>> class DevelopmentExceptionMonitor():
... def getExceptionHandlers():
... return [email_local_root, log_exception]
...
>>> class ProductionExceptionMonitor():
... def getExceptionHandlers():
... return [emails_system_admin, log_exception, create_ticket]
...
>>> class SomeSystem:
... pm = None # Performance Monitor
... em = None # Exception Monitor
... def __init__(self, performance_monitor, exception_monitor):
... pm = performance_monitor
... em = exception_monitor
... def on_exception(e):
... for handler in em.getExceptionHandlers():
... handler(e)
... def perform_performance_monitoring(s):
... for handler in pm.getPerformanceMonitorHandlers():
... handler(s)
所以 SomeSystem 对象是 performance_monitor 和 exception_monitor 的组合。每个组合都将为所需的责任链返回一系列处理程序。尽管此示例实际上只是使更简单的责任链复杂化,其中 SomeSystem 可以由链本身启动。尽管将它们打包可能会有所帮助。