观察者模式(Observer Pattern)升级版

来源:互联网 发布:淘宝上的乳胶床垫 编辑:程序博客网 时间:2024/05/29 18:03

简介

前面的博客https://goo.gl/DFOz50中已经介绍过基本的观察者模式的代码实现,在实际应用中,我们往往希望代码更加简洁,同时也希望能与现有的框架,比如Spring,结合起来。下面介绍如何做抽象。

简单抽象

前面介绍过观察者模式有Subject,Observer,Client几种角色。在使用面向对象的时候Subject 和Observer都可以被抽象成接口,所以从原来的三种角色可以进化为6个角色。
(1) Subject : 被监控对象,抽象以后我们叫做BUS(总线,所有对被监控对象的操作都由它完成);
(2) concreteSubject:具体的被监控对象
(3)Observer(Listener):观察者
(4)concreteObserver:具体的观察者
(5)event : 监控对象和被监控对象交互时用到的消息

下面的类图用来解释新的观察者模式:
这里写图片描述


Note:
(1) 图中引入了泛型T作为观察者,从而使得每一个Bus的具体实现对应一个Listener接口,这样一个Bus最终只对应到一类事件;
(2)Listener和Bus之间交互使用一个单独的类Event实现;
(3)ExecutorService的引入使得监听器的响应与主线程异步进行,提升效率。

如果对上面的图进一步抽象的话就编程了下面这样:
这里写图片描述

代码实现

Step 1

创建AbstractBus

public abstract class BaseBus<T> {    private final List<T> listeners = new CopyOnWriteArrayList<T>();    private final ExecutorService executorService;    protected BaseBus(ExecutorService executorService) {        this.executorService = executorService;    }    public void iterate(final ListenerCallback<T> callback){        for(final T t:listeners){            this.executorService.submit(new Callable<Object>() {                @Override                public Object call() throws Exception {                    callback.doWithListener(t);                    return true;                }            });        }    }    public interface ListenerCallback<T> {        Object doWithListener(T t);    }    public boolean addListener(T listener) {        return this.listeners.add(listener);    }    public List<T> getListeners() {        return listeners;    }    public void setListeners(List<T> listeners) {        this.listeners.addAll(listeners);    }}

Step 2

创建AbstractBus的具体实现:

public class ProfileChangeBus extends BaseBus<ProfileChangeListener> {    public ProfileChangeBus(){        super(new ThreadPoolExecutor(                2, 10,                0L, TimeUnit.MILLISECONDS,                new LinkedBlockingQueue<Runnable>(100),                Executors.defaultThreadFactory(),                new ThreadPoolExecutor.CallerRunsPolicy()));    }    public void fireCreate(final ProfileChangeEvent event) {        event.setType(0);        iterate(new ListenerCallback<ProfileChangeListener>() {            @Override            public Object doWithListener(ProfileChangeListener profileChangeListener) {                profileChangeListener.onCreate(event);                return true;            }        });    }    public void fireUpdate(final ProfileChangeEvent event) {        event.setType(0);        this.iterate(new ListenerCallback<ProfileChangeListener>() {            @Override            public Object doWithListener(ProfileChangeListener profileChangeListener) {                profileChangeListener.onUpdate(event);                return true;            }        });    }    public void fireDelete(final ProfileChangeEvent event) {        event.setType(0);        this.iterate(new ListenerCallback<ProfileChangeListener>() {            @Override            public Object doWithListener(ProfileChangeListener profileChangeListener) {                profileChangeListener.onDelete(event);                return true;            }        });    }}

Step 3

创建Listener

public interface ProfileChangeListener {    void onCreate(ProfileChangeEvent profileChangeEvent);    void onUpdate(ProfileChangeEvent profileChangeEvent);    void onDelete(ProfileChangeEvent profileChangeEvent);}

Step 4

创建Listener的具体实现,这里有3个实现类:
(1)

public class ProfileChangeListenerAdapter implements ProfileChangeListener {    @Override    public void onCreate(ProfileChangeEvent profileChangeEvent) {        System.out.println("trigger create");    }    @Override    public void onUpdate(ProfileChangeEvent profileChangeEvent) {        System.out.println("trigger update");    }    @Override    public void onDelete(ProfileChangeEvent profileChangeEvent) {        System.out.println("trigger delete");    }}

(2)

public class ProfileChangeListenerAdapter4MQ extends ProfileChangeListenerAdapter {    @Override    public void onCreate(ProfileChangeEvent profileChangeEvent) {        System.out.println("mq trigger create");    }    @Override    public void onUpdate(ProfileChangeEvent profileChangeEvent) {        System.out.println("mq trigger update");    }    @Override    public void onDelete(ProfileChangeEvent profileChangeEvent) {        System.out.println("mq trigger delete");    }}

(3)

public class ProfileChangeListener4DB implements ProfileChangeListener{    @Override    public void onCreate(ProfileChangeEvent profileChangeEvent) {        System.out.println("db trigger create");    }    @Override    public void onUpdate(ProfileChangeEvent profileChangeEvent) {        System.out.println("db trigger create");    }    @Override    public void onDelete(ProfileChangeEvent profileChangeEvent) {        System.out.println("db trigger create");    }}

Step 5

创建Event

public class ProfileChangeEvent {    private int type;    private String message;    public ProfileChangeEvent(int type, String message){        this.type = type;        this.message = message;    }    public int getType() {        return type;    }    public void setType(int type) {        this.type = type;    }    public String getMessage() {        return message;    }    public void setMessage(String message) {        this.message = message;    }}

Step 6

将Listener注入到ConcreteBus

  <bean id="profileChangeBus" class="designpattern.observer.ProfileChangeBus">        <property name="listeners">            <list>                <bean class="designpattern.observer.ProfileChangeListener4DB" />                <bean class="designpattern.observer.ProfileChangeListenerAdapter4MQ"/>            </list>        </property>    </bean>

Step 7

测试:

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = {        "classpath:config/*.xml"})public class ObserverPatternTest {    @Autowired    private ProfileChangeBus profileChangeBus;    @Test    public void test(){        profileChangeBus.fireCreate(new ProfileChangeEvent(1, "1"));    }}
0 0
原创粉丝点击