组合模式和责任链模式示例

4

有人能给出同时使用组合模式和责任链模式的实际示例吗?

谢谢

3个回答

4
一个非常实用的例子是GUI设计,例如使用Qt框架。
一个QObject可以是一个单独的对象或多个对象的组合体。QObjects(理想情况下)知道它们的父QObject,因此它们也形成了一个责任链
举个例子: 主窗口有一个对话框(QObject)。 对话框有一个输入行和一个布局框(所有QObjects)。 布局框有2个按钮(所有QObjects)。
事件传递到一个按钮上(例如点击)将通过责任链传递,直到找到一个QObject可以处理该事件。
另一方面也可以(由于组合设计)。对话框的show()会传递给子对象,所以输入行、布局框和按钮也会变为可见状态。

4

这个例子结合了 责任链模式命令模式组合模式,并利用在 .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
{
    // ...
}

2

实际上,可能无法给出一个确定的答案,但我可以看出你需要一系列责任链来完成任务。以下是一个Python示例:

>>> 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对象是性能监视器和异常监视器的组合体。每个组件都将返回所需责任链的一系列处理程序。虽然此示例实际上只是使更简单的责任链变得复杂,其中SomeSystem可以使用这些链初始化。但保持它们打包可能会有所帮助。

1
我在Steven Metsker和William Wake的《Java设计模式》一书中找到了一个很好的组合+责任链的例子。您可以在Google图书中阅读它。基本上,我们有机器、线路、舱位和工厂。工厂是舱位的组合,依此类推。在这一点上,我们得到了组合模式。从机器到工厂的每个元素都有一个负责该组件的工程师。但是,在某些情况下,简单的机器没有工程师,因此我们必须寻找其父级以找到他(CoR)。[] - Fabio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接