简单说,对象间定义了一对多的依赖,当一个对象的改变,可以通知依赖的对象。
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写法和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