首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >复合+责任链示例

复合+责任链示例
EN

Stack Overflow用户
提问于 2010-03-16 10:01:53
回答 3查看 3.4K关注 0票数 4

有没有人能给出一个将设计模式组合和责任链一起使用的实际例子?

谢谢

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-08-03 18:04:09

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

QObject可以是单个对象,也可以是多个对象的组合。QObjects (理想情况下)知道他们的父QObject,所以他们也形成了一系列的责任。

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

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

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

票数 4
EN

Stack Overflow用户

发布于 2018-01-15 22:42:34

此示例结合了责任链、命令链和复合链,并利用了.NET熟悉的Try*方法风格。

给定命令和处理程序类型:

代码语言:javascript
复制
public interface IResults { }

public interface ICommand { }

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

给出几个IHandler实现:

代码语言:javascript
复制
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实现:

代码语言:javascript
复制
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;
    }
}

并在客户端代码中使用它:

代码语言:javascript
复制
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
}

通过使用泛型,类型参数化/约束也可以确保一定程度的安全性:

代码语言:javascript
复制
public interface IResults { }

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

public interface IHandler<TCommand, TResults>
    where TCommand : ICommand<TResults>
    where TResults : IResults
{
    // ...
}
票数 4
EN

Stack Overflow用户

发布于 2010-03-16 10:39:35

一个实际的答案可能是不可能的,但我知道在哪里你会有一个责任链的组合。下面是一个pythonish式的例子:

代码语言:javascript
复制
>>> 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
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2451672

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档