复合+责任链示例

发布于 2024-08-25 10:18:41 字数 49 浏览 6 评论 0原文

谁能给出一个结合使用设计模式“组合”和“责任链”的实际例子吗?

谢谢

Can anyone give a practical example of using the design patterns Composite and Chain of Responsibility together?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

久而酒知 2024-09-01 10:18:41

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

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

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

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

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

A very practical example is GUI design, for example with the Qt framework.

A QObject can be an individual object or a composite of more objects. QObjects (ideally) know their parent QObject, so they also form a chain of responsibility.

Example:
The main window has a dialog (a QObject).
The dialog has an input line and a layout-box (all QObjects).
The layout box has 2 buttons (all QObjects).

An event to a button (e.g. click) will be passed on through the chain of responsibility until an QObject can handle the event.

The other direction also works (due to the composite design). A show() to the dialog will be passed to the child-objects, so the input-line and the layout-box and the buttons will become visible too.

昨迟人 2024-09-01 10:18:41

此示例结合了责任链命令复合,并利用了熟悉的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
{
    // ...
}

This example combines Chain of Responsibility, Command, and Composite, and leverages the Try* method style familiar to .NET.

Given command and handler types:

public interface IResults { }

public interface ICommand { }

public interface IHandler
{
    Boolean TryHandle(ICommand command, out IResults results);
}

Given a few IHandler implementations:

public class FooHandler : IHandler
{
    public Boolean TryHandle(ICommand command, out IResults results)
    {
        // ...
    }
}

public class BarHandler : IHandler
{
    public Boolean TryHandle(ICommand command, out IResults results)
    {
        // ...
    }
}

And a composite IHandler implementation:

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;
    }
}

And using it in client code:

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
}

Through the use of generics, type parameterization/constraints can ensure a degree of safety too:

public interface IResults { }

public interface ICommand<TResults>
    where TResults : IResults
{
    // ...
}

public interface IHandler<TCommand, TResults>
    where TCommand : ICommand<TResults>
    where TResults : IResults
{
    // ...
}
残龙傲雪 2024-09-01 10:18:41

一个实际的答案可能是不可能的,但我可以看到你在哪里会有责任链的组成。这是一个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对象是一个performance_monitor和一个exception_monitor的组合。每个组合将返回一系列处理程序以实现所需的责任链。尽管这个例子实际上只是使更简单的责任链变得复杂,其中 SomeSystem 可以用链本身来启动。尽管将它们包装起来可能会有所帮助。

A practical answer may be impossible, but I can see where you would have a composition of chains of responsibility. Here's a pythonish example:

>>> 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)

So the SomeSystem object is a composite of a performance_monitor and an exception_monitor. Each of the composites will return a series of handlers for desired chain of responsibility. Although this example is really only complicating a simpler Chains of Responsibility, where the SomeSystem could be initiated with the chains themselves. Although keeping them packaged may be helpful.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文