一對多關係(Subject & Observer),實際資料位於主題(Subject)中,觀察者依附於主題,只要主題資料有更動,觀察者也會一併被通知
主題類別(要發送訊息的類別實作它)
public interface Subject {//主題 public void registerObserver(Observer ob);// 註冊觀察者 public void removeObserver(Observer ob);// 移除觀察者 public void notifyObservers();// 通知所有觀察者資料變動 }
觀察者類別(要接收訊息的類別實作它)
import java.util.ArrayList; interface Observer {// 觀察者 public void updateNum(ArrayList<Integer> al);// 所有觀察者更新資料 }
樂透開獎機(這是我的主題)
import java.util.ArrayList; import java.util.Random; public class LottoSystem implements Subject, Runnable {// Runnable只用於方便開獎,沒有其他用途 ArrayList<Observer> obsal;// 存放所有觀察者 ArrayList<Integer> numberal;// 存放樂透數字 public LottoSystem() { obsal = new ArrayList<Observer>(); numberal = new ArrayList<Integer>(); for (int i = 0; i < 6; i++) {// 初始 6 個號碼為 0 numberal.add(0); } } public void registerObserver(Observer ob) { obsal.add(ob); } public void removeObserver(Observer ob) { int i = obsal.indexOf(ob); if (i >= 0) { obsal.remove(i); } } // 主題更新資料之後,必須呼叫此方法以通知所有觀察者 public void notifyObservers() { for (int i = 0; i < obsal.size(); i++) { Observer ob = (Observer) obsal.get(i); ob.updateNum(numberal); } } public void lottery() { Random r = new Random(); for (int i = 0; i < numberal.size(); i++) { int tempnum = r.nextInt(48); for (int j = 0; j < numberal.size(); j++) { if (tempnum == numberal.get(j) && i != j) { tempnum = r.nextInt(48); j = 0; i = 0; } } numberal.set(i, tempnum); } notifyObservers(); } // 模擬開獎 public void run() { while (true) { lottery(); try { Thread.currentThread().sleep(1500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
這是購買樂透的人(也是觀察者)
import java.util.ArrayList; public class ShowLottoNum implements Observer { String name; ArrayList<Integer> numlist;// 存放樂透數字 Subject s;// 主題,用來註冊該觀察者 // 當觀察者建構自己必須傳入已存在的主題物件以註冊自己本身 public ShowLottoNum(Subject s, String name) { this.s = s; s.registerObserver(this); this.name = name; } @Override public void updateNum(ArrayList<Integer> al) { // TODO Auto-generated method stub numlist = al; showNum(); } public void showNum() { System.out.print(name + " get number :"); for (int i = 0; i < numlist.size(); i++) { System.out.print(numlist.get(i) + ","); } System.out.println(); } }
測試程式
import java.util.ArrayList; import java.util.List; public class Simulator { public static void main(String[] args) { LottoSystem ls = new LottoSystem();// 主題 ShowLottoNum sln = new ShowLottoNum(ls, "John");// 觀察者1(若需要更多觀察者,只要照著 // ShowLottoNum 建構即可 ) ShowLottoNum sln2 = new ShowLottoNum(ls, "Peter");// 觀察者2 ShowLottoNum sln3 = new ShowLottoNum(ls, "Little flower");// 觀察3 // 開始開獎 new Thread(ls).start(); } }
Article Comments