Pattern Observer:
通過下面的例子來學習觀察者模式。 我們有 兩個接口Editeur.java和Lecteur.java。可以了解為編輯者和讀者。
Editeur的代碼如下,它要實作堵住:
package observeur;
public interface Editeur {
<span style="white-space:pre"> </span>public void ajouteLecteur(Lecteur l);
<span style="white-space:pre"> </span>public void surpprimeLecteur(Lecteur l);
<span style="white-space:pre"> </span>public void notifierLecteur();
}
LibData類繼承了Editeur接口,這裡它有四個成員變量,nbLecture記錄讀者總數。Lecture類型的ArrayList,用于存放讀者。它實作了Editeur的接口方法,代碼如下:
package observeur;
import java.util.ArrayList;
public class LibData implements Editeur{
private int ca;
private int nbVol;
private int nbLecteur;
ArrayList<Lecteur> listLecteurs= new ArrayList<Lecteur>();
public void ajouteLecteur(Lecteur l) {
this.listLecteurs.add(l);
}
public void surpprimeLecteur(Lecteur l) {
this.listLecteurs.remove(l);
}
public void notifierLecteur() {
for(Lecteur lecteur: this.listLecteurs){
lecteur.upDate(ca, nbVol, nbLecteur);
}
}
public void dataChanged(){
notifierLecteur();
}
public void setChanged(int ca, int nbVol, int nbLecteur){
this.ca=ca;
this.nbVol=nbVol;
this.nbLecteur=nbLecteur;
dataChanged();
}
}
Lecture的代碼如下,因為它是讀者,是以隻需要做一件事,更新資料:
package observeur;
public interface Lecteur {
public void upDate(int ca, int nbVol, int nbLecteur);
}
AfficheCourant 類繼承了Lecture接口,每次執行個體化它的時候都需要将它注冊給一個Editeur。并且它實作了Lecture接口的方法。
package observeur;
public class AfficheCourant implements Lecteur{
private int ca;
private int nbVol;
private int nbLecteur;
private Editeur libData;
public AfficheCourant (Editeur libData) {
this.libData = libData;
libData.ajouteLecteur(this);
}
public void upDate(int ca, int nbVol, int nbLecteur) {
this.ca = ca;
this.nbVol = nbVol;
this.nbLecteur = nbLecteur;
}
public void display(){
System.out.println("ca="+String.valueOf(ca)+" nbVol="+String.valueOf(nbVol)+" bLecteur="+String.valueOf(nbLecteur));
}
}
Main()方法,代碼如下:
package observeur;
public class Essi {
public static void main(String[] args) {
// TODO Auto-generated method stub
LibData libData = new LibData();
AfficheCourant afficheCourant = new AfficheCourant(libData);
//afficheStat
libData.setChanged(12, 12, 23);
libData.setChanged(312, 312, 1);
//pour tester le resultat
afficheCourant.display();
}
}
小結:
observateur 可以有N個執行個體。
Observable 隻能有1個執行個體。
Chaque Abonne a son Editeur.
Pattern Singleton: 有建立出多個執行個體的風險,因為我們的電腦cpu實際上是單線程運算的,當一個執行個體恰好運作完了if判斷,等于null,這時另一個建立執行個體的代碼也恰好來到if這裡判斷,那麼它的結果頁必然是null的,是以這時就會建立出兩個執行個體。
public class Singleton{
private static Singleton instance = null;
private Singleton(){}
public static Singleton getInstance(){//需要<span style="color: rgb(0, 0, 139); font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; font-size: 14px; line-height: 17.8048000335693px;">synchronized</span>
if(instance==null){
instance = new Singleton();
}
return instance;
}
}
是以需要synchronise 為了避免多個執行個體的可能性,在getInstance()方法前面加上synchronized。
public class Singleton{
private static Singleton instance = null;
private Singleton(){}
public synchronized static Singleton getInstance(){
if(instance==null){
instance = new Singleton();
}
return instance;
}
}
//class Singleton 和 pattern Singleton 的差別:
Singleton static s = new Singleton (); //static instance
Singleton s = Singleton.getInstance();//pattern Singleton
Pattern Iterator:
這裡我們建3個類: Boisson.java, IteratorSurBoisson.java和Main.java。
Boisson.java繼承了Iterable接口(java)内定義一個字元串數組boisson,初始值為:{"the","boisson","chocolat"}; 具體代碼:
package Iterator;
import java.util.Iterator;
public class Boisson implements Iterable<String> {
String[] boisson= {"the","boisson","chocolat"};
@Override
public Iterator<String> iterator(){
return new IteratorSurBoissons(this);
}
public int length(){
return boisson.length;
}
public final String[] getBoisson() {
return boisson;
}
public final void setBoisson(String[] boisson) {
this.boisson = boisson;
}
}
這裡需要我們重寫iterator()方法,它傳回一個IteratorSurBoissons的執行個體。
IteratorSurBoissons 類繼承了Iterator接口。它有兩個成員變量,一個是Boisson,另一個是整型的conpteur,用來記錄指針(下标)初始值為0。在它的構造函數裡 初始化了Boisson執行個體。這裡要實作hanNext()和next()方法,分别用來判斷是否有下一個元素,取下一個元素。 具體代碼:
package Iterator;
import java.util.Iterator;
public class IteratorSurBoissons implements Iterator<String>{
private Boisson boissons;
int compteur=0;
public IteratorSurBoissons(Boisson boissonsAparcourir){
this.boissons= boissonsAparcourir;
}
@Override
public boolean hasNext(){
if(this.compteur < boissons.length()){
return true;
}else {
return false;
}
}
@Override
public String next(){
String b = boissons.boisson[compteur];
this.compteur++;
return b;
}
}
main()類裡, 建立了一個Boisson執行個體b,調用此b的iterator()方法 傳回一個 Iterator<String>給 packVikingIterator。一個while循環,讀取Boisson的值。
package Iterator;
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Boisson b = new Boisson();
Iterator<String> packVikingIterator = b.iterator();
while (packVikingIterator.hasNext()) {
System.out.println(packVikingIterator.next());
}
}
}