Observer pattern dưới đây là một số ví dụ khác về việc sử dụng mô hình quan sát trong nhiều tình huống:
Ví dụ 1: Ứng dụng thảo luận
Một ứng dụng chat có một phòng chat (ChatRoom) và nhiều người dùng (Users). Tất cả người dùng trong phòng chat sẽ được thông báo khi có tin nhắn mới.
Không gian trò chuyện (Subject)
class ChatRoom { constructor() { this.users = []; this.messages = []; } // Thêm người dùng addUser(user) { this.users.push(user); } // Xóa người dùng removeUser(user) { this.users = this.users.filter(u => u !== user); } // Thêm tin nhắn addMessage(message) { this.messages.push(message); this.notifyUsers(); } // Thông báo cho tất cả người dùng notifyUsers() { this.users.forEach(user => user.update(this.messages)); } }
User (Observer)
class User { constructor(name) { this.name = name; } // Phương thức cập nhật update(messages) { console.log(`${this.name} nhận được tin nhắn mới:`); messages.forEach(message => console.log(message)); } }
Cách sử dụng:
const chatRoom = new ChatRoom(); const user1 = new User("Người dùng 1"); const user2 = new User("Người dùng 2"); chatRoom.addUser(user1); chatRoom.addUser(user2); chatRoom.addMessage("Xin chào mọi người!"); chatRoom.addMessage("Chúng ta có một tin nhắn mới.");
Một hệ thống dự báo thời tiết bao gồm một đối tượng theo dõi thời tiết (WeatherStation) và các quan sát viên (Displays). Tất cả các màn hình sẽ hiển thị thông tin cập nhật khi dữ liệu thời tiết thay đổi.
WeatherStation (Subject)
class WeatherStation { constructor() { this.displays = []; this.weatherData = null; } // Thêm màn hình hiển thị addDisplay(display) { this.displays.push(display); } // Xóa màn hình hiển thị removeDisplay(display) { this.displays = this.displays.filter(d => d !== display); } // Cập nhật dữ liệu thời tiết setWeatherData(weatherData) { this.weatherData = weatherData; this.notifyDisplays(); } // Thông báo cho tất cả màn hình hiển thị notifyDisplays() { this.displays.forEach(display => display.update(this.weatherData)); } }
Display (Observer)
class Display { constructor(type) { this.type = type; } // Phương thức cập nhật update(weatherData) { console.log(`Màn hình ${this.type} cập nhật dữ liệu thời tiết:`); console.log(weatherData); } }
Cách sử dụng:
const weatherStation = new WeatherStation(); const tempDisplay = new Display("Nhiệt độ"); const humidityDisplay = new Display("Độ ẩm"); weatherStation.addDisplay(tempDisplay); weatherStation.addDisplay(humidityDisplay); weatherStation.setWeatherData({ temperature: 25, humidity: 70 }); weatherStation.setWeatherData({ temperature: 26, humidity: 65 });
Một hệ thống quản lý sự kiện có một người quản lý sự kiện (EventManager) và nhiều người đăng ký (Subscribers). Tất cả những người đã đăng ký cho sự kiện sẽ được thông báo khi có sự kiện mới.
Subject
class EventManager { constructor() { this.subscribers = []; this.events = []; } // Thêm người đăng ký addSubscriber(subscriber) { this.subscribers.push(subscriber); } // Xóa người đăng ký removeSubscriber(subscriber) { this.subscribers = this.subscribers.filter(s => s !== subscriber); } // Thêm sự kiện addEvent(event) { this.events.push(event); this.notifySubscribers(); } // Thông báo cho tất cả người đăng ký notifySubscribers() { this.subscribers.forEach(subscriber => subscriber.update(this.events)); } }
Observer
class Subscriber { constructor(name) { this.name = name; } // Phương thức cập nhật update(events) { console.log(`${this.name} nhận được thông báo sự kiện mới:`); events.forEach(event => console.log(event)); } }
Cách sử dụng
const eventManager = new EventManager(); const subscriber1 = new Subscriber("Người đăng ký 1"); const subscriber2 = new Subscriber("Người đăng ký 2"); eventManager.addSubscriber(subscriber1); eventManager.addSubscriber(subscriber2); eventManager.addEvent("Sự kiện 1"); eventManager.addEvent("Sự kiện 2");
Những ví dụ này cho thấy cách mô hình quan sát có thể được sử dụng trong nhiều tình huống khác nhau để quản lý sự thay đổi trạng thái và thông báo cho nhiều đối tượng liên quan.
Khi một phòng khách sạn được đặt hoặc hủy trong hệ thống đặt chỗ khách sạn, các bộ phận khác nhau, bao gồm quản lý, bộ phận dọn phòng và lễ tân, phải được thông báo cho nhau.
Subject
class HotelManager { constructor() { this.rooms = []; this.observers = []; } // Thêm Observer addObserver(observer) { this.observers.push(observer); } // Xóa Observer removeObserver(observer) { this.observers = this.observers.filter(obs => obs !== observer); } // Thêm phòng addRoom(room) { this.rooms.push(room); this.notifyObservers(); } // Hủy phòng removeRoom(room) { this.rooms = this.rooms.filter(r => r !== room); this.notifyObservers(); } // Thông báo cho tất cả các Observer notifyObservers() { this.observers.forEach(observer => observer.update(this.rooms)); } }
Department (Observer)
class Department { constructor(name) { this.name = name; } // Phương thức cập nhật update(rooms) { console.log(`${this.name} nhận được thông báo về thay đổi trong danh sách phòng:`); rooms.forEach(room => console.log(room)); } }
Cách dùng
const hotelManager = new HotelManager(); const housekeeping = new Department("Dọn phòng"); const frontDesk = new Department("Lễ tân"); hotelManager.addObserver(housekeeping); hotelManager.addObserver(frontDesk); hotelManager.addRoom("Phòng 101"); hotelManager.addRoom("Phòng 102"); hotelManager.removeRoom("Phòng 101");
Trong một hệ thống thị trường chứng khoán, tất cả các nhà đầu tư được thông báo khi giá cổ phiếu thay đổi.
StockMarket (Subject)
class StockMarket { constructor() { this.prices = {}; this.investors = []; } // Thêm nhà đầu tư addInvestor(investor) { this.investors.push(investor); } // Xóa nhà đầu tư removeInvestor(investor) { this.investors = this.investors.filter(inv => inv !== investor); } // Cập nhật giá cổ phiếu updatePrice(stock, price) { this.prices[stock] = price; this.notifyInvestors(); } // Thông báo cho tất cả nhà đầu tư notifyInvestors() { this.investors.forEach(investor => investor.update(this.prices)); } }
Investor (Observer)
class Investor { constructor(name) { this.name = name; } // Phương thức cập nhật update(prices) { console.log(`${this.name} nhận được cập nhật giá cổ phiếu:`); console.log(prices); } }
Sử dụng
const stockMarket = new StockMarket(); const investor1 = new Investor("Nhà đầu tư 1"); const investor2 = new Investor("Nhà đầu tư 2"); stockMarket.addInvestor(investor1); stockMarket.addInvestor(investor2); stockMarket.updatePrice("AAPL", 150); stockMarket.updatePrice("GOOG", 1200);
Tất cả các thành viên nhóm trong một hệ thống quản lý dự án phải được thông báo khi tình trạng nhiệm vụ thay đổi.
ProjectManager (Subject)
class ProjectManager { constructor() { this.tasks = []; this.teamMembers = []; } // Thêm thành viên nhóm addTeamMember(member) { this.teamMembers.push(member); } // Xóa thành viên nhóm removeTeamMember(member) { this.teamMembers = this.teamMembers.filter(m => m !== member); } // Thêm nhiệm vụ addTask(task) { this.tasks.push(task); this.notifyTeamMembers(); } // Cập nhật nhiệm vụ updateTask(task) { const index = this.tasks.findIndex(t => t.id === task.id); if (index !== -1) { this.tasks[index] = task; this.notifyTeamMembers(); } } // Thông báo cho tất cả thành viên nhóm notifyTeamMembers() { this.teamMembers.forEach(member => member.update(this.tasks)); } }
TeamMember (Observer)
class TeamMember { constructor(name) { this.name = name; } // Phương thức cập nhật update(tasks) { console.log(`${this.name} nhận được cập nhật nhiệm vụ:`); console.log(tasks); } }
Sử dụng
const projectManager = new ProjectManager(); const member1 = new TeamMember("Thành viên 1"); const member2 = new TeamMember("Thành viên 2"); projectManager.addTeamMember(member1); projectManager.addTeamMember(member2); projectManager.addTask({ id: 1, name: "Nhiệm vụ 1", status: "Mới" }); projectManager.updateTask({ id: 1, name: "Nhiệm vụ 1", status: "Đang thực hiện" });
Trong một hệ thống quản lý đơn hàng, khi trạng thái của đơn hàng thay đổi, các bộ phận liên quan như kho, vận chuyển, và kế toán cần được thông báo.
OrderManager (Subject)
class OrderManager { constructor() { this.orders = []; this.departments = []; } // Thêm bộ phận addDepartment(department) { this.departments.push(department); } // Xóa bộ phận removeDepartment(department) { this.departments = this.departments.filter(dep => dep !== department); } // Thêm đơn hàng addOrder(order) { this.orders.push(order); this.notifyDepartments(); } // Cập nhật đơn hàng updateOrder(order) { const index = this.orders.findIndex(o => o.id === order.id); if (index !== -1) { this.orders[index] = order; this.notifyDepartments(); } } // Thông báo cho tất cả các bộ phận notifyDepartments() { this.departments.forEach(department => department.update(this.orders)); } }
Department (Observer)
class Department { constructor(name) { this.name = name; } // Phương thức cập nhật update(orders) { console.log(`${this.name} nhận được cập nhật đơn hàng:`); console.log(orders); } }
Sử dụng
const orderManager = new OrderManager(); const warehouse = new Department("Kho"); const shipping = new Department("Vận chuyển"); const accounting = new Department("Kế toán"); orderManager.addDepartment(warehouse); orderManager.addDepartment(shipping); orderManager.addDepartment(accounting); orderManager.addOrder({ id: 1, name: "Đơn hàng 1", status: "Mới" }); orderManager.updateOrder({ id: 1, name: "Đơn hàng 1", status: "Đang xử lý" });
Trong hệ thống quản lý blog, mọi người theo dõi (subscribers) sẽ được thông báo khi có bài viết mới.
Blog (Subject)
class Blog { constructor() { this.posts = []; this.subscribers = []; } // Thêm người theo dõi addSubscriber(subscriber) { this.subscribers.push(subscriber); } // Xóa người theo dõi removeSubscriber(subscriber) { this.subscribers = this.subscribers.filter(sub => sub !== subscriber); } // Thêm bài viết addPost(post) { this.posts.push(post); this.notifySubscribers(); } // Thông báo cho tất cả người theo dõi notifySubscribers() { this.subscribers.forEach(subscriber => subscriber.update(this.posts)); } }
Subscriber (Observer)
class Subscriber { constructor(name) { this.name = name; } // Phương thức cập nhật update(posts) { console.log(`${this.name} nhận được thông báo bài viết mới:`); console.log(posts); } }
Sử dụng:
const blog = new Blog(); const subscriber1 = new Subscriber("Người theo dõi 1"); const subscriber2 = new Subscriber("Người theo dõi 2"); blog.addSubscriber(subscriber1); blog.addSubscriber(subscriber2); blog.addPost({ title: "Bài viết 1", content: "Nội dung bài viết 1" }); blog.addPost({ title: "Bài viết 2", content: "Nội dung bài viết 2" });
Tất cả người hâm mộ trong một hệ thống quản lý sự kiện thể thao sẽ được thông báo khi kết quả của trận đấu thay đổi.
SportsEvent (Subject)
class SportsEvent { constructor() { this.matches = []; this.fans = []; } // Thêm người hâm mộ addFan(fan) { this.fans.push(fan); } // Xóa người hâm mộ removeFan(fan) { this.fans = this.fans.filter(f => f !== fan); } // Cập nhật kết quả trận đấu updateMatchResult(match) { const index = this.matches.findIndex(m => m.id === match.id); if (index !== -1) { this.matches[index] = match; this.notifyFans(); } else { this.matches.push(match); this.notifyFans(); } } // Thông báo cho tất cả người hâm mộ notifyFans() { this.fans.forEach(fan => fan.update(this.matches)); } }
Fan (Observer)
class Fan { constructor(name) { this.name = name; } // Phương thức cập nhật update(matches) { console.log(`${this.name} nhận được cập nhật kết quả trận đấu:`); matches.forEach(match => console.log(`${match.team1} vs ${match.team2}: ${match.score}`)); } }
Sử dụng
const sportsEvent = new SportsEvent(); const fan1 = new Fan("Người hâm mộ 1"); const fan2 = new Fan("Người hâm mộ 2"); sportsEvent.addFan(fan1); sportsEvent.addFan(fan2); sportsEvent.updateMatchResult({ id: 1, team1: "Đội A", team2: "Đội B", score: "2-1" }); sportsEvent.updateMatchResult({ id: 2, team1: "Đội C", team2: "Đội D", score: "0-0" });
Hệ thống quản lý tin tức thông báo cho tất cả các ứng dụng khách.
NewsAgency (Subject)
class NewsAgency { constructor() { this.news = []; this.clients = []; } // Thêm ứng dụng khách addClient(client) { this.clients.push(client); } // Xóa ứng dụng khách removeClient(client) { this.clients = this.clients.filter(c => c !== client); } // Thêm tin tức addNews(newsItem) { this.news.push(newsItem); this.notifyClients(); } // Thông báo cho tất cả ứng dụng khách notifyClients() { this.clients.forEach(client => client.update(this.news)); } }
Client (Observer)
class Client { constructor(name) { this.name = name; } // Phương thức cập nhật update(news) { console.log(`${this.name} nhận được tin tức mới:`); news.forEach(newsItem => console.log(newsItem)); } }
Sử dụng
const newsAgency = new NewsAgency(); const client1 = new Client("Ứng dụng khách 1"); const client2 = new Client("Ứng dụng khách 2"); newsAgency.addClient(client1); newsAgency.addClient(client2); newsAgency.addNews("Tin tức 1: Sự kiện quan trọng đã xảy ra"); newsAgency.addNews("Tin tức 2: Một sự kiện khác vừa được công bố");
Đây là tất cả những ví dụ áp dụng Observer Pattern các bạn hãy xem và tham khảo
Còn nhiều trường hợp khác sẽ tổng hợp sau tại đây.
Đây
#Mtips5s #Contact
Fanpage: https://www.facebook.com/mtipscoder
Group trao đổi, chia sẻ: https://www.facebook.com/groups/mtipscoder
Website: https://mtips5s.com
Youtube: https://mtips5s.com
Twitter(X): @takagiks99
Instagram: @khuongkara
Threads: @khuongkara
Google Maps: @khuongkara
Chúc các bạn thành công!
Leave A Comment