android 源码设计模式之--观察者模式

sancaiodm Android应用 2021-10-09 1116 0

 观察者模式也叫订阅者模式 

1模式定义:

  定义对象间的一种一对多的依赖关系,当一个对象的状态发送改变时,所有依赖于它的对象都能得到通知并被自动更新,

 在观察者模式中,发生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标可以对应多个观察者

2应用场景

  当一个对象的状态改变时,与它所有的关联对象都会更新它已存在自己内部的状态


3组成部分

    观察者,我们称它为Observer,有时候我们也称它为订阅者,即Subscriber

    被观察者,我们称它为Observable,即可以被观察的东西,有时候还会称之为主题,即Subject

image.png

4示例场景说明

情景1

       有一种短信服务,比如天气预报服务,一旦你订阅该服务,你只需按月付费,付完费后,每天一旦有天气信息更新,它就会及时向你发送最新的天气信息。这样你需不时时刻刻关注天气变化,一但天气变化了你却能第一时间收到变化通知,


情景2

        杂志的订阅,你只需向邮局订阅杂志,缴纳一定的费用,当有新的杂志时,邮局会自动将杂志送至你预留的地址。


5代码示例讲解

1【实体类】--被观察的内容

package com.san.javatest.observer;
 
public class ContentObject {
 
	public String mManName = "aaa";
	public int mManAge = 30;
	public int mManMoney = 10000;
 
	
	public ContentObject(String mManName, int mManAge, int mManMoney) {
		super();
		this.mManName = mManName;
		this.mManAge = mManAge;
		this.mManMoney = mManMoney;
	}
 
	public String getmManName() {
		return mManName;
	}
 
	public void setmManName(String mManName) {
		this.mManName = mManName;
	}
 
	public int getmManAge() {
		return mManAge;
	}
 
	public void setmManAge(int mManAge) {
		this.mManAge = mManAge;
	}
 
	public int getmManMoney() {
		return mManMoney;
	}
 
	public void setmManMoney(int mManMoney) {
		this.mManMoney = mManMoney;
	}
 
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "ContentObject {"+
				"mManName ="+mManName+
				"  mManAge ="+mManAge+
				"  mManMoney ="+mManMoney+"}";
	}
}

2【被观察者】---管理观察者

package com.san.javatest.observer;
 
import java.util.ArrayList;
import java.util.List;
 
/**
 * 被观察者:Observable
 * 即主题: Subject
 * @author User
 * @param <T>
 *
 */
public class Observable<T> {
 
	private  List<Observer<T>> mListObserver = new ArrayList<Observer<T>>();
	public  void registerObserverable(Observer<T> mObserver){
		if(mListObserver != null){
			if(!mListObserver.contains(mObserver)){
				mListObserver.add(mObserver);
			}
		}
	}
	
	
	public  void unRegisterObserverable(Observer<T> mObserver){
		if(mListObserver != null){
			mListObserver.remove(mObserver);
		}
	}
	
	
	public void notifyChange(T t){
		for(Observer<T> mObserver: mListObserver){
			mObserver.noChange(t);
		}
	}
	
	public  void clearAllObserable(){
		if(mListObserver != null && mListObserver.size() != 0){
			mListObserver.clear();
		}
	}
}

3【观察者】  所有的观察者是它的派生类

package com.san.javatest.observer;
 
/*
 * 观察者:Observer 
 * 即订阅者:Subscriber
 */
public interface Observer<T> {
	
	public void noChange(T t);
 
}

4【触发使用类】

package com.san.javatest.observer;
 
public class MianTest {
 
	public static void main(String[] args) {
		//观察者1
		Observer<ContentObject> laowang = new Observer<ContentObject>(){
			@Override
			public void noChange(ContentObject mCObject) {
				// TODO Auto-generated method stub
				System.out.println(mCObject.toString());
			}
			
		};	
		
		//观察者2
		Observer<ContentObject> laoliu = new Observer<ContentObject>(){
			@Override
			public void noChange(ContentObject mCObject) {
				// TODO Auto-generated method stub
				System.out.println(mCObject.toString());
			}
			
		};	
		//观察者3
		Observer<ContentObject> laochen = new Observer<ContentObject>(){
			@Override
			public void noChange(ContentObject mCObject) {
				// TODO Auto-generated method stub
				System.out.println(mCObject.toString());
			}
			
		};
		
		ContentObject aa = new ContentObject("laowang",19,222);
		ContentObject bbb = new ContentObject("laoliu",29,8888);
		
		Observable<ContentObject> server = new Observable<ContentObject>();
		
		server.registerObserverable(laoliu);//注册观察者1
		server.registerObserverable(laowang);//注册观察者2
		server.registerObserverable(laochen);//注册观察者3
		
		server.notifyChange(aa);//将实例体类aa的内容更新发送给所有注册者
		System.out.println("----------------------");
		server.notifyChange(bbb);//将实例体类bbb的内容更新发送给所有注册者
		System.out.println("----------------------");
		server.unRegisterObserverable(laowang);//观察者2取消观察
		server.notifyChange(aa);
	}
}

