[英]Registering listeners according to SOLID pricipals
I'm practicing oop
concepts these days.这些天我正在练习
oop
概念。 To figure it out I tried the below problem.为了弄清楚,我尝试了以下问题。
There is a sensor monitoring system.有传感器监控系统。 It is a simple system that prints a value, whenever a sensor has picked a value.
这是一个简单的系统,只要传感器选择了一个值,它就会打印一个值。
I tried to solve this problem according to oop
and SOLID
principals.我试图根据
oop
和SOLID
原则解决这个问题。
So I created an interface SensorListener
所以我创建了一个接口
SensorListener
interface SensorListener{
public void onValueUpdated(SensorTypes type, double value);
}
Then I created a Sensor
class然后我创建了一个
Sensor
class
public class Sensor {
private int value;
private SensorTypes types;
private SensorListener sensorListener;
public Sensor(SensorTypes types) {
this.types = types;
}
public void setValue(int value) {
this.value = value;
sensorListener.onValueUpdated(types, value);
}
public void registerListener(SensorListener sensorListener) {
this.sensorListener = sensorListener;
}
}
For sensor types the enum
is as below对于传感器类型,
enum
如下
public enum SensorTypes {
TEMPERATURE, PH, HUMIDITY;
}
For the monitoring purpose I created a class SensorMonitor
that implements SensorListener`出于监控目的,我创建了一个实现
SensorMonitor
的 class SensorMonitor`
public class SensorMonitor implements SensorListener {
@Override
public void onValueUpdated(SensorTypes type, double value) {
System.out.println("Sensor Name: " + type + ", Measure: " + value);
}
}
Finally in the main method I mocked the sensor updated using a Thread
,最后在 main 方法中,我模拟了使用
Thread
更新的传感器,
public static void main(String[] args) {
SensorMonitor sensorMonitor = new SensorMonitor();
Sensor temperature = new Sensor(SensorTypes.TEMPERATURE);
temperature.registerListener(sensorMonitor);
Sensor humidity = new Sensor(SensorTypes.HUMIDITY);
humidity.registerListener(sensorMonitor);
Sensor pH = new Sensor(SensorTypes.PH);
pH.registerListener(sensorMonitor);
Thread thread = new Thread(() -> {
int i = 0;
while (true) {
try {
temperature.setValue(i++);
Thread.sleep(3000);
humidity.setValue(i++);
Thread.sleep(3000);
pH.setValue(i++);
Thread.sleep(3000);
} catch (InterruptedException e) {
System.out.println("thread interrupted");
}
}
});
thread.start();
}
In this way program successfully works and prints the output in 3 second intervals.通过这种方式,程序成功运行并以 3 秒的间隔打印 output。
Sensor Name: TEMPERATURE, Measure: 0.0
传感器名称:温度,测量:0.0
Sensor Name: HUMIDITY, Measure: 1.0
传感器名称:湿度,测量:1.0
Sensor Name: PH, Measure: 2.0
传感器名称:PH,测量:2.0
I'm satisfied with the behavior because it does what it says.我对这种行为感到满意,因为它按照它所说的去做。 But I'm not sure whether this a correct
oop
way of implementing interfaces
and whether up to which context is this application scalable.但我不确定这是否是一种正确的
oop
实现interfaces
的方式,以及该应用程序是否可扩展至哪个上下文。
For example as the SensorMonitor
how can it know the details of currently operating sensors, and what sensors are in the monitoring process?比如作为
SensorMonitor
,它如何知道当前运行的传感器的详细信息,以及监控过程中有哪些传感器?
Can someone point out what are the pros and cons in my approach.有人可以指出我的方法的优缺点。
Is this conforms to SOLID principals?这符合 SOLID 原则吗?
I appreciate a more concise approach for this problem.我很欣赏这个问题的更简洁的方法。
There's no way to tell whether a design is good or bad if there's no specific requirements.如果没有具体要求,就无法判断一个设计是好是坏。 If you just wanted to be able to listen to new sensor values then your current design works.
如果您只是想能够听到新的传感器值,那么您当前的设计就可以了。
One thing that's certainly flawed is that registerListener
overrides the previous listener (if any) so that could have unexpected results from the client perspective: setListener
would probably have made it more clear that's the expected behavior or throw an exception if registerListener
is called more than once if it doesn't support more than one registration.肯定有缺陷的一件事是
registerListener
覆盖了以前的侦听器(如果有的话),因此从客户端的角度来看可能会产生意想不到的结果: setListener
可能会更清楚地说明这是预期的行为,或者如果多次调用registerListener
则抛出异常如果它不支持多个注册。
For example as the SensorMonitor how can it know the details of currently operating sensors, and what sensors are in the monitoring process?
比如作为 SensorMonitor,它如何知道当前运行的传感器的详细信息,以及监控过程中有哪些传感器?
Well obviously your design fails at solving this problem since the SensorMonitor
isn't modeled as such and acts more simply as an independent "listener".很明显,您的设计未能解决这个问题,因为
SensorMonitor
没有像这样建模,而是更简单地充当独立的“侦听器”。 You'd simply have to adapt your SensorMonitor
concept for the new requirements.您只需根据新要求调整您的
SensorMonitor
概念即可。
public class SensorMonitor implements SensorListener {
private final Set<Sensor> sensors;
public SensorMonitor() {
sensors = new HashSet<>();
}
public void startMonitoring(Sensor sensor) {
sensors.add(sensor);
// Note that Current `registerListener` implementation could break the monitor
// since you could override the monitor's listener.
sensor.registerListener(this);
}
public Set<Sensor> monitoredSensors() {
return Collections.unmodifiableSet(sensors);
}
@Override
public void onValueUpdated(SensorTypes type, double value) {
System.out.println("Sensor Name: " + type + ", Measure: " + value);
}
}
Now you could make the monitor more flexible by allowing to instantiate it with a SensorListener
and you could implement a CompositeSensorListener
to merge multiple listeners together, etc.现在,您可以通过允许使用
SensorListener
对其进行实例化来使监视器更加灵活,并且您可以实现CompositeSensorListener
以将多个侦听器合并在一起,等等。
Like I said there's no good nor bad design when there's no specific problem to solve .就像我说的,当没有具体问题需要解决时,没有好坏的设计。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.