【问题标题】:Decoration pattern used for creating JMSMessages / Where should the timeout start用于创建 JMSMessages 的装饰模式/超时应该从哪里开始
【发布时间】:2013-03-13 09:26:56
【问题描述】:

我开始构建一个消息传递框架,我决定使用装饰模式来创建 JMSMessages。

class BaseMessage implements Message { ... }

抽象装饰

class AbstractDecoration implements Message {
   Message message;

   public AbstractDecoration(Message message) {
      this.message = message
   }
}

装饰示例:

class JsonPayloadDecoration extends AbstractDecoration { ... }

用法示例:

...

IMessage m = new BaseMessage(...);
m = new ExpireDecoration(m, 10, TimeUnit.MINUTES);
m = new TextPayloadDecoration(m, "Text!");
m = new CorrelationDecoration(m, "123456");
m = new PriorityDecoration(m, 9);
m = new NonPersistentDecoration(m);
m = new QueueDestinationDecoration(m, "JMSTEST.DECORATIONTEST1");
m = new ErrorHandlerDecoration(m, errorhandler, 1000);

// requestor handles MessageProducers
// m.send will create the real JMSMessage and use the requestor
// to send the message with a MessageProducer
m.send(requestor);

起初,我想了解一下整个装修的想法,现在是我真正的问题。 ErrorHandlerDecorationerrorhandler 有超时。 timeout 应该什么时候开始?何时创建或何时调用m.send?我正在和我的同事争论这个问题。

【问题讨论】:

    标签: java design-patterns timeout decorator messaging


    【解决方案1】:

    消息发送时间过长不会触发“超时”吗?它可能应该在调用 send 时开始,除非构造函数正在执行除填充字段之外的特殊操作。

    关于您关于使用装饰器模式的智慧的问题:装饰器模式非常适合提供功能排列,这似乎是您的情况(但是,您的代码示例中不存在这种用法)。如果您只打算对消息应用一个装饰器,请考虑改用策略模式。

    还要小心相互排斥的装饰器。如果你有太多这些,跟踪哪些装饰器与哪些兼容可能会令人困惑。

    编辑以回应您的评论:确保不兼容的装饰器不一起使用的一种方法是获取到目前为止应用于对象的装饰器列表,并在您看到冲突时抛出异常.要获取装饰器列表,可以将此方法添加到 AbstractDecoration:

    List<AbstractDecoration> getDecorations() {
        List<AbstractDecoration> decorations;
        if (message instanceof AbstractDecoration) {
            decorations = ((AbstractDecoration) message).getDecorations();
        }
        else {
            decorations = new ArrayList<AbstractDecoration>();
        }
    
        decorations.add(this);
        return decorations;
    }
    

    因此,一旦您已经应用了装饰器列表,只需检查每个装饰器的 instanceof 以检测冲突。请注意,您必须在相关的互斥装饰器的两端都执行此操作,否则当装饰器以一个顺序而不是另一个顺序应用时,不会发生此验证。

    感觉有点像黑客。我不是装饰器模式的专家,所以我不知道解决这个问题的标准是什么;这是我当场想到的。

    编辑:在考虑了更多之后,在 AbstractDecoration 的构造函数中进行此验证可能更有意义。然后,您的规则是集中的,您甚至可以将它们委托给另一个类。

    【讨论】:

    • 感谢您的意见。你知道处理互斥装饰器的方法吗?我确实有一些装饰器,如果使用另一个装饰器,则不应使用它们。
    • 我为此目的构建了这个static &lt;T&gt; T getDecoration(Message m, Class&lt;T extends AbstractDecorator&gt; decoration)。它返回装饰的实例。问题是decoration 是否有多个。
    • 哦,这很聪明,我没想到。 “如果decoration 不止一个”是什么意思?有什么问题?您可以为每个互斥的 T 调用 getDecoration(m, T) 并检查它们是否存在吗?
    猜你喜欢
    • 2010-12-18
    • 2011-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多