用Java設計形式中的不雅察者形式開辟微信"號的例子。本站提示廣大學習愛好者:(用Java設計形式中的不雅察者形式開辟微信"號的例子)文章只能為提供參考,不一定能成為您想要的結果。以下是用Java設計形式中的不雅察者形式開辟微信"號的例子正文
還記得警匪片上,強盜們是怎樣合營實行犯法的嗎?一個團伙在停止偷盜的時刻,總有一兩小我在門口把風——假如有甚麼風吹草動,則會立刻告訴外面的同伙緊迫退卻。或許放風的人其實不必定熟悉外面的每個同伙;而在外面或許有新來的小弟不熟悉這個放風的。然則這沒甚麼,這個影響不了他們之間的通信,由於他們之間有早已約定好的記號。
呵呵,下面提到的放風者、偷盜者之間的關系就是不雅察者形式在實際中的活生生的例子。
不雅察者(Observer)形式別名宣布-定閱(Publish/Subscribe)形式。GOF給不雅察者形式以下界說:界說對象間的一種一對多的依附關系,當一個對象的狀況產生轉變時,一切依附於它的對象都獲得告訴並被主動更新。
在這裡先講一上面向對象設計的一個主要准繩——單一職責准繩。是以體系的每一個對象應當將重點放在成績域中的團圓籠統上。是以幻想的情形下,一個對象只做一件工作。如許在開辟中也就帶來了諸多的利益:供給了重用性和保護性,也是停止重構的優越的基本。
是以簡直一切的設計形式都是基於這個根本的設計准繩來的。不雅察者形式的來源我認為應當是在GUI和營業數據的處置上,由於如今絕年夜多半講授不雅察者形式的例子都是這一題材。然則不雅察者形式的運用決不只限於此一方面。
好了,關於界說的懂得老是須要實例來解析的,現在的微佩服務號相當火啊,上面就以微佩服務號為配景,給年夜家引見不雅察者形式。
看一張圖:
個中每一個應用者都有上圖中的3條線,為了使圖片清楚省略了。
如上圖所示,辦事號就是我們的主題,應用者就是不雅察者。如今我們明白下功效:
1、辦事號就是主題,營業就是推送新聞
2、不雅察者只須要定閱主題,只需有新的新聞就會送來
3、當不想要此主題新聞時,撤消定閱
4、只需辦事號還在,就會一向有人定閱
好了,如今我們來看看不雅察者形式的類圖:
接上去就是代碼時光了,我們模仿一個微信3D彩票辦事號,和一些定閱者。
起首開端寫我們的主題接口,和不雅察者接口:
package com.zhy.pattern.observer;
/**
* 主題接口,一切的主題必需完成此接口
*
* @author zhy
*
*/
public interface Subject
{
/**
* 注冊一個不雅察著
*
* @param observer
*/
public void registerObserver(Observer observer);
/**
* 移除一個不雅察者
*
* @param observer
*/
public void removeObserver(Observer observer);
/**
* 告訴一切的不雅察著
*/
public void notifyObservers();
}
package com.zhy.pattern.observer;
/**
* @author zhy 一切的不雅察者須要完成此接口
*/
public interface Observer
{
public void update(String msg);
}
接上去3D辦事號的完成類:
package com.zhy.pattern.observer;
import java.util.ArrayList;
import java.util.List;
public class ObjectFor3D implements Subject
{
private List<Observer> observers = new ArrayList<Observer>();
/**
* 3D彩票的號碼
*/
private String msg;
@Override
public void registerObserver(Observer observer)
{
observers.add(observer);
}
@Override
public void removeObserver(Observer observer)
{
int index = observers.indexOf(observer);
if (index >= 0)
{
observers.remove(index);
}
}
@Override
public void notifyObservers()
{
for (Observer observer : observers)
{
observer.update(msg);
}
}
/**
* 主題更新新聞
*
* @param msg
*/
public void setMsg(String msg)
{
this.msg = msg;
notifyObservers();
}
}
模仿兩個應用者:
package com.zhy.pattern.observer;
public class Observer1 implements Observer
{
private Subject subject;
public Observer1(Subject subject)
{
this.subject = subject;
subject.registerObserver(this);
}
@Override
public void update(String msg)
{
System.out.println("observer1 獲得 3D 號碼 -->" + msg + ", 我要記上去。");
}
}
package com.zhy.pattern.observer;
public class Observer2 implements Observer
{
private Subject subject ;
public Observer2(Subject subject)
{
this.subject = subject ;
subject.registerObserver(this);
}
@Override
public void update(String msg)
{
System.out.println("observer2 獲得 3D 號碼 -->" + msg + "我要告知捨友們。");
}
}
可以看出:辦事號中保護了一切向它定閱新聞的應用者,當辦事號有新新聞時,告訴一切的應用者。全部架構是一種松耦合,主題的完成不依附與應用者,當增長新的應用者時,主題的代碼不須要轉變;應用者若何處置獲得的數據與主題有關;
最初看下測試代碼:
package com.zhy.pattern.observer.test;
import com.zhy.pattern.observer.ObjectFor3D;
import com.zhy.pattern.observer.Observer;
import com.zhy.pattern.observer.Observer1;
import com.zhy.pattern.observer.Observer2;
import com.zhy.pattern.observer.Subject;
public class Test
{
public static void main(String[] args)
{
//模仿一個3D的辦事號
ObjectFor3D subjectFor3d = new ObjectFor3D();
//客戶1
Observer observer1 = new Observer1(subjectFor3d);
Observer observer2 = new Observer2(subjectFor3d);
subjectFor3d.setMsg("20140420的3D號碼是:127" );
subjectFor3d.setMsg("20140421的3D號碼是:333" );
}
}
輸入成果:
observer1 獲得 3D 號碼 -->20140420的3D號碼是:127, 我要記上去。 observer2 獲得 3D 號碼 -->20140420的3D號碼是:127我要告知捨友們。 observer1 獲得 3D 號碼 -->20140421的3D號碼是:333, 我要記上去。 observer2 獲得 3D 號碼 -->20140421的3D號碼是:333我要告知捨友們。
關於JDK或許Andorid中都有許多處所完成了不雅察者形式,好比XXXView.addXXXListenter , 固然了 XXXView.setOnXXXListener紛歧定是不雅察者形式,由於不雅察者形式是一種一對多的關系,關於setXXXListener是1對1的關系,應當叫回調。
祝賀你學會了不雅察者形式,下面的不雅察者形式使我們從無到有的寫出,固然了java中曾經幫我們完成了不雅察者形式,借助於java.util.Observable和java.util.Observer。
上面我們應用Java內置的類完成不雅察者形式:
起首是一個3D彩票辦事號主題:
package com.zhy.pattern.observer.java;
import java.util.Observable;
public class SubjectFor3d extends Observable
{
private String msg ;
public String getMsg()
{
return msg;
}
/**
* 主題更新新聞
*
* @param msg
*/
public void setMsg(String msg)
{
this.msg = msg ;
setChanged();
notifyObservers();
}
}
上面是一個雙色球的辦事號主題:
package com.zhy.pattern.observer.java;
import java.util.Observable;
public class SubjectForSSQ extends Observable
{
private String msg ;
public String getMsg()
{
return msg;
}
/**
* 主題更新新聞
*
* @param msg
*/
public void setMsg(String msg)
{
this.msg = msg ;
setChanged();
notifyObservers();
}
}
最初是我們的應用者:
package com.zhy.pattern.observer.java;
import java.util.Observable;
import java.util.Observer;
public class Observer1 implements Observer
{
public void registerSubject(Observable observable)
{
observable.addObserver(this);
}
@Override
public void update(Observable o, Object arg)
{
if (o instanceof SubjectFor3d)
{
SubjectFor3d subjectFor3d = (SubjectFor3d) o;
System.out.println("subjectFor3d's msg -- >" + subjectFor3d.getMsg());
}
if (o instanceof SubjectForSSQ)
{
SubjectForSSQ subjectForSSQ = (SubjectForSSQ) o;
System.out.println("subjectForSSQ's msg -- >" + subjectForSSQ.getMsg());
}
}
}
看一個測試代碼:
package com.zhy.pattern.observer.java;
public class Test
{
public static void main(String[] args)
{
SubjectFor3d subjectFor3d = new SubjectFor3d() ;
SubjectForSSQ subjectForSSQ = new SubjectForSSQ() ;
Observer1 observer1 = new Observer1();
observer1.registerSubject(subjectFor3d);
observer1.registerSubject(subjectForSSQ);
subjectFor3d.setMsg("hello 3d'nums : 110 ");
subjectForSSQ.setMsg("ssq'nums : 12,13,31,5,4,3 15");
}
}
測試成果:
subjectFor3d's msg -- >hello 3d'nums : 110 subjectForSSQ's msg -- >ssq'nums : 12,13,31,5,4,3 15
可以看出,應用Java內置的類完成不雅察者形式,代碼異常簡練,對了addObserver,removeObserver,notifyObservers都曾經為我們完成了,一切可以看出Observable(主題)是一個類,而不是一個接口,根本上書上都關於Java的如斯設計抱有不和的立場,認為Java內置的不雅察者形式,守法了面向接口編程這個准繩,然則假如轉念想想,切實其實你拿一個主題在這寫不雅察者形式(我們本身的完成),接口的思惟很好,然則假如如今持續添加許多個主題,每一個主題的ddObserver,removeObserver,notifyObservers代碼根本都是雷同的吧,接口是沒法完成代碼復用的,並且也沒有方法應用組合的形式完成這三個辦法的復用,所以我認為這裡把這三個辦法在類中完成是公道的。