自己写的一个android中关于观察者模式的demo。关于观察者的定义,可以看另外一篇文章:Java设计模式之观察者模式
下面先来看看代码的结构图:
结构的大体说明:包manager和包managerimpl用来管理观察者,包manager中是抽象的观察者,包managerimpl中是具体的观察者。
包listener和包notify 用来管理被观察者(也成为目标),包listener中是抽象的被观察者,提供注册和删除观察者对象的接口,包notify中是具体的被观察者,当它的状态发送改变时,向它的各个观察者发出通知。
包common中的类起全局的作用,用来管理所有的观察者。
与上面的包的路径平行的是包fragment和MainActivity,TestService,TestPrint等类,这些类是实现观察者接口的对象,具体分为4种类型:Activity,Fragment,Service和普通的类(TestPrint.java)。因为Android中入口程序是在Activity中,所以普通类TestPrint.java还要另外提供一个方法addListener()来使自己实现观察着的接口,并且将这个方法放在MainActivity中调用。
代码如下,
包listener中:两个类中共有6个方法,模拟收到了6中不同的消息,然后通知观察者。这里为了简单,通知的内容都是基本数据类型,具体情况中可以使用JavaBean实现。
publicinterfaceRecvMsgOne {
publicvoidnotifyRecvMsgHaHa(String haha);
publicvoidnotifyRecvMsgXiXi(String xixi);
}
publicinterfaceRecvMsgTwo {
publicvoidnotifyRecvName(String str);
publicvoidnotifyRecvAge(intnum);
publicvoidnotifyRecvSex(booleanbool);
publicvoidnotifyRecvAddress(String address);
}
包notify中:
//一个最基本的空的interface,用来管理具体的被观察者
publicinterfaceBaseListener {
}
publicinterfaceOnRecvMsgHaHaextendsBaseListener{
publicvoidonRecvHaHa(String haha);
}
publicinterfaceOnRecvMsgXiXiextendsBaseListener{
publicvoidonRecvXiXi(String xixi);
}
publicinterfaceOnRecvMsgNameextendsBaseListener{
publicvoidonRecvName(String name);
}
....还有其他的具体的被观察者,格式同上面。
包manager中:
publicinterfaceManagerOne{
publicvoidaddListenerOne(RecvMsgOne listener);
publicvoidremoveListenerOne(RecvMsgOne listener);
}
publicinterfaceManagerTwo {
publicvoidaddListenerTwo(RecvMsgTwo listener);
publicvoidremoveListenerTwo(RecvMsgTwo listener);
}
包managerimpl中:
//实现了抽象的观察者ManagerOne,并且观察两个目标
publicclassManagerImplOneimplementsManagerOne, OnRecvMsgHaHa, OnRecvMsgXiXi{
publicManagerImplOne(){
SendMsgActivity.addListener(this);
}
privateList recvMsgOneList =newCopyOnWriteArrayList();
@Override
publicvoidaddListenerOne(RecvMsgOne listener) {
synchronized(recvMsgOneList) {
if(!recvMsgOneList.contains(listener)) {
recvMsgOneList.add(listener);
}
}
}
@Override
publicvoidremoveListenerOne(RecvMsgOne listener) {
synchronized(recvMsgOneList) {
if(recvMsgOneList.contains(listener)){
recvMsgOneList.remove(listener);
}
}
}
@Override
publicvoidonRecvXiXi(String xixi) {
synchronized(recvMsgOneList){
for(RecvMsgOne l : recvMsgOneList){
l.notifyRecvMsgXiXi(xixi);
}
}
}
@Override
publicvoidonRecvHaHa(String haha) {
synchronized(recvMsgOneList){
for(RecvMsgOne l : recvMsgOneList){
l.notifyRecvMsgHaHa(haha);
}
}
}
}
//实现了抽象的观察者ManagerTwo,并且观察四个目标
publicclassManagerImplTwoimplementsManagerTwo, OnRecvMsgName, OnRecvMsgAge,
OnRecvMsgSex, OnRecvMsgAddress {
publicManagerImplTwo(){
SendMsgActivity.addListener(this);
}
privateList recvMsgTwoList =newCopyOnWriteArrayList();
@Override
publicvoidaddListenerTwo(RecvMsgTwo listener) {
synchronized(recvMsgTwoList) {
if(!recvMsgTwoList.contains(listener)) {
recvMsgTwoList.add(listener);
}
}
}
@Override
publicvoidremoveListenerTwo(RecvMsgTwo listener) {
synchronized(recvMsgTwoList) {
if(recvMsgTwoList.contains(listener)) {
recvMsgTwoList.remove(listener);
}
}
}
@Override
publicvoidonRecvAddress(String address) {
synchronized(recvMsgTwoList) {
for(RecvMsgTwo l : recvMsgTwoList) {
l.notifyRecvAddress(address);
}
}
}
@Override
publicvoidonRecvSex(booleansex) {
synchronized(recvMsgTwoList) {
for(RecvMsgTwo l : recvMsgTwoList) {
l.notifyRecvSex(sex);
}
}
}
@Override
publicvoidonRecvAge(intage) {
synchronized(recvMsgTwoList){
for(RecvMsgTwo l : recvMsgTwoList) {
l.notifyRecvAge(age);
}
}
}
@Override
publicvoidonRecvName(String name) {
synchronized(recvMsgTwoList){
for(RecvMsgTwo l : recvMsgTwoList) {
l.notifyRecvName(name);
}
}
}
}
还有一个很重要的包:common
//用来管理所有的观察者
publicclassGlobalManager {
privatestaticManagerOne managerOne;
privatestaticManagerTwo managerTwo;
publicstaticManagerOne getManagerOne(){
if(null== managerOne){
managerOne =newManagerImplOne();
}
returnmanagerOne;
}
publicstaticManagerTwo getManagerTwo(){
if(null== managerTwo){
managerTwo =newManagerImplTwo();
}
returnmanagerTwo;
}
}
上面就是大体的观察者和被观察者,其次就是实现观察者接口的对象,具体分为4种类型:Activity,Fragment,Service和普通的类(TestPrint.java)。大体的功能已经在上面说过了。因为除了实现观察者外,他们都没有其他的逻辑,所以这里就不列出代码了。下面是模拟接收到消息并通知观察者的SendMsgActivity:
publicclassSendMsgActivityextendsActivity{
privateButton btnSend;
privateEditText edit;
privateString msgType;
@Override
protectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle("模拟收到消息的界面");
setContentView(R.layout.activity_sendmsg);
btnSend = (Button) findViewById(R.id.sendAct_send);
edit = (EditText) findViewById(R.id.sendAct_edit);
btnSend.setOnClickListener(newOnClickListener() {
@Override
publicvoidonClick(View v) {
sendMsg();
}
});
}
protectedvoidsendMsg() {
msgType = edit.getText().toString().trim();
inttype = Integer.valueOf(msgType);
switch(type) {
case1:
for(OnRecvMsgHaHa l : onRecvMsgHaHaList){
l.onRecvHaHa("Hahahaha...");
}
break;
case2:
for(OnRecvMsgXiXi l : onRecvMsgXiXiList){
l.onRecvXiXi("Xixixixi...");
}
break;
case3:
for(OnRecvMsgName l : onRecvMsgNameList){
l.onRecvName("XiaoMing");
}
break;
case4:
for(OnRecvMsgSex l : onRecvMsgSexList){
l.onRecvSex(true);
}
break;
case5:
for(OnRecvMsgAge l : onRecvMsgAgeList){
l.onRecvAge(24);
}
break;
case6:
for(OnRecvMsgAddress l : onRecvMsgAddressList){
l.onRecvAddress("杭州市西湖区");
}
break;
default:
break;
}
}
/*** 通过下面的list给所有注册的观察者发送消息 ***/
privatestaticList onRecvMsgAddressList =newCopyOnWriteArrayList();
privatestaticList onRecvMsgAgeList =newCopyOnWriteArrayList();
privatestaticList onRecvMsgHaHaList =newCopyOnWriteArrayList();
privatestaticList onRecvMsgXiXiList =newCopyOnWriteArrayList();
privatestaticList onRecvMsgSexList =newCopyOnWriteArrayList();
privatestaticList onRecvMsgNameList =newCopyOnWriteArrayList();
publicstaticvoidaddListener(BaseListener listener){
if(listenerinstanceofOnRecvMsgAddress){
onRecvMsgAddressList.add((OnRecvMsgAddress)listener);
}
if(listenerinstanceofOnRecvMsgAge){
onRecvMsgAgeList.add((OnRecvMsgAge)listener);
}
if(listenerinstanceofOnRecvMsgHaHa){
onRecvMsgHaHaList.add((OnRecvMsgHaHa)listener);
}
if(listenerinstanceofOnRecvMsgXiXi){
onRecvMsgXiXiList.add((OnRecvMsgXiXi)listener);
}
if(listenerinstanceofOnRecvMsgSex){
onRecvMsgSexList.add((OnRecvMsgSex)listener);
}
if(listenerinstanceofOnRecvMsgName){
onRecvMsgNameList.add((OnRecvMsgName)listener);
}
}
/**
* 会移除所有的观察者,在程序退出时调用是一种好的编码习惯
* @param listener
*/
publicstaticvoidremoveListener(BaseListener listener){
if(listenerinstanceofOnRecvMsgAddress){
onRecvMsgAddressList.remove((OnRecvMsgAddress)listener);
}
if(listenerinstanceofOnRecvMsgAge){
onRecvMsgAgeList.remove((OnRecvMsgAge)listener);
}
if(listenerinstanceofOnRecvMsgHaHa){
onRecvMsgHaHaList.remove((OnRecvMsgHaHa)listener);
}
if(listenerinstanceofOnRecvMsgXiXi){
onRecvMsgXiXiList.remove((OnRecvMsgXiXi)listener);
}
if(listenerinstanceofOnRecvMsgSex){
onRecvMsgSexList.remove((OnRecvMsgSex)listener);
}
if(listenerinstanceofOnRecvMsgName){
onRecvMsgNameList.remove((OnRecvMsgName)listener);
}
}
}
下面是整个demo运行后的效果图:
输入的数字1--6代表上面的6中消息类型,输入数字,点击发送按钮后,目标会通知各自的观察者。
具体的代码可以在这里下载:https://github.com/215836017/ObservableDemo.git
同时欢迎大佬给予宝贵的建议和意见。