设计模式中,观察者模式(Observer)/发布-订阅模式(Publish-Subscribe)的原理和Java代码示例讲解。
观察者模式 - 同步与异步实现示例
一、通俗解释观察者模式
场景比喻
- 想象你订阅了某个电商 APP 的“降价提醒”功能:
- 当商品降价时,你会收到推送消息。
- 你朋友也订阅了这个商品,他也会收到消息。
- 如果有很多人都订阅了,商场并不知道你们是谁,它只会“群发通知”。
这就是 观察者模式:
- 被观察者(Subject / Observable):比如商场 Store,负责发布通知。
- 观察者(Observer):比如顾客 Customer、管理员 Admin,负责接收通知。
- 依赖关系:当被观察者发生变化时,它会通知所有观察者。
特点:
- 解耦:商场不关心有多少观察者,也不关心他们的身份。
- 扩展性强:你想加一个“工商局管理员”观察者,直接注册即可,不需要改动商场逻辑。
- 灵活:可以同步通知,也可以异步通知(提高性能)。
二、异步实现代码
import java.util.*;
import java.util.concurrent.*;
// Product类:商品
class Product {
private String name;
private double price;
public Product(String name, double price) {
this.name = name;
this.price = price;
}
public String getName() { return name; }
public double getPrice() { return price; }
public void setPrice(double price) { this.price = price; }
@Override
public String toString() {
return String.format("Product{name='%s', price=%.2f}", name, price);
}
}
// 观察者接口
interface ProductObserver {
void onPublished(Product product);
void onPriceChanged(Product product);
}
// Admin:管理员
class Admin implements ProductObserver {
public void onPublished(Product product) {
System.out.println("[Admin] New product published: " + product);
}
public void onPriceChanged(Product product) {
System.out.println("[Admin] Price changed: " + product);
}
}
// Customer:消费者
class Customer implements ProductObserver {
public void onPublished(Product product) {
System.out.println("[Customer] Yay! New product: " + product);
}
public void onPriceChanged(Product product) {
System.out.println("[Customer] Price alert: " + product);
}
}
// 新增观察者:GovOfficial(政府监管员)
class GovOfficial implements ProductObserver {
public void onPublished(Product product) {
System.out.println("[GovOfficial] Checking compliance for new product: " + product);
}
public void onPriceChanged(Product product) {
System.out.println("[GovOfficial] Monitoring price change: " + product);
}
}
// 被观察者:Store
class Store {
private List<ProductObserver> observers = new ArrayList<>();
private Map<String, Product> products = new HashMap<>();
private ExecutorService executor = Executors.newCachedThreadPool();
public void addObserver(ProductObserver observer) {
observers.add(observer);
}
public void removeObserver(ProductObserver observer) {
observers.remove(observer);
}
public void addNewProduct(String name, double price) {
Product p = new Product(name, price);
products.put(p.getName(), p);
notifyObserversAsync(o -> o.onPublished(p));
}
public void setProductPrice(String name, double price) {
Product p = products.get(name);
if (p != null) {
p.setPrice(price);
notifyObserversAsync(o -> o.onPriceChanged(p));
}
}
private void notifyObserversAsync(java.util.function.Consumer<ProductObserver> action) {
for (ProductObserver o : observers) {
executor.submit(() -> {
try {
action.accept(o);
} catch (Exception e) {
System.err.println("Error notifying observer: " + e.getMessage());
}
});
}
}
public void shutdown() {
executor.shutdown();
}
}
// 主程序
public class ObserverDemo {
public static void main(String[] args) throws InterruptedException {
Store store = new Store();
store.addObserver(new Admin());
store.addObserver(new Customer());
store.addObserver(new GovOfficial());
store.addObserver(new ProductObserver() {
public void onPublished(Product product) {
System.out.println("[Logger] Product published log: " + product);
}
public void onPriceChanged(Product product) {
System.out.println("[Logger] Price changed log: " + product);
}
});
store.addNewProduct("iPhone 16", 9999);
store.setProductPrice("iPhone 16", 8999);
Thread.sleep(1000);
store.shutdown();
}
}
三、同步实现代码
import java.util.*;
// Product类:商品
class Product {
private String name;
private double price;
public Product(String name, double price) {
this.name = name;
this.price = price;
}
public String getName() { return name; }
public double getPrice() { return price; }
public void setPrice(double price) { this.price = price; }
@Override
public String toString() {
return String.format("Product{name='%s', price=%.2f}", name, price);
}
}
// 观察者接口
interface ProductObserver {
void onPublished(Product product);
void onPriceChanged(Product product);
}
// Admin:管理员
class Admin implements ProductObserver {
public void onPublished(Product product) {
System.out.println("[Admin] New product published: " + product);
}
public void onPriceChanged(Product product) {
System.out.println("[Admin] Price changed: " + product);
}
}
// Customer:消费者
class Customer implements ProductObserver {
public void onPublished(Product product) {
System.out.println("[Customer] Yay! New product: " + product);
}
public void onPriceChanged(Product product) {
System.out.println("[Customer] Price alert: " + product);
}
}
// GovOfficial:政府监管员
class GovOfficial implements ProductObserver {
public void onPublished(Product product) {
System.out.println("[GovOfficial] Checking compliance for new product: " + product);
}
public void onPriceChanged(Product product) {
System.out.println("[GovOfficial] Monitoring price change: " + product);
}
}
// 被观察者:Store
class Store {
private List<ProductObserver> observers = new ArrayList<>();
private Map<String, Product> products = new HashMap<>();
public void addObserver(ProductObserver observer) {
observers.add(observer);
}
public void removeObserver(ProductObserver observer) {
observers.remove(observer);
}
public void addNewProduct(String name, double price) {
Product p = new Product(name, price);
products.put(p.getName(), p);
notifyObservers(o -> o.onPublished(p));
}
public void setProductPrice(String name, double price) {
Product p = products.get(name);
if (p != null) {
p.setPrice(price);
notifyObservers(o -> o.onPriceChanged(p));
}
}
private void notifyObservers(java.util.function.Consumer<ProductObserver> action) {
for (ProductObserver o : observers) {
try {
action.accept(o);
} catch (Exception e) {
System.err.println("Error notifying observer: " + e.getMessage());
}
}
}
}
// 主程序
public class ObserverSyncDemo {
public static void main(String[] args) {
Store store = new Store();
store.addObserver(new Admin());
store.addObserver(new Customer());
store.addObserver(new GovOfficial());
store.addObserver(new ProductObserver() {
public void onPublished(Product product) {
System.out.println("[Logger] Product published log: " + product);
}
public void onPriceChanged(Product product) {
System.out.println("[Logger] Price changed log: " + product);
}
});
store.addNewProduct("iPhone 16", 9999);
store.setProductPrice("iPhone 16", 8999);
}
}

浙公网安备 33010602011771号