设计模式之观察者模式

内容抄自《设计模式》清华大学出版社,2011

模式动机:
无论是在现实世界中还是在软件系统中,人们常常会遇到这样一类问题,一个对象的状态改变会引发其他对象的
状态改变,如十字路口的交通信号灯,红灯亮则汽车停,绿灯亮则汽车行,这些对象之间存在一种依赖关系,一个
对象的行为会导致依赖它的其他对象发生反应。

模式定义:
定义对象间的一种一对多的依赖关系,使得每当一个对象的状态发生改变时,其相关依赖对象都得到通知并被自动
更新。观察者模式又叫发布订阅模式。

结构分析:

包含角色:
1.Subject(抽象观察目标)
2.ConcreteSubject(具体观察目标)
3.Observer(抽象观察者)
4.ConcreteObserver(具体观察者) //如果和具体观察目标存在关联关系,则比较复杂

模式分析:
 

public abstract class Subject{
    protected ArrayList observers = new ArrayList<>();
    public abstract void add(Observer observer);
    public abstract void remove(Observer observer);
    public abstract void notify();
}
public class ConcreteSubject extends Subject{
    @Override
    public void add(Observer observer){
        observers.add(observer);
    }
    @Override
    public void remove(Observer observer){
        observers.remove(observer);
    }
    @Override
    public void notify(Observer observer){
        for(Observer o:observers){
            o.accept();
        }
    }
}
public interface Observer{
    public void accept();
}
public class ConcreteObserver implements Observer{
    @Override
    public void accept(){
        //dosome
    }
}

优点:
1.使观察者和观察目标解耦,观察目标不需要了解具体观察者。
2.支持广播通信,简化了一对多系统设计的难度。
3.符合开闭原则,新增具体观察者和观察目标,无须修改现有代码。

缺点:
1.如果在观察者和观察目标之间有循环依赖的话,可能会发生循环调用。
2.观察者不知道观察目标发生了什么样的变化,只知道发生了变化。
3.观察者被通知的动作都一样,需要使用事件委托机制解决

适用环境:
1.一个抽象模型有两个方面,一个方面多的改变会使得另一方面的改变。将这些方面封装在独立的对象中,使他们可以各自独立的改变和复用
2.一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变。
3.需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象。。。。。可以使用观察者模式创建一种链式触发机制

Java自带观察者模式分析:

包含角色:
1.Subject(抽象观察目标->java.util.Observable)
2.ConcreteSubject(具体观察目标->X extends Observable)
3.Observer(抽象观察者->Observer)
4.ConcreteObserver(具体观察者->X implements Observer)
 

public ConcreteSubject extends Observable{
    public void dosome(){
        super.setChanged();
        super.notifyObservers();
    }
}

public ConcreteObserver implements Observer{
    @Override
    public void update(Observable o, Object arg) {
         //o 为具体观察目标本身
        //dosome
    }
}

栗子:java自带

class Example {

	static class MyObservable extends Observable{
		public void dodo() {
			super.setChanged();
			super.notifyObservers("aa");
		}
	}
	
	static class MyOb implements Observer{
		@Override
		public void update(Observable o, Object arg) {
			System.out.println(o);
			System.out.println(arg);
		}
	}
	public static void main(String[] args) {
		MyObservable observable = new MyObservable();
		observable.addObserver(new MyOb());
		observable.dodo();
	}
}

栗子:自写

public class Test {

	static interface Observer{
		public void accept();
	}
	static class Observer1 implements Observer{
		@Override
		public void accept() {
			System.out.println("观察者1收到通知");
		}
	}
	static class Observer2 implements Observer{
		@Override
		public void accept() {
			System.out.println("观察者2收到通知");
		}
	}
	//被观察者
	static class Obserable{
		private List<Observer> obList;
		public Obserable() {
			this.obList = new ArrayList<>();
		}
		public void addObserver(Observer ob){
			obList.add(ob);
		}
		public void removeObserver(Observer ob){
			obList.remove(ob);
		}
		public void doSome(){
			for (Observer observer : obList) {
				observer.accept();
			}
		}
	}
	
	public static void main(String[] args) {
		Obserable obserable = new Obserable();
		//obserable.addObserver( new Observer1());
		//obserable.addObserver( new Observer2());
		obserable.doSome();
	}
}

栗子:事件委托

/**
 * 为了解决各观察者行为不一致的问题
 */
public class ObWithEvent {

	static class EventManager{
		private List<Event> list = new ArrayList<>();
		public void add(Event e){
			list.add(e);
		}
		public void remove(Event e){
			list.remove(e);
		}
		public void publish() {
			for (Event event : list) {
				event.invoke();
			}
		}
	}
	
	static abstract class Publisher{
		protected EventManager manager = new EventManager();
		public void add(Event e){
			this.manager.add(e);
		}
		public void remove(Event e){
			this.manager.remove(e);
		}
		public void publish(){
			this.manager.publish();
		}
	}
	
	static class ConcretePublisher extends Publisher{
		
	}
	
	//把各种信息封装成Event
	static class Event{
		private Object obj;
		private String methodName;
		public Event(Object obj, String methodName) {
			this.obj = obj;
			this.methodName = methodName;
		}
		public void invoke(){
			try {
				Method method = obj.getClass().getDeclaredMethod(methodName,new Class<?>[0]);
				method.invoke(obj, null);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	//具体观察者 (没有抽象了)
	static class LoginListener{
		public void handler2() {
			System.out.println("Login开始处理");
		}
	}
	//具体观察者 (没有抽象了)
	static class OtherListener{
		public void handler1() {
			System.out.println("Other开始处理");
		}
	}
	
	public static void main(String[] args) {
		LoginListener aa = new LoginListener();
		OtherListener bb = new OtherListener();
		ConcretePublisher publisher = new ConcretePublisher();
		publisher.add(new Event(aa,"handler2"));
		publisher.add(new Event(bb,"handler1"));
		publisher.publish();
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值