观察者模式抽取的工具类

来源:互联网 发布:linux编译工具链 编辑:程序博客网 时间:2024/04/19 09:35

最近项目有很多需要在Activity中传送数据、数据更改后刷新界面、异步更新数据的地方,所以对观察者模式做了一个抽取,做了一个工具包,使用的时候非常简单,下面上代码~


例如,以某个类作为数据进行公布:


public class Task implements Publisher.Publishable{}


需要注意作为数据的类要实现这个Publishable接口,然后创建TaskPublisher


public class TaskPublisher {    public static final Publisher publisher = new Publisher();    public static final PublishableHolder<Task> task = new PublishableHolder<>(publisher);}

这里publisher变量是用来注册和注销的入口,它本身实现了观察者模式的通知方法,Publishable接口也在Publisher类中


public class Publisher {    private final List<Observer> observers;    public Publisher() {        this.observers = new ArrayList<>();    }    /**     * 注册     *     * @param observer     */    public void register(Observer observer) {        if (!isRegistered(observer)) {            observers.add(observer);        }    }    /**     * 注销     *     * @param observer     */    public void unRegister(Observer observer) {        if (isRegistered(observer)) {            observers.remove(observer);        }    }    public boolean isRegistered(Observer observer) {        return observers.contains(observer);    }    /**     * 获取注册听众数量     *     * @return     */    public int getObserversCount() {        return observers.size();    }    /**     * 通知所有听众     */    public void notifyObservers(Object data) {        if (observers.size() > 0) {            for (Observer observer : observers) {                if (observer != null) {                    observer.update(data);                }            }        }    }    public interface Observer {        void update(Object data);    }    public interface Publishable {    }}


当你在某个类中实现了Publisher.Observer接口的update方法后,就可以调用注册方法进行注册了


public class TaskObserver implements Publisher.Observer{    public void update(Object data){        // do something    }}


在合适的地方进行注册和注销


TaskObserver taskObserver = new TaskObserver();//注册TaskPublisher.publisher.register(taskObserver);//注销TaskPublisher.publisher.unRegister(taskObserver);

进行注册之后,获取需要的数据


Task task = TaskPublisher.task.getData();


之后就可以使用该数据进行界面初始化之类的工作


需要注意,一定要在注册之后获取数据,否则异步操作有可能让你错过一次数据更新!


那么剩下的就是PublishableHolder了,见代码


public class PublishableHolder<P extends Publisher.Publishable> {    private final Publisher publisher;    private P data;    public PublishableHolder(Publisher publisher) {        this.publisher = publisher;    }    public P getData() {        return data;    }    public void setData(P data) {        this.data = data;        publisher.notifyObservers(this.data);    }    /**     * 在data的引用地址不改变的情况下修改data内部的数据推荐调用此方法     * 否则需要自行通知publisher     *     * @param changer     */    public void modifyData(DataChanger changer) {        if (changer != null) {            changer.doChange(data);            publisher.notifyObservers(data);        }    }    /**     * 修改数据接口     */    public interface DataChanger<P extends Publisher.Publishable> {        void doChange(P data);    }}

另外还可以使用List<Publishable>的数据,用到了另一个类PublishableListHolder


public class PublishableListHolder<P extends Publisher.Publishable> {    private final List<P> list;    private final Publisher publisher;    public PublishableListHolder(Publisher publisher) {        list = new ArrayList<>();        this.publisher = publisher;    }    public void setList(List<P> list) {        this.list.clear();        this.list.addAll(list);        publisher.notifyObservers(this.list);    }    public List<P> getList(Publisher.Observer observer) {        return list;    }    public void addItem(P publishable) {        list.add(publishable);        publisher.notifyObservers(list);    }    public void removeItem(P publishable) {        if (list.contains(publishable)) {            list.remove(publishable);            publisher.notifyObservers(list);        }    }    public void addAll(List<P> publishableList) {        list.addAll(publishableList);        publisher.notifyObservers(list);    }    public void removeAll(List<P> publishableList) {        list.removeAll(publishableList);        publisher.notifyObservers(list);    }    public void clear() {        list.clear();        publisher.notifyObservers(list);    }}





0 0
原创粉丝点击