复合+责任链的例子

时间:2010-03-16 02:01:53

标签: design-patterns composite chain-of-responsibility

任何人都可以提供一个使用设计模式Composite和Chain of Responsibility的实际例子吗?

由于

3 个答案:

答案 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
{
    // ...
}