4

谁能给出一个结合使用设计模式 Composite 和 Chain of Responsibility 的实际例子?

谢谢

4

3 回答 3

4

一个非常实际的例子是 GUI 设计,例如使用 Qt 框架。

QObject 可以是单个对象或多个对象的组合。QObject(理想情况下)知道它们的父 QObject,因此它们也形成了责任链

示例:主窗口有一个对话框(一个 QObject)。该对话框有一个输入行和一个布局框(所有 QObjects)。布局框有 2 个按钮(所有 QObjects)。

按钮的事件(例如单击)将通过责任链传递,直到 QObject 可以处理该事件。

另一个方向也有效(由于复合设计)。对话框的 show() 将被传递给子对象,因此输入行和布局框以及按钮也将变得可见。

于 2016-08-03T10:04:09.433 回答
4

此示例结合了责任链命令复合,并利用了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
{
    // ...
}
于 2018-01-15T14:42:33.750 回答
2

一个实际的答案可能是不可能的,但我可以看到你会有责任链的组合。这是一个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 可以由链本身启动。尽管将它们打包可能会有所帮助。

于 2010-03-16T02:39:35.413 回答