观察者模式

观察者模式

观察者模式中,有订阅者和发布者。发布者在发布消息后,所有订阅者都可以受到消息。

手动实现观察者模式

订阅者接口

observerCjw

package observer_cjw;


/**
 *观察者接口
 */
public interface observerCjw {
	
	
	/**
	 * 功能:把接收的消息打印出来.
	 */
	void say();
	
	/**
	 * 功能:更新信息
	 */
	void setMsg(String msg);
	
	
}

订阅者实现类

observerCjwImpl

package observer_cjw;

public class observerCjwImpl implements observerCjw {

	private String msg;
	
	@Override
	public void say() {
		System.out.println("msg: " + msg);
	}

	@Override
	public void setMsg(String msg) {
		this.msg = msg;
	}

}

发布者接口

observableCjw

package observer_cjw;

/**
 *发布者接口
 *功能:添加订阅者,删除订阅者,发布消息
 */
public interface observableCjw {
	
	/**
	 * 功能:添加订阅者
	 */
	void addObserver(observerCjw observerCjw);
	
	/**
	 * 功能:删除订阅者
	 */
	void delObserver(observerCjw observerCjw);
	
	/**
	 * 功能:发布消息
	 */
	void upMsg(String msg);
	
}

发布者实现类

observableCjwImpl

package observer_cjw;

import java.util.List;

public class observableCjwImpl implements observableCjw {

	private List<observerCjw> list;
	
	

	public observableCjwImpl() {
		super();
		// TODO Auto-generated constructor stub
	}

	public observableCjwImpl(List<observerCjw> list) {
		super();
		this.list = list;
	}

	@Override
	public void addObserver(observerCjw observerCjw) {
		list.add(observerCjw);
	}

	@Override
	public void delObserver(observerCjw observerCjw) {
		list.remove(observerCjw);
	}

	@Override
	public void upMsg(String msg) {
		for (observerCjw observerCjw : list) {
			observerCjw.setMsg(msg);
		}
	}

}

测试一下

package observer_cjw;

import java.util.ArrayList;

public class test01 {
	public static void main(String[] args) {
//		创建3个订阅者
		observerCjw observerCjw = new observerCjwImpl();
		observerCjw observerCjw2 = new observerCjwImpl();
		observerCjw observerCjw3 = new observerCjwImpl();
		
//		创建1个发布者
		observableCjw observableCjw = new observableCjwImpl(new ArrayList<observerCjw>());
		
//		发布者添加订阅者
		observableCjw.addObserver(observerCjw);
		observableCjw.addObserver(observerCjw2);
		observableCjw.addObserver(observerCjw3);

//		发布者发布消息
		observableCjw.upMsg("早上好");
		
//		订阅者打印收到的消息
		observerCjw.say();
		observerCjw2.say();
		observerCjw3.say();
		System.out.println("-----------------------");
		
//		发布者发布消息
		observableCjw.upMsg("中午好");
		
//		订阅者打印收到的消息
		observerCjw.say();
		observerCjw2.say();
		observerCjw3.say();
		System.out.println("-----------------------");
		
//		退订
		observableCjw.delObserver(observerCjw2);
		
//		发布者发布消息
		observableCjw.upMsg("晚上好");
		
//		订阅者打印收到的消息
		observerCjw.say();
		observerCjw2.say();
		observerCjw3.say();
		System.out.println("-----------------------");
		
	}
}

打印输出

msg: 早上好
msg: 早上好
msg: 早上好
-----------------------
msg: 中午好
msg: 中午好
msg: 中午好
-----------------------
msg: 晚上好
msg: 中午好
msg: 晚上好
-----------------------

项目打包 提取码:2lod 环境:eclipse,jdk1.8

jdk实现观察者模式

jdk自带了实现观察者模式的接口和类。订阅者要实现 Observer 接口,发布者要继承 Observable 类。

这两个接口/类代码量不多,可以分析一下源码。

Observer接口

