任何人都可以提供一个使用设计模式Composite和Chain of Responsibility的实际例子吗?
由于
答案 0 :(得分:3)
一个非常实用的例子是GUI设计,例如使用Qt框架。
QObject可以是单个对象,也可以是更多对象的复合。 QObjects(理想情况下)知道他们的父QObject,因此他们也形成责任链。
实施例: 主窗口有一个对话框(一个QObject)。 该对话框有一个输入行和一个布局框(所有QObjects)。 布局框有2个按钮(所有QObjects)。
按钮的事件(例如点击)将通过责任链传递,直到QObject可以处理该事件。
另一个方向也有效(由于复合设计)。对话框的show()将传递给子对象,因此输入行和布局框以及按钮也将变为可见。
答案 1 :(得分:2)
一个实际的答案可能是不可能的,但我可以看到你将在哪里组成一系列责任。这是一个蟒蛇的例子:
>>> 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可以用链本身启动。虽然保持包装可能会有所帮助。
答案 2 :(得分:2)
此示例结合了责任链, Command 和 Composite ,并利用.NET熟悉的Try*
方法风格
给出命令和处理程序类型:
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
{
// ...
}