示例代码输出:

ContentObject {mManName =laowang  mManAge =19  mManMoney =222}
ContentObject {mManName =laowang  mManAge =19  mManMoney =222}
ContentObject {mManName =laowang  mManAge =19  mManMoney =222}
----------------------
ContentObject {mManName =laoliu  mManAge =29  mManMoney =8888}
ContentObject {mManName =laoliu  mManAge =29  mManMoney =8888}
ContentObject {mManName =laoliu  mManAge =29  mManMoney =8888}
----------------------
ContentObject {mManName =laowang  mManAge =19  mManMoney =222}
ContentObject {mManName =laowang  mManAge =19  mManMoney =222}

上面示例中用的泛类,也就是说【被观察的内容】可以通用并未固定数据类型,上面【被观察的内容】是的人,下面我们稍做修改将【被观察的内容】改为: 新闻

   第一:创建【被观察的内容】新闻类

package com.san.javatest.observer;
 
public class ContentObjectNews {
 
	public String  mTitle;
	public String mContent;
	public String mAuthor;
	public ContentObjectNews(String mTitle, String mContent, String mAuthor) {
		super();
		this.mTitle = mTitle;
		this.mContent = mContent;
		this.mAuthor = mAuthor;
	}
	
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "News{ title ="+mTitle+
				"News Content ="+mContent+
				"News author ="+mAuthor+"}";
	}
}

2【触发使用类】

package com.kte.javatest.observer;
 
public class MianTest {
 
	public static void main(String[] args) {
		//观察者1
		Observer<ContentObjectMan> laowang = new Observer<ContentObjectMan>(){
			@Override
			public void noChange(ContentObjectMan mCObject) {
				// TODO Auto-generated method stub
				System.out.println(mCObject.toString());
			}
			
		};	
		
		//观察者2
		Observer<ContentObjectMan> laoliu = new Observer<ContentObjectMan>(){
			@Override
			public void noChange(ContentObjectMan mCObject) {
				// TODO Auto-generated method stub
				System.out.println(mCObject.toString());
			}
			
		};	
		//观察者3
		Observer<ContentObjectMan> laochen = new Observer<ContentObjectMan>(){
			@Override
			public void noChange(ContentObjectMan mCObject) {
				// TODO Auto-generated method stub
				System.out.println(mCObject.toString());
			}
			
		};
		
		
		ContentObjectMan aa = new ContentObjectMan("laowang",19,222);
		ContentObjectMan bbb = new ContentObjectMan("laoliu",29,8888);
		
		Observable<ContentObjectMan> server = new Observable<ContentObjectMan>();
		
		server.registerObserverable(laoliu);//注册观察者1
		server.registerObserverable(laowang);//注册观察者2
		server.registerObserverable(laochen);//注册观察者3
		
		//server.notifyChange(aa);//将实例体类aa的内容更新发送给所有注册者
		System.out.println("----------------------");
		//server.notifyChange(bbb);//将实例体类bbb的内容更新发送给所有注册者
		System.out.println("----------------------");
		server.unRegisterObserverable(laowang);//观察者2取消观察
		//server.notifyChange(aa);
		
		/*---------------------------------------------------------------------------------------*/
		Observer<ContentObjectNews>  newObserver1 = new Observer<ContentObjectNews>(){
			@Override
			public void noChange(ContentObjectNews t) {
				// TODO Auto-generated method stub
				System.out.println(t);
			}
		};
		
		Observer<ContentObjectNews>  newObserver2 = new Observer<ContentObjectNews>(){
			@Override
			public void noChange(ContentObjectNews t) {
				// TODO Auto-generated method stub
				System.out.println(t);
			}
		};
		ContentObjectNews news1 = new ContentObjectNews("news1","aaa","laowang");
		ContentObjectNews news2 = new ContentObjectNews("news2","bbb","laoli");
		Observable<ContentObjectNews> server2 = new Observable<ContentObjectNews>();
		server2.registerObserverable(newObserver1);
		server2.registerObserverable(newObserver2);
		server2.notifyChange(news1);
		server2.unRegisterObserverable(newObserver1);
		server2.notifyChange(news2);
	}
}

示例输出结果

----------------------
----------------------
News{ title =news1News Content =aaaNews author =laowang}
News{ title =news1News Content =aaaNews author =laowang}
News{ title =news2News Content =bbbNews author =laoli}


评论