软件设计模式-观察者模式

一、什么是观察者模式

        观察者模式属于行为型设计模式。它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,其所有依赖者都会收到通知并自动更新。

二、什么时候用观察者模式

       首先,察者模式属于行为型模式。当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,所有依赖于它的对象都应该受到通知并且自动更新,那么可使用本模式。

三、有哪些组成

观察者模式包括以下几个部分:

  1. Subject(主题,被观察者):定义了一个一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。主题对象通常会维护一个观察者列表,并提供方法用于注册、移除和通知观察者。

  2. Observer(观察者):定义了一个更新接口,当被观察对象的状态发生变化时能够得到通知。观察者一般会注册到主题对象中,以便主题对象状态改变时能够及时得到通知并作出相应处理。

  3. ConcreteSubject(具体主题):具体的主题对象,维护具体观察者对象的状态,当状态发生变化时通知所有注册的观察者。

  4. ConcreteObserver(具体观察者):具体的观察者对象,实现了观察者接口中定义的更新方法,在接收到主题对象通知时进行相应的处理。

  5. Notification(通知):通知是被观察者发出的一种消息,用于告知观察者发生了变化。通知可以附带一些额外的数据,以便观察者能够获取变化的具体信息。

通过各部分间的协作,实现了对象之间的解耦,使得一个对象发生变化时能够自动通知其他对象。

四、有哪些不足

  1. 过多细粒度的通知:当主题对象状态频繁变化时,观察者可能会收到大量的通知,这可能导致性能上的开销。

  2. 可能引发循环依赖:观察者和主题之间是一个松散的耦合关系,但在实际应用中,如果设计不合理,可能会出现观察者和主题相互依赖的情况,这可能会导致设计上的混乱。

  3. 定位困难:在某些情况下,观察者模式的使用可能会导致代码的执行路径变得复杂,使得定位问题变得困难。

  4. 可能引起内存泄漏:如果观察者没有被正确地移除或者被错误地持有,可能会导致内存泄漏问题。

  5. 通知顺序不确定:观察者模式中,观察者接收到通知的顺序是不确定的,这可能会导致一些潜在的问题。

五、示例代码

这里我用学生接收不同群消息的例子来说明本例子的使用。

//Observer(观察者)接口,本题看成所有订阅了这个群的学生
interface Student {
	void update();
}

//ConcreteObserver(具体的观察者)类
public class ConcreteStudent implements Student {
	 private String name;
	 public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public ConcreteGroup getGroup() {
		return group;
	}

	public void setGroup(ConcreteGroup group) {
		this.group = group;
	}

	private ConcreteGroup group;

	 public ConcreteStudent(String name, ConcreteGroup group) {
	     this.name = name;
	     this.group = group;
	 }

	 public void update() {
	     System.out.println("Observer " + name + " received update. New notification: " + group.getNotification().getContent());
	 }
}

//Subject(被观察者)接口,这里看成群
public interface Group {
	 void attach(ConcreteStudent observer);
	 void detach(ConcreteStudent observer);
	 void notifyStudents();
	}

//ConcreteSubject(具体的被观察者)类 有一个订阅者列表
class ConcreteGroup implements Group {
	private String Name;
	public ConcreteGroup(String name) {
		super();
		Name = name;
	}

	private List<ConcreteStudent> Students = new ArrayList<>();
	private Notification notification;
	
	public void attach(ConcreteStudent Student) {
	     System.out.println(Student.getName()+"加入群聊:"+Name);
		Students.add(Student);
	}

	public void detach(ConcreteStudent Student) {
		System.out.println(Student.getName()+"退出群聊"+Name);
		Students.remove(Student);
	}

	public void notifyStudents() {
		for (ConcreteStudent Student : Students) {
			Student.update();
		}
	}

	public void setNotification(Notification notification) {
		// TODO Auto-generated method stub
		this.notification = notification;
		notifyStudents();
	}

	public Notification getNotification() {
		// TODO Auto-generated method stub
		return notification;
	}
}

public class Notification {
	private String content;
	private Date publicateTime;

	public Notification(String content, Date publicateTime) {
		this.content = content;
		this.publicateTime = publicateTime;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public Date getPublicateTime() {
		return publicateTime;
	}

	public void setPublicateTime(Date publicateTime) {
		this.publicateTime = publicateTime;
	}

}

public class MainTest {

	public static void main(String[] args) {
		ConcreteGroup group = new ConcreteGroup("快乐学习");

		ConcreteStudent student1 = new ConcreteStudent("Student1", group);
		ConcreteStudent student2 = new ConcreteStudent("Student2", group);

		group.attach(student1);
		group.attach(student2);
		Date date = new Date(); 
		group.setNotification(new Notification("快写pta",date));

		group.detach(student1);
		Date date2 = new Date(); 
		group.setNotification(new Notification("快写课堂作业",date2));

	}
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值