<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Java Votary

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      48 隨筆 :: 1 文章 :: 80 評論 :: 0 Trackbacks
    轉載自TheServerSide網站,介紹使用Spring來創建Observer模式。
    http://www.theserverside.com/articles/article.tss?l=SpringLoadedObserverPattern
     

    This article describes an easy process of implementing the observer pattern in the Spring framework (Spring Core). Also discussed in this article are a few of the Spring Core classes as well as an easy way to start the Spring Framework in any project. Finally, this article shows developers and designers that the Spring framework is a great reason to continue design pattern advocacy in your projects.

    Recently, it seems when developers use the Spring framework to improve their projects they focus only on simple object oriented design techniques. Unfortunately some of the more brilliantly researched patterns are forgotten in place of a brilliant framework (Spring). Although the Factory Pattern and the Singleton Pattern are built into Spring, other patterns such as the Decorator Pattern, the Adapter Pattern, and the Observer Pattern are often forgotten because of the new ideas Spring has to offer. Fortunately, design patterns and the Spring framework can exist in the same application. In this article I show how the commonly used Observer Pattern fits nicely in the Spring Framework.

    Observer Pattern

    The Observer Pattern is also known as a publisher and subscriber design pattern. The pattern is useful when you have one publisher and many subscribers (one-to-many) that are interested in the publisher's state or messages. Additionally, interested subscribers have the ability to register and unregister as they please. Lastly, subscribers are notified of the publisher's messages automatically (that is, by no effort of their own). Figure 1 is an example of a typical observer pattern.

    Figure 1. Observer Pattern


    I chose to use a more widely accepted diagram to describe the Observer Pattern so you will notice that the aforementioned publisher is actually the Subject in this diagram. The subscriber is the Observer in the diagram. The intimate details of the Observer Pattern are far outside of the scope of this article, but a note worthy topic is how the Spring framework can be used to leverage good object oriented design techniques while creating the concrete classes of this pattern.

    A normal concreteObserver class is required to have code similar to this constructor (or a similar “setter” method to achieve the registering of the Observer with the Subject):

    public concreteObserver(Subject s) {
    	s.addListener(this);
    }
    

    Below you will see how the Spring framework wires the two concrete classes together with XML and not with code inside the classes. Ultimately, this allows the developer to avoid any unnecessary coupling of the concrete classes.

    Spring Considerations

    Since this article covers only the most simple implementation of the observer pattern, I utilize only the required Spring framework jars. At a minimum you need to have the spring-core.jar, the spring-context.jar, and the spring-beans.jar from the Spring framework distribution. Also to avoid any run time errors you need the commons-logging.jar from the Apache Commons project in your class path.

    Each of these jars provide a specific role that make using the Spring framework possible. First is the spring-core.jar; this jar is required for all Spring applications. It includes Spring's dependency injection classes as well as other classes that are used to create Spring beans. The spring-context.jar contains the ApplicationContext interface. This interface is used to start the Spring framework in my included example project.

    The last Spring jar is the spring-beans.jar. It contains the DesposibleBean interface which the FileSystemXmlApplicationContext bean sub-interfaces. I do not directly use the DesposibleBean interface but I use the FileSystemXmlApplicationContext bean to located the XML file used to configure the Spring framework. The code that implements these classes is shown in Listing 6.

    Wiring The Observer Pattern with Spring

    To illustrate the Observer Pattern concretely, I chose to create a Town Crier class that sends messages to any registered Town Resident class. To keep this example simple, I developed the same interfaces shown in Figure 1, but the concrete classes are TownCrier and TownResident. All four of these classes are shown in Listings 1 through 4.

    After I created the TownCrier (Listing 3) and two TownResident (Listing 4) classes I created an incomplete version the ObserverContext.xml file (Listing 5). This file contains the Spring definitions of the concrete implementation beans. Since this example is simple, I chose not to use any of the more complex attributes of the bean tag.

    Typical Bean tags for the shown classes:

    	<bean id="townCrier" class="springobserver.TownCrier"/>
    	<bean id="townResident1" class="springobserver.TownResident"/>
    	<bean id="townResident1" class="springobserver.TownResident2"/>
    

    At this point, I was able to run my ExampleRun class (Listing 6), but nothing eventful actually happened. This is because the TownResident classes were not “wired” into the TownCrier class.

    To perform the wiring of the Observer Pattern I chose to use Spring's MethodInvokingFactoryBean class. This process is a very simple way of calling a method on a class and ultimately passing a parameter into method. In this example, the parameter is the bean definition of a townResident. A snapshot of this bean definition is:

    <bean id="registerTownResident1" 
    class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="targetObject"><ref local="townCrier"/></property>
        <property name="targetMethod"><value>addListener</value></property>
        <property name="arguments">
        <list>
          <ref bean="townResident1"/>
        </list>
        </property>
    </bean>
    

    As you can see, the targetObject is the townCrier bean, the targetMethod is the addListener method and the argument is the townResident1 bean. This configuration is the only code needed to compose the concrete implementations of the TownCrier with TownResident class.

    Now that I have the beans wired together using the MethodInvokingFactoryBean class, I can run my ExampleRun class and see that my TownResident classes are receiving messages from the TownCrier class. Results shown in Example 1.

    Conclusion

    A few lessons learned in this article include a simple way to start the Spring framework, how to use the MethodInvokingFactoryBean, and an efficient implementation the Observer Pattern in the Spring framework. Since this is a minimal approach to the Spring framework, I was able to show the relationship between the ApplicationContext and it's implementation FileSystemXmlApplicationContext class. This process for starting Spring applications is a very easy way to leverage an incredible framework.

    Part of this framework is the MethodInvokingFactoryBean. When using it you are free to employ any parameter available to you such as an Integer, a String, or in our case, another Spring bean. By allowing you to expose methods in your context xml files you can be as flexible as you can dream. This article has covered the addListener() method of the Observer Pattern. I would like to extend a challenge to you to figure out how to implement the removeListener() method using strictly the Spring framework.

    Lastly, the Observer Pattern is a common and very useful pattern. The practices shown in this article provide an example of how the concrete implementation of the Observer interface can be developed with no additional coupling to the concrete implementation of the Subject interface. This feature of Spring encourages good object oriented design techniques. As a final note, there is really no reason developers and designers can not find ways to marry proven design patterns with beautifully developed frameworks.

    Listing 1. The Observer Interface
    package springobserver;
    public interface Observer {
      public void update(String messageText);
    }
    
    Listing 2. The Subject Interface
    package springobserver;
    public interface Subject {
      public void addListener(Observer o);
      public void removeListener(Observer o);
      public void notifyListeners();
    }
    
    Listing 3. The Town Crier
    package springobserver;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    
    public class TownCrier implements Subject {
    
    	private List townResident = new ArrayList();
    	private String messageText;
    
    	// this message is added so I can give 
    	// this class a reason to call notifyListener.
    	public void setMessage(String message){
    		System.out.println("I'm the Town Crier and " +
    				"I've got a message: " + message);
    		this.messageText = message;
    		this.notifyListeners();
    	}
    	
    	public void addListener(Observer o) {
    		this.townResident.add(o);
    	}
    
    	public void removeListener(Observer o) {
    		if (this.townResident.contains(o)){
    			this.townResident.remove(o);
    		}
    	}
    
    	
    	// call the update method on 
    	// each observer (town resident)
    	public void notifyListeners() {
    		for (Iterator iter = townResident.iterator(); iter.hasNext();) {
    			Observer listener = (Observer) iter.next();
    			listener.update(messageText);
    		}
    	}
    
    }
    
    Listing 4. The Town Residents
    package springobserver;
    
    public class TownResident implements Observer {
    	public void update(String messageText) {
    		System.out.println("Greetings my name is: " + this);
    		System.out.println("I heard: " + messageText);
    	}
    
    -------- new class --------
    package springobserver;
    
    public class TownResident2 implements Observer {
    	public void update(String messageText) {
    		System.out.println("Greetings my name is: " + this);
    		System.out.println("I heard: " + messageText);
    	}
    
    }
    Listing 5. The Application Context XML (ObserverContext.xml)
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
    "http://www.springframework.org/dtd/spring-beans.dtd">
    
    <beans>
    	<!-- This bean is the town crier.  
    	He's responsible for notifying all town residents that are interested in his message -->
    	<bean id="townCrier" class="springobserver.TownCrier"/>
    	
    	<!-- this bean is a town resident interested in the town criers messages -->
    	<bean id="townResident1" class="springobserver.TownResident"/>          
           
    	<!-- this bean is another town resident interested in the town criers messages -->
    	<bean id="townResident2" class="springobserver.TownResident2"/>
        
        
         <!-- this is a method invoking bean that registers the first town resident with
              with the town crier -->   
        <bean id="registerTownResident1" 
          class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
          <property name="targetObject"><ref local="townCrier"/></property>
          <property name="targetMethod"><value>addListener</value></property>
          <property name="arguments">
          <list>
            <ref bean="townResident1"/>
          </list>
          </property>
        </bean>
        
        
         <!-- this is a method invoking bean that registers the second town 
              resident with the town crier -->   
        <bean id="registerTownResident2" 
          class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
          <property name="targetObject"><ref local="townCrier"/></property>
          <property name="targetMethod"><value>addListener</value></property>
          <property name="arguments">
          <list>
            <ref bean="townResident2"/>
          </list>
          </property>
        </bean>         
     
     </beans>
    
    Listing 6. Example Run
    package springobserver;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.FileSystemXmlApplicationContext;
    
    public class ExampleRun {
    	public static void main(String[] args) {
    		// launch the spring frame work.
    		ApplicationContext ctx = new FileSystemXmlApplicationContext(
    				"/config/ObserverContext.xml");
    		// grab the Town Crier out of the spring 
    		// framework and send a message too all observers
    		TownCrier crier = (TownCrier) ctx.getBean("townCrier");
    		crier.setMessage("It is 1 O'Clock and all is well!");
    	}
    }
    
    Example 1. System Output
    I'm the Town Crier and I've got a message: It is 1 O'Clock and all is well!
    Greetings my name is: springobserver.TownResident@80fa6f
    I heard: It is 1 O'Clock and all is well!
    Greetings my name is: springobserver.TownResident2@1b9ce4b
    I heard: It is 1 O'Clock and all is well!
    

    posted on 2005-11-22 14:17 Dion 閱讀(775) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 国产精品亚洲综合网站| 亚洲国产精品综合久久2007| 亚洲欧美日韩综合俺去了| 69xx免费观看视频| 911精品国产亚洲日本美国韩国| 久久精品乱子伦免费| 亚洲国产日韩一区高清在线| 久久99国产乱子伦精品免费| 久久久久亚洲精品无码蜜桃| 国产91免费在线观看| 亚洲男人的天堂久久精品| 影音先锋在线免费观看| 亚洲精品美女久久7777777| 日本高清免费网站| 免费一区二区三区在线视频| 亚洲无线码一区二区三区| 免费观看91视频| 亚洲天堂一区二区三区四区| AV免费网址在线观看| 精品一区二区三区免费毛片| 亚洲精品黄色视频在线观看免费资源 | 婷婷亚洲天堂影院| 全黄A免费一级毛片| 久久久久亚洲AV成人网人人网站| 黄色一级视频免费| 国产亚洲美女精品久久久2020| 免费91最新地址永久入口 | 亚洲国产精品一区二区三区久久| 亚洲精品国产日韩无码AV永久免费网| 亚洲AV午夜成人片| 久久久久免费看黄A片APP | 青青操免费在线观看| 亚洲黄色免费在线观看| 好吊妞在线新免费视频| 七次郎成人免费线路视频| 久久精品国产精品亚洲毛片| 免费看国产精品麻豆| 精品国产麻豆免费人成网站| 亚洲免费福利在线视频| 国产亚洲av人片在线观看| 免费精品国偷自产在线在线|