這樣的時間間隔查詢不僅會消耗服務器上的大量資源,還會導致網絡流量超出實際需要。 盡管Java從第0天開始就支持Observer Pattern,但始終認為它不是最佳實現(請參閱Observer和Observable )。 進入JavaEE世界甚至會使事情復雜化。 但是,JavaEE6帶有替代方法。
JavaEE6提供了“ @Observable”注釋,作為Observer Pattern的現成的簡便實現。 讓我們訪問上一篇文章 ,并將其擴展為使用觀察者。
package com.devchronicles.observer;import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.enterprise.event.Event;
import javax.inject.Inject;/**** @author Murat Yener*/
@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class EventService {@Injectprivate String message;@Inject Event<String> event;public void startService(){System.out.println("start service call "+message);event.fire("this is my "+message);System.out.println("done...");}
}
將向EventService類注入String類型的Event對象,該事件對象可用于觸發String對象。 如果您沒有閱讀上一篇文章,則message對象是一個String,它將由工廠產生并注入到EventService類中。 為簡化起見,您可以在名為message的變量中鍵入任何字符串常量。
既然我們已經完成了可觀察部分,那么現在該創建一個觀察者來監聽我們的事件了。
package com.devchronicles.observer;import javax.ejb.Stateless;
import javax.enterprise.event.Observes;/**** @author Murat Yener*/
@Stateless
public class EventObserver {public void doLogging(@Observes String message){System.out.println("Observed:"+message);}
}
Observes注釋將方法標記為已觸發的String事件的觀察者。 如果運行服務器并啟動start service方法,您將認識到如何將字符串神奇地注入EventService類,然后將其觸發到EventObserver類將其嘲笑(觀察到)的位置。 令人驚訝的是,這是在JavaEE6中實現觀察者模式所需的全部。
如前所述,JavaEE6提供了一種簡單的方法來實現觀察者模式。 發布該帖子后,我收到了關于如何區分觸發和觀察到的字符串類型的幾個問題。
盡管在現實世界中,您可能不會觸發和觀察純字符串,但是您自己的對象將按其類型進行觀察,但是區分相同類型的對象并設置不同的觀察者來偵聽它們仍然很容易。
首先讓我們從區分純字符串的部分開始。
package com.devchronicles.observer;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.inject.Qualifier;/**** @author Murat Yener*/
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.PARAMETER})
public @interface MyEvent {Type value();enum Type{LOGGING, MESSAGE}
}
上面的接口將用作注釋,以標記要觸發的字符串,以后只需注釋相應的部分即可觀察到。
package com.devchronicles.observer;import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.enterprise.event.Event;
import javax.inject.Inject;/**** @author Murat Yener*/
@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class EventService {@Injectprivate String message;@Inject @MyEvent(MyEvent.Type.LOGGING)Event<String> event;@Inject @MyEvent(MyEvent.Type.MESSAGE)Event<String> anotherEvent;public void startService(){System.out.println("start service call "+message);event.fire("this is my "+message);System.out.println("done...");anotherEvent.fire("done with the service!");}
}
我們只添加具有所需類型的MyEvent批注,然后像以前一樣觸發事件。 標有紅色的部分就是我們在上一篇文章中添加的示例。
現在讓我們注釋觀察者部分。 同樣,我們將在前面的示例中添加紅色部分。
package com.devchronicles.observer;import javax.ejb.Stateless;
import javax.enterprise.event.Observes;/**** @author Murat Yener*/
@Stateless
public class EventObserver {public void doLogging(@Observes @MyEvent(MyEvent.Type.LOGGING) String message){System.out.println("Observed:"+message);}public void doLogging(@Observes @MyEvent(MyEvent.Type.MESSAGE) String message){System.out.println("Observed another type of message:"+message);}
}
那就是您甚至需要區分要觀察的相同類型對象的全部。
參考: JavaEE重新審視設計模式:觀察者 , JavaEE重新審視設計模式:觀察器來自JCG合作伙伴 Murat Yener的Developer Chronicles博客上的第2部分 。
翻譯自: https://www.javacodegeeks.com/2012/04/java-ee-revisits-design-patterns_17.html