Observer接口只有一个方法

public interface Observer {
    void update(Observable o, Object arg);
}
方法功能
update更新消息

Observable类

字段名类型功能
changedboolean
obsVector存放订阅者
方法名返回类型功能
Observablevoid初始订阅者集合
addObservervoid添加订阅者
deleteObservervoid删除订阅者
notifyObserversvoid发布消息
notifyObservers(有参)void发布消息
deleteObserversvoid删除所有的订阅者
setChangedvoid标记需要更新
clearChangedvoid标记不需要更新
hasChangedboolean是否更新
countObserversint返回订阅者数量

注释源码

package observer;

import java.util.Observer;
import java.util.Vector;

public class Observable {
	
//	标记是否需要更新,false表示更新完毕.
    private boolean changed = false;
    
//  订阅者集合, 使用Vector集合来存放订阅者.
    private Vector<Observer> obs;

//	初始化订阅者集合
    public Observable() {
        obs = new Vector<>();
    }

    
    /**
     * 功能:添加一个订阅者
     */
    public synchronized void addObserver(Observer o) {
//    	为空,抛出空指针异常
        if (o == null)
            throw new NullPointerException();
//      判断是否重复订阅
        if (!obs.contains(o)) {
            obs.addElement(o);
        }
    }

    
    /**
     * 功能:删除一个订阅者
     */
    public synchronized void deleteObserver(Observer o) {
        obs.removeElement(o);
    }

    
    /**
     * 功能:发布消息(默认消息)
     */
    public void notifyObservers() {
        notifyObservers(null);
    }

    
    /**
     * 功能:发布消息
     */
    public void notifyObservers(Object arg) {
        
//    	存放订阅者
        Object[] arrLocal;

//      把自己锁定
        synchronized (this) {
//          判断是否更新完毕
            if (!changed)
                return;
//          把订阅者集合放入object数组中
            arrLocal = obs.toArray();
//          标记更新完毕
            clearChanged();
        }

        for (int i = arrLocal.length-1; i>=0; i--)
//        	把每一个订阅者都强转为Observer类型,每一个订阅者都执行update方法
            ((Observer)arrLocal[i]).update(this, arg);
    }

    
    /**
     * 功能:删除所有订阅者
     */
    public synchronized void deleteObservers() {
        obs.removeAllElements();
    }

    
    /**
     * 功能:设置需要更新
     */
    protected synchronized void setChanged() {
        changed = true;
    }

    
    
    /**
     * 功能:标记不需要更新
     */
    protected synchronized void clearChanged() {
        changed = false;
    }

    
    /**
     * 功能:返回是否需要更新标记
     */
    public synchronized boolean hasChanged() {
        return changed;
    }

    
    /**
     * 功能:返回订阅者的数量
     */
    public synchronized int countObservers() {
        return obs.size();
    }
}

为什么使用vector集合?

vector是线程安全的,大小自动变化的对象数组。

synchronized方法和synchronized代码块的使用?

​ 增加/删除订阅者,返回订阅者数量,发布消息。使用synchronized方法/synchronized代码块做到了线程安全。

扩展性?

​ 源码的设计非常好,订阅者的更新方法中可以使用发布者对象以及更新信息对象,相关联的信息,订阅者都可以获得。

必须实现Observable的子类?

​ 是的,因为标记需要更新的方法是受保护的。不允许外界直接调用。必须实现其子类,将标记更新方法公开。

示例

订阅者
package observer;

import java.util.Observable;
import java.util.Observer;

/**
 *订阅者
 */
public class ObserverCjw implements Observer{

	/* 
	 * 功能:将发布的消息打印出来
	 */
	@Override
	public void update(Observable o, Object arg) {
		System.out.println(this+":"+(String)arg);
	}

}

发布者
package observer;

import java.util.Observable;

/**
 *发布者
 */
public class ObservableCjw extends Observable{
	
	/* 
	 * 功能:公开setChanged方法
	 */
	public void setChanged() {
		super.setChanged();
	}
}

