คราวนี้มาเป็น Pattern ที่ 2 แล้วที่ผมเขียนในเรื่อง Design Pattern in Depth โดยตอนนี้ขอเขียนเกี่ยวกับ BNK48 แล้วกันครับ น้องเณอปราง ^___^
Table of Contents
ทำไมต้องใช้ Observer Pattern
- ถ้า Design ด้านแนวคิดที่ว่า อยากรู้ให้มาถาม (Server) สิ่งที่เกิดขึ้น คือ Client ต้องคอยวิ่งมาถาม (Request) ตรวจสอบว่าข้อมูลที่ Server มัน Update ยัง … Update ยังงง
- ถ้าเกิดข้อมูลที่ต้องกระจายเป็นข้อมูลของวง Girl Group อย่าง BNK48 กำหนดให้เป็น Class BNK48Data ซึ่งมีหน้าที่ (Operation)
- Method getMemberData() – ข้อมูลสมาชิก
- Method getVote() – ดูผลการโหวต
- Method BNKDataChange() – เอาไว้ Update Data ของกับหน้าจอของ User
- แล้วถ้าต้องเพิ่ม Dashboard สรุป stat ที่งาน (มโนไปไกลเลยเรา 555) คือ แก้ Code ใน Class BNK48VoteDataOld !!!!!!
- มาดู Class Diagram แบบแรกกันครับ

- !!!! เราทำอย่างไรให้ Class BNK48Data นั้น Clean ที่สุด แก้อะไรก็แล้วเพิ่มแล้ว ไม้ต้องไปสั่ง Update ให้ Client ด้วย ถ้ามีดูที่ Class BNKVoteDateOld Method BNK48DataChange() มันต้องไป Update Display ทั้ง 2 เอง ตาม Code ดังนี้
public class BNK48VoteDataOld {
// instance variable declarations
// ....
public void BNK48DataChanged() {
// Some logic ...
userDisplay.update(MemberData, CurrentVote);
dashboardStatDisplay.update(MemberData, CurrentVote);
}
// other methods ...
}เมื่อไหร่ควรจะใช้
- ตอนที่จำเป็นต้องกระจายข้อมูลเยอะให้กับผู้รับที่มีจำนวนเยอะมากๆ (ONE TO MANY) อาทิ และไม่อยากให้ Server รับภาระให้การ Push ข้อมูลไปที่ Client เมื่อมีการเปลี่ยนแปลง เช่น
- ตลาดหุ้น ต้องการส่งการแจ้งเตือนของราคาตลาดที่เปลี่ยนแปลง ไปยังโปรแกรม Trade หุ้นที่ได้ลงะทะบียนไว้ (Subscribe)
- วงไอดอล BNK48 ต้องการแจ้งเตือนข้อมูลการออก Event ในแต่ละวันให้กับเหล่าโอดะที่ติดตามอยู่
- สิ่งที่ได้ - ลด coupling ระหว่าง class เพราะไม่ต้องรู้ว่ามีตัว Observer ทั้งหมดกี่รูปแบบ
Pattern มันเป็นอย่างไร - Class Diagram
- ใช้ Observer แล้วเป็นอย่างไร มาดูกัน ภาระของ Subject BNK48VoteData ลดลงไปครับ

- ส่วนประกอบที่สำคัญกันบ้าง
- Subject - แหล่งข่าว (ONE)
- Observer - ผู้สังเกตุการณ์ (MANY)
มุมมองตอน Runtime - Object Diagram
- อันนี้ไม่ขออธิบายเยอะครับ รูปมันบอกอยู่แล้ว

มุมมองลำดับการทำงาน - Sequence Diagram
- ตอน Register Observer ถ้าดูจาก Code ด้านล่างเป็น Method registerObserver(Observer o)

- ตอน Notify

- ตอน Notify - อันนี้ใช้ Loop เพราะถ้าของจริง คงไม่มี Display แค่ 2 อันครับ ถ้าดูจาก Code ด้านล่างเป็น Method notifyObservers()

ปิดท้ายด้วย Source Code (อาจจะรันไม่ได้ Code เทพ No Complier 5555) เพื่อให้เห็นภาพรวมตาม Sequence Diagram
- ส่วนของ Subject
public class BNK48VoteData implements Subject {
// instance variable declarations
private ArrayList observers;
// Other Variable ..
public BNK48VoteData() {
observers = new ArrayList();
}
public void registerObserver(Observer o) {
observers.add(o);
}
public void removeObserver(Observer o) {
int i = observers.indexOf(o);
if (i >= 0) {
observers.remove(i);
}
}
public void notifyObservers() {
for (int i = 0; i < observers.size(); i++) {
Observer observer = (Observer)observers.get(i);
observer.update(MemberData, CurrentVote);
}
}
public void BNK48DataChanged() {
//เห็นว่า Code มันจะไม่รู้จักกับ Display ตรงๆนะครับ มันรู้จักกับ Interface Observer แทน
notifyObservers();
}
public void getBNKData() {
//Set Data .....
//NotifyChange
BNK48DataChanged();
}
}- ส่วนของ Observer
import java.util.Observable;
import java.util.Observer;
public class UserDisplay implements Observer, DisplayStyle {
Observable observable;
//Other Local Data
public UserDisplay(Observable observable) {
this.observable = observable;
observable.addObserver(this);
}
public void update(Observable obs, Object arg) {
if (obs instanceof BNK48VoteData) {
BNK48VoteData data = (BNK48VoteData)obs;
//Do Something ...
display();
}
}
public void display() {
//Some implementation here!!!
}
}หมายเหตุ
- ทำไปทำมา ไม่น่าตั้งชื่อ Class เป็น BNK48 เลย มันดูเฉพาะเจาะจงมาก น่าจะปรับเป็น Class MemberVoting แทน จะได้เอาไปใช้กับหลายๆกรณีที่คล้ายคลึงกันครับ
Discover more from naiwaen@DebuggingSoft
Subscribe to get the latest posts sent to your email.


