✅针对天气预报变化时触发用户通知和推荐行程用什么设计模式?
当天气不同时,用户会收到不同的通知,通知中包括具体的天气和推荐的行程。
典型回答
这里有两个点,一个是天气不同的时候发通知,还有一个就是不同的天气发送的内容不一样。
天气变化是典型的事件驱动场景,需通知多个订阅方(如通知服务、推荐服务),观察者模式天然支持一对多依赖关系,实现低耦合的事件响应机制。
不同天气对应不同的行程推荐策略(如晴天推荐户外活动、雨天推荐室内活动),策略模式通过封装可互换的业务逻辑实现逻辑灵活切换。
那么其实就是需要结合 观察者模式 和 策略模式两种设计模式。
观察者模式
- Subject(被观察者):天气服务(
<font style="color:rgb(64, 64, 64);">WeatherService</font>),负责监测天气变化,并管理观察者列表。 - Observer(观察者):定义通知接口(如
<font style="color:rgb(64, 64, 64);">sendNotification</font>),由具体观察者实现。<font style="color:rgb(64, 64, 64);">NotificationService</font>:向用户发送天气变化的通知。<font style="color:rgb(64, 64, 64);">RecommendationService</font>:生成并推送推荐行程。
+-------------------+ +-------------------+
| WeatherService |<>------->| WeatherObserver |
+-------------------+ +-------------------+
| - observers: List | | + update(Weather) |
| + register() | +-------------------+
| + unregister() | ʌ
| + notify() | +-----------+-----------+
+-------------------+ | |
v v
+---------------------+ +---------------------+
| NotificationService | | RecommendationService |
+---------------------+ +---------------------+
| + update(Weather) | | - strategy: Strategy |
+---------------------+ | + update(Weather) |
| + setStrategy() |
+---------------------+- 用户和行程服务订阅天气服务(注册为观察者)。
- 天气变化时,
<font style="color:rgb(64, 64, 64);">WeatherService</font>调用<font style="color:rgb(64, 64, 64);">notify()</font>,遍历所有观察者。 - 每个观察者(如
<font style="color:rgb(64, 64, 64);">NotificationService</font>和<font style="color:rgb(64, 64, 64);">RecommendationService</font>)执行各自的更新逻辑。
策略模式
- **<font style="color:rgb(64, 64, 64);">策略接口</font>**<font style="color:rgb(64, 64, 64);">:</font>`<font style="color:rgb(64, 64, 64);">Strategy</font>`<font style="color:rgb(64, 64, 64);">,定义生成推荐的方法(如 </font>`<font style="color:rgb(64, 64, 64);">generateRec()</font>`<font style="color:rgb(64, 64, 64);">)。</font>
- **<font style="color:rgb(64, 64, 64);">具体策略</font>**<font style="color:rgb(64, 64, 64);">:针对不同天气实现推荐逻辑,如 </font>`<font style="color:rgb(64, 64, 64);">SunnyDayStrategy</font>`<font style="color:rgb(64, 64, 64);">、</font>`<font style="color:rgb(64, 64, 64);">RainyDayStrategy</font>`<font style="color:rgb(64, 64, 64);">。</font>
+-------------------+ +-------------------+
| WeatherService |<>------->| WeatherObserver |
+-------------------+ +-------------------+
| - observers: List | | + update(Weather) |
| + register() | +-------------------+
| + unregister() | ʌ
| + notify() | +-----------+-----------+
+-------------------+ | |
v v
+---------------------+ +---------------------+
| NotificationService | | RecommendationService |
+---------------------+ +---------------------+
| + update(Weather) | | - strategy: Strategy |
+---------------------+ | + update(Weather) |
| + setStrategy() |
+---------------------+
ʌ
|
+--------+--------+
| Strategy |
+-----------------+
| + generateRec() |
+-----------------+
ʌ
+---------------+---------------+
| |
v v
+---------------------+ +---------------------+
| SunnyDayStrategy | | RainyDayStrategy |
+---------------------+ +---------------------+
| + generateRec() | | + generateRec() |
+---------------------+ +---------------------+// 推荐服务 + 策略模式
class RecommendationService implements WeatherObserver {
private RecommendationStrategy strategy;
public void setStrategy(RecommendationStrategy strategy) {
this.strategy = strategy;
}
@Override
public void update(WeatherData data) {
// 根据天气类型切换策略
switch(data.getType()) {
case SUNNY: setStrategy(new SunnyStrategy()); break;
case RAINY: setStrategy(new RainyStrategy()); break;
}
String rec = strategy.generateRecommendation(data);
sendRecommendation(rec);
}
}
// 策略接口与实现
interface RecommendationStrategy {
String generateRecommendation(WeatherData data);
}
class SunnyStrategy implements RecommendationStrategy {
@Override
public String generateRecommendation(WeatherData data) {
return "今日晴,推荐去公园野餐,紫外线指数:" + data.getUVIndex();
}
}