测试一下
package observer;

import java.util.Observer;

public class Test {
	public static void main(String[] args) {
//		发布者
		ObservableCjw observableCjw = new ObservableCjw();
//		订阅者
		Observer oCjw = new ObserverCjw();
		Observer oCjw2 = new ObserverCjw();
		Observer oCjw3 = new ObserverCjw();
		
//		订阅
		observableCjw.addObserver(oCjw);
		observableCjw.addObserver(oCjw2);
		observableCjw.addObserver(oCjw3);
		
//		发布消息
		observableCjw.setChanged();
		observableCjw.notifyObservers("早上好");
		System.out.println("------------------");
		
//		发布消息
		observableCjw.setChanged();
		observableCjw.notifyObservers("中午好");
		System.out.println("------------------");
		
//		退订
		observableCjw.deleteObserver(oCjw2);
		
//		发布消息
		observableCjw.setChanged();
		observableCjw.notifyObservers("晚上好");
		System.out.println("------------------");
	}
}

输出打印
observer.ObserverCjw@6d06d69c:早上好
observer.ObserverCjw@7852e922:早上好
observer.ObserverCjw@4e25154f:早上好
------------------
observer.ObserverCjw@6d06d69c:中午好
observer.ObserverCjw@7852e922:中午好
observer.ObserverCjw@4e25154f:中午好
------------------
observer.ObserverCjw@6d06d69c:晚上好
observer.ObserverCjw@4e25154f:晚上好
------------------

项目打包 提取码:2zvh 环境:eclipse,jdk1.8

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于微信小程序的家政服务预约系统采用PHP语言和微信小程序技术,数据库采用Mysql,运行软件为微信开发者工具。本系统实现了管理员和客户、员工三个角色的功能。管理员的功能为客户管理、员工管理、家政服务管理、服务预约管理、员工风采管理、客户需求管理、接单管理等。客户的功能为查看家政服务进行预约和发布自己的需求以及管理预约信息和接单信息等。员工可以查看预约信息和进行接单。本系统实现了网上预约家政服务的流程化管理,可以帮助工作人员的管理工作和帮助客户查询家政服务的相关信息,改变了客户找家政服务的方式,提高了预约家政服务的效率。 本系统是针对网上预约家政服务开发的工作管理系统,包括到所有的工作内容。可以使网上预约家政服务的工作合理化和流程化。本系统包括手机端设计和电脑端设计,有界面和数据库。本系统的使用角色分为管理员和客户、员工三个身份。管理员可以管理系统里的所有信息。员工可以发布服务信息和查询客户的需求进行接单。客户可以发布需求和预约家政服务以及管理预约信息、接单信息。 本功能可以实现家政服务信息的查询和删除,管理员添加家政服务信息功能填写正确的信息就可以实现家政服务信息的添加,点击家政服务信息管理功能可以看到基于微信小程序的家政服务预约系统里所有家政服务的信息,在添加家政服务信息的界面里需要填写标题信息,当信息填写不正确就会造成家政服务信息添加失败。员工风采信息可以使客户更好的了解员工。员工风采信息管理的流程为,管理员点击员工风采信息管理功能,查看员工风采信息,点击员工风采信息添加功能,输入员工风采信息然后点击提交按钮就可以完成员工风采信息的添加。客户需求信息关系着客户的家政服务预约,管理员可以查询和修改客户需求信息,还可以查看客户需求的添加时间。接单信息属于本系统里的核心数据,管理员可以对接单的信息进行查询。本功能设计的目的可以使家政服务进行及时的安排。管理员可以查询员工信息,可以进行修改删除。 客户可以查看自己的预约和修改自己的资料并发布需求以及管理接单信息等。 在首页里可以看到管理员添加和管理的信息,客户可以在首页里进行家政服务的预约和公司介绍信息的了解。 员工可以查询客户需求进行接单以及管理家政服务信息和留言信息、收藏信息等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值