设计模式(一)—— 观察者模式

观察者模式(Observer Pattern)

又叫做发布订阅

两个角色:观察者和被观察者

两者存在“观察”的逻辑关联,当被观察者发生改变的时候,观察者就会观察到这样的变化,并且做出相应的响应,观察不是直接调用,实现观察者模式有很多形式,比较直观的一种是使用“注册——通知——撤销注册”的形式;

设计如下图:

具体代码如下:

//主题对象(被观察者)接口
public interface ISubject {
	void registerObserver(Observer observer);//注册观察者
	void removeObserver(Observer observer);//删除观察者
	void notifyObserver();//通知观察者

}

//主题对象(被观察者)
public class Subject implements ISubject {

	List<Observer> list = null;
	
	private String message;
	
	public Subject() {
		this.list = new ArrayList<>();
	}

	@Override
	public void registerObserver(Observer observer) {
		
		list.add(observer);
	}

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
		notifyObserver();
	}

	@Override
	public void removeObserver(Observer observer) {
		list.remove(observer);
	}

	@Override
	public void notifyObserver() {
		for (int i = 0; i < list.size(); i++) {
			list.get(i).update(message);
		}

	}
	
	public List<Observer> getList() {
		return list;
	}

	public void setList(List<Observer> list) {
		this.list = list;
	}

	@Override
	public String toString() {
		return "Subject [list=" + list + ", message=" + message + "]";
	}
	
}

//观察者接口
/***
 * 依赖倒转原则
 *
 */
public interface Observer {

	void update(Object o);
	
}

//观察者对象
public class ConcreteObserver implements Observer {

	private String name;
	private String message;
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}


	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

	@Override
	public void update(Object o) {
		
		this.message = (String) o;
		
	}	
	
}

//测试类
public class Test {

	public class Test {

	public static void main(String[] args) {
		
		ConcreteObserver observer = new ConcreteObserver();
		ConcreteObserver observer1 = new ConcreteObserver();
		ConcreteObserver observer2 = new ConcreteObserver();
		Subject subject = new Subject();
		subject.registerObserver(observer);
		subject.registerObserver(observer1);
		subject.registerObserver(observer2);
		subject.setMessage("111");
		System.out.println(observer.getMessage());
		
		subject.setMessage("222");
		subject.removeObserver(observer1);
		System.out.println(subject.list);
		System.out.println(observer1.getMessage());
		
	}
}
}

如上四个类,两个接口分别代表主题对象(被观察者)和观察者接口。

这里解释一下,主题对象即被观察者里面的方法,registerObserver 是注册观察者,因为观察者需要观察被观察者消息的变化,所以,在被观察者里面就需要一个集合来装观察者,以便当被观察者消息发生变化是及时通知到每一位观察者。removeObserver 是删除观察者,也就是说观察者可以选择放弃被观察者。还有一个notifyObserver通知观察者方法,是专门通知每一位观察者消息的。最后是观察者Observer对象中的update方法,主要是当被观察者通知消息时直接调用该方法。

之所以需要接口就是便于后期的扩展性。

但在这里发现一个问题:也就是说当观察者后期扩展时,每次都需要在观察者里面添加新的属性,在该例子中时message属性,如果有新的观察对象,那么会有新的观察属性,势必会在该观察者里面得添加一个新的属性,貌似违背了,设计理念中的开闭原则,怎么办呢?

希望看到的同行大牛给出新的一些建议,谢谢下方留言!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

焱墩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值