设计模式之 Observer - 观察者模式
Observer模式也叫观察者模式,是由GoF提出的23种软件设计模式的一种。Observer模式是行为模式之一,它的作用是当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态。本文介绍设计模式中的(Observer)模式的概念,用法,以及实际应用中怎么样使用Observer模式进行开发。
package zieckey.designpatterns.study.observer.nojdk;
public class Client
{
????/**
???? * Test Observer Pattern
???? * --
???? *
???? */
????public static void main( String[] args )
????{
????????NewsPublisher publisher = new NewsPublisher();
????????
????????//添加观察者对象
????????publisher.register( new SubscriberObserver() );
????????publisher.register( new ManagerObserver() );
????????//发布新闻,触发通知事件
????????publisher.publishNews( "Hello news", "news body" );
????}
}
NewsPublisher
package zieckey.designpatterns.study.observer.nojdk;
/**
?* Subject ROLE
?* NewsPublisher: news publisher
?*
?*/
public class NewsPublisher extends Observable
{
????public void publishNews( String newsTitle, String newsBody )
????{
????????News news = new News( newsTitle, newsBody );
????????System.out.println( "News published:" + newsTitle );
????????this.notifyAllObervers( news ); //通知各Observer,并发送一个名为news对象的消息
????????//other process ... such as save news to database
????}
}
???
SubscriberObserver
??
package zieckey.designpatterns.study.observer.nojdk;
/**
?* Observer ROLE
?*
?*/
public class SubscriberObserver implements IObserver
{
????public void update( Observable observee, Object param )
????{
????????if ( param instanceof News )
????????{
????????????mail2Subscriber( (News)param );
????????}
????}
????private void mail2Subscriber( News news )
????{
????????System.out.println( "Mail to subscriber. A news published with title : "
????????????????+ news.getTitle() );
????}
}
ManagerObserver
package zieckey.designpatterns.study.observer.nojdk;
/**
?* Observer ROLE
?*
?*/
public class ManagerObserver implements IObserver
{
????public void update( Observable observee, Object param )
????{
????????if ( param instanceof News )
????????{
????????????mail2Manager( (News)param );
????????}
????}
????private void mail2Manager( News news )
????{
????????System.out.println( "Mail to Manager. A news published with title : "
????????????????+ news.getTitle() );
????}
}
News
package zieckey.designpatterns.study.observer.nojdk;
//data entity
public class News
{
????private String????title;
????private String????body;
????public News( String title, String body )
????{
????????this.title = title;
????????this.body = body;
????}
????public String getBody()
????{
????????return body;
????}
????public void setBody( String body )
????{
????????this.body = body;
????}
????public String getTitle()
????{
????????return title;
????}
????public void setTitle( String title )
????{
????????this.title = title;
????}
}
???
Observable
package zieckey.designpatterns.study.observer.nojdk;
import java.util.ArrayList;
/**
?* Subject(被观察者)
?* 被观察的对象。
?* 当需要被观察的状态发生变化时,需要通知队列中所有观察者对象。
?* Subject需要维持(添加,删除,通知)一个观察者对象的队列列表。
?*
?* @author zieckey
?*
?*/
public class Observable
{
????private ArrayList < IObserver >????arrayList????= null;
????Observable( )
????{
????????arrayList = new ArrayList < IObserver >();
????}
????public void register( IObserver observer )
????{
????????arrayList.add( observer );
????}
????public void unregister( IObserver observer )
????{
????????arrayList.remove( observer );
????}
????public void notifyAllObervers( Object arg )
????{
????????for ( int i = 0; i < arrayList.size(); i++ )
????????{
????????????arrayList.get( i ).update( this, arg );
????????}
????}
}
IObserver
package zieckey.designpatterns.study.observer.nojdk;
/**
?*
?* Observer(观察者)
?* 接口或抽象类。
?* 当Subject的状态发生变化时,Observer对象将通过一个callback函数得到通知。
?*
?* @author zieckey
?*
?*/
public interface IObserver
{
????public void update( Observable observee, Object param );
}
运行程序输出:
News published:Hello news
Mail to subscriber. A news published with title:Hello news
Mail to Manager. A news published with title : Hello news
应用场景和优缺点
?????? 上面已经对观察者模式做了比较详细的介绍,还是那句话,人无完人,模式也不是万能的,我们要用好设计模式来解决我们的实际问题,就必须熟知模式的应用场景和优缺点:
?????? 观察者模式的应用场景:
观察者模式的优点:
观察者模式的缺陷:
?????? 相信大家现在对观察者模式都应该很清楚了吧!OK!那么,就像我们在前面的文章里反复强调的一样,设计原则远比模式重要,学习设计模式的同时一定要注意体会设计原则的应用。这里我们再来看看观察者模式里都符合那些设计原则。
在观察者模式的应用场景里变化的部分是Subject的状态和Observer的数量。使用Observer模式可以很好地将这两部分隔离开,我们可以任意改变Observer的数量而不需要去修改Subject,而Subject的状态也可以任意改变,同样不会对其Observer有任何影响。
Subject和Observer都使用接口来实现。Subject只需要跟踪那些实现了IObserver接口的对象,所以其只依赖于IObserver;而所有Observer都通过ISubject接口来注册、撤销、接收通知,所以它们也只依赖于 ISubject;所以这是面向接口编程的,这样的实现方式使得Subject和Observer之间完全没有任何耦合。
观察者模式使用对象组合将Subject和若干observer联系起来。它们之间的关系不是通过类的继承而是在运行时的动态组合。