观察者模式

文章目录

      • 定义
      • 观察者实现接口
      • 主题 (被观察者类)
      • 观察者白话描述
      • 变形的观察者
      • kotlin实现

定义

简单说,对象间定义了一对多的依赖,当一个对象的改变,可以通知依赖的对象。

java 支持

观察者实现接口

public interface Observer{
    
    void update(Observable 0, Object arg);
}

主题 (被观察者类)

public class Observable{
    
    private boolean changed = false;
    
    //一个持有观察者的容器
    private Vector obs;
    
    public Observable(){
        obs = new Vector<>();
    }
    
    //添加
    
    public synchronized void addObserver(Observer o){
        
        if(0 == null){
            throw new NullPointerException
        }
        if(!obs.contains(o)){
            obs.addElements(o)
        }
    }
    
    // 移除
     public synchronized void deleteObserver(Observer o){
         obs.removeElement(o);
     }
     
     public synchronized void deleteObservers(){
         obs.removeAllElements();
     }
    
    
    //通知方法
    public void notifyObservers(){
        notifyObservers(null);
    }
    
    
    public void notifyObservers(Object arg){
        
        Object[] arrLocal;
        
        synchronized(this){
            if(!hasChanged){
                return;
            }
            
            arrlocal = obs.toArray();
            clearChanged();
            
        }
        
        for(int i= arrLocal.length-1; i>=0, i--){
            ((Observer)arrLocal[i]).update(this,arg);
        }
    }
    
    
    protected synchronized void setChanged(){
        changed = true;
    }
    
    public synchronized boolean hasChanged(){
        return chanaged;
    }
    
    public synchronized int countObservers(){
        return obs.size();
    }
    
    
}

观察者白话描述

被观察者 有个容器用来装观察者,需要暴露增加观察者和删除观察者的方法,之后被观察者需要知道怎么通知到观察者,也就是需要知道调用观察者的方法。

JDK通过接口,约定了通知的方法,观察都需要实现该方法。如果去掉这个Observer这个接口,同样能实现的。

变形的观察者

public class ReflectInvokeObservable {
	/**
	 * java 泛型
	 * 泛型类,是在实例化类的时候指明泛型的具体类型;泛型方法,是在调用方法的时候指明泛型的具体类型。
	 * Class c表示这个Class可以放任意的类,?表示object(所有类都隐性从Object继承的)
	 * Class的作用就是指明泛型的具体类型,而Class类型的变量c,可以用来创建泛型类的对象。
	 */
	
	private Class [] mParameterType = null;
	
	private class ObservableStruct{
		//mMethod.invoke()相当于调用Observable 的 update方法
		public Method mMethod = null;
		//相当于Observable
		public Class mClass = null;
		public T mObjectRef = null;
		public ObservableStruct(T object , Method method){
			this.mMethod = method;
			this.mObjectRef = object;
			this.mClass = object.getClass();
		}
		
	}

	//相当于Observable中的 Vector obs;
	private LinkedList> mInvokeObservers = new LinkedList<>();
	
	public ObservableStruct(Class[] parameterType){
		this.mParameterType = parameterType;
		
	}
	
	public  boolean addObserver(T t, String methodName){

		if(isAdd(t)){
			return true;
		}
		try {
			Method m = t.getClass().getMethod(methodName, mParameterType);
			ObservableStruct  reflectStruct = new ObservableStruct<>(t, m);
			synchronized (this) {
				mInvokeObservers.add(reflectStruct);
			}

		} catch (NoSuchMethodException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	public void deleteObserver(Object object){
		synchronized (this) {
			for (ObservableStruct struct : mInvokeObservers) {
				if (struct != null && struct.mObjectRef == object) {
					mInvokeObservers.remove(struct);
					return;
				}
			}
		}
	}
	
	public boolean isAdd(Object object){
		synchronized (this) {
			for (ObservableStruct mInvokeObserver : mInvokeObservers) {
				if (mInvokeObserver.mObjectRef == object) {
					return true;
				}
			}
			return false;
		}
	}
	
	public void clear(){
		synchronized (this) {
			mInvokeObservers.clear();
		}
	}
	
	public void invoke(Object... params){
		
		if(arrayContentIsEqual(mParameterType, params, false)){
			checkParamsErrors(params);
		}
		try {
			callObservers(params);
		} catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
			e.printStackTrace();
		}
	}
	
	public void invokeWithAcceptSuberClass(Object... params){
		if(arrayContentIsEqual(mParameterType, params, true)){
			checkParamsErrors(params);
		}
		
		try {
			callObservers(params);
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
	}
	
	private void checkParamsErrors(Object... params){
		
		StringBuilder builder = new StringBuilder("参数类型不匹配, 期望的是:(");
		for(int i=0;i> tempList = null;
		synchronized (this) {
			tempList = new LinkedList<>(mInvokeObservers);
		}
		for(ObservableStruct reflectStruct : tempList){
			reflectStruct.mMethod.invoke(reflectStruct.mObjectRef, params);
		}
		tempList.clear();
		tempList = null;
	}
	
	public boolean  arrayContentIsEqual(Class[] a1 , Object[] a2 , boolean isAcceptSuperClass){
		
		if(a1 == null){
			return a2 == null  || a2.length == 0;
		}
		
		if(a2 == null){
			return a1.length == 0;
		}
		
		if(a1.length != a2.length ){
			return false;
		}
		
		for(int i=0; i < a1.length ; i++ ){
			if(isAcceptSuperClass){
				if(a2[i] != null && ! a1[i].isInstance(a2[i])){
					return false;
				}
			}else{
				if(a2[i] != null && a1[i] != a2.getClass()){
					return false;
				}
			}
		}
		
		return true;
	}
}

kotlin实现

kotlin写法和java类似, 但是kotlin提供的可观察属性 Delegates.observable 标注委托支持

Design-Patterns-In-Kotlin

Examp

interface TextChangedListener {

    fun onTextChanged(oldText: String, newText: String)
}

class PrintingTextChangedListener : TextChangedListener {
    
    private var text = ""
    
    override fun onTextChanged(oldText: String, newText: String) {
        text = "Text is changed: $oldText -> $newText"
    }
}

class TextView {

    val listeners = mutableListOf()

    var text: String by Delegates.observable("") { _, old, new ->
        listeners.forEach { it.onTextChanged(old, new) }
    }
}

Usage

val textView = TextView().apply {
    listener = PrintingTextChangedListener()
}

with(textView) {
    text = "Lorem ipsum"
    text = "dolor sit amet"
}

output

Text is changed  -> Lorem ipsum
Text is changed Lorem ipsum -> dolor sit amet

你可能感兴趣的:(设计模式)