คราวนี้มาเป็น Pattern ที่ 2 แล้วที่ผมเขียนในเรื่อง Design Pattern in Depth โดยตอนนี้ขอเขียนเกี่ยวกับ BNK48 แล้วกันครับ น้องเณอปราง ^___^
ทำไมต้องใช้ 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.