Spring中使用设计模式(二、观察者模式)

通过观察者模式重构受损的智慧农业控制系统,确保添加新设备时不影响原有功能。采用Spring框架实现事件发布与监听机制,遵循开闭原则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring中使用设计模式(二、观察者模式)

观察者模式是行为类模式的一种,可以解耦发布和订阅。本文结合前几天阿里的今年83行代码重构大师赛题目说明。

观察者模式

题目:生存舱有一个智慧农业的控制系统,该系统能根据温度、湿度、风力的变化来控制各种设备。为了让因灾害而失去家园的人们尽早地有能力自给自足,我们需要给这个系统添加新的设备。但是现在系统已经受损,无法在添加新设备时保证不影响原有功能。

这个任务就交给你啦 你的任务:用观察者模式重构系统的代码,使添加新设备时不用担心影响原有功能(符合开闭原则)。

public class WeatherData {
    private SeedingMachine seedingMachine;
    private ReapingMachine reapingMachine;
    private WateringMachine wateringMachine;
    public WeatherData(SeedingMachine seedingMachine, ReapingMachine reapingMachine, WateringMachine wateringMachine){
        this.seedingMachine = seedingMachine;
        this.reapingMachine = reapingMachine;
        this.wateringMachine = wateringMachine;
    }

    public void measurementsChanged(int temp, int humidity, int windPower)
    {
        if (temp > 5)        {            
            seedingMachine.start();
            if (humidity > 65)
                reapingMachine.start();
        }
        if (temp > 10 && humidity < 55 && windPower < 4)
            wateringMachine.start();
    }
}

数据的变动与智慧农业的控制系统的监控处理是两件事,最好不要写在一起,用事件触发即可。

代码没有单测覆盖,先补单测,测试代码,具体如下:

	
@RunWith(SpringRunner.class)
@SpringBootTest
class SpringPattenTest {

    @Autowired
    SeedingMachine seedingMachine;
    @Autowired
    WeatherData weatherData;
    @Test
    void should_get_seedingMachine_started_when_temp_Over_5() {
        boolean isOpen = seedingMachine.getStatus();
        assertEquals(false,isOpen);
        weatherData.measurementsChanged(6,0,0);
        isOpen = seedingMachine.getStatus();
        assertEquals(true,isOpen);
    }
}

重思路,weatherData变化作为事件,只需要让上下文发布者通知各监听器即可。环境变化为事件类:

@Component
public class WeatherData extends ApplicationEvent {
    private int temp =0;
    private int humidity=0;
    private int windPower=0;

    public WeatherData(ApplicationContext source) {
        super(source);
    }

    @Autowired
    MyPublisher myPublisher;
    public void measurementsChanged(int temp, int humidity, int windPower) {
        this.temp = temp;
        this.humidity = humidity;
        this.windPower = windPower;
        myPublisher.publisherEvent(this);
    }
    public int getTemp() {
        return temp;
    }
}

上下文发布者发布事件。

@Component
public class MyPublisher implements ApplicationContextAware{
    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
    public void publisherEvent(WeatherData myEvent) {
        System.out.println("---开始发布 myEvent 事件---");
        applicationContext.publishEvent(myEvent);
    }
}

监听者可以有多个,每个实现具体的触发条件就好。

@Component
public class SeedingMachine implements ApplicationListener<WeatherData> {
    private boolean isOpen;
    public boolean getStatus() {
        return isOpen;
    }
    @Override
    public void onApplicationEvent(WeatherData weatherData) {
        if (weatherData.getTemp() > 5) {
            this.isOpen= true;
        }
    }
}

后续智慧农业的控制系统有多种不同逻辑的机器,只增加机器类即可。后续,不同逻辑的机器类可以抽出同一个接口,方便管理。

jdk也提供观察者模式,但已经使用了Spring,这种方式的观察者模式用起来也挺方便。

在实际项目中,servletListener对请求进行拦截、主题订阅等可以用本模式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值