1

I started to build a messaging framework and I decided to use the decoration pattern for creating JMSMessages.

class BaseMessage implements Message { ... }

Abstract decoration

class AbstractDecoration implements Message {
   Message message;

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

Decoration example:

class JsonPayloadDecoration extends AbstractDecoration { ... }

Usage example:

...

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

At first I would like to get some input about the whole decoration idea and now to my real question. The errorhandler of ErrorHandlerDecoration has a timeout. When should the timeout start? When it's created or when m.send is called? I am arguing with my colleagues about that.

4

1 回答 1

1

当消息发送时间过长时不会触发“超时”吗?它可能应该在send被调用时开始,除非构造函数正在做一些特殊的事情而不是填充字段。

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

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

编辑以回应您的评论:确保不兼容的装饰器不一起使用的一种方法是获取到目前为止应用于对象的装饰器列表,并在您看到冲突时抛出异常。要获取装饰器列表,可以将此方法添加到 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 的构造函数中进行此验证可能更有意义。然后,您的规则是集中的,您甚至可以将它们委托给另一个班级。

于 2013-03-13T10:44:10.277 回答