我正在尝试为我的类层次结构找到解决方案,我认为它会爆炸 假设我有一个这样的事件接口
public interface Event {
String getId();
String getType();
String getName();
String getDescription();
Date getDate();
JsonElement getRaw();
}
public class BasicEvent implements Event {
protected String eventId;
protected String eventType;
protected String eventDescription;
protected String eventName;
protected Date time;
protected JsonElement raw;
public BasicEvent(String eventId, String eventType, String eventDescription, String eventName, Date time,
JsonElement raw) {
this.eventId = eventId;
this.eventType = eventType;
this.eventDescription = eventDescription;
this.eventName = eventName;
this.time = time;
this.raw = raw;
}
public BasicEvent(String eventId, String eventType, Date time, JsonElement raw) {
this(eventId, eventType, null, eventId, time, raw);
}
public BasicEvent(String eventId, String eventType, Date time, String eventName, String eventDescription) {
this(eventId, eventType, eventDescription, eventName, time, null);
}
@Override
public String getId() {
return this.eventId;
}
@Override
public String getType() {
return this.eventType;
}
@Override
public String getName() {
return this.eventName;
}
@Override
public String getDescription() {
return this.eventDescription;
}
@Override
public Date getDate() {
return this.time;
}
@Override
public JsonElement getRaw() {
return raw;
}
public Map<String, Object> getData() {
return new Gson().fromJson(raw, Map.class);
}
@Override
public String toString() {
return "BasicEvent{" + "eventId=" + eventId + ", eventType=" + eventType + ", time=" + time + ", raw=" + raw
+ '}';
}
}
可以从系统,设备或区域触发事件,因此使用继承,我可以添加3个类
public class ZoneEvent extends BasicEvent {
private Long zoneId;
public ZoneEvent(BasicEvent event, Long zoneId) {
super(event);
this.zoneId = zoneId;
}
public Long getZoneId() {
return zoneId;
}
public void setZoneId(Long zoneId) {
this.zoneId = zoneId;
}
}
public class DeviceEvent extends BasicEvent {
private Long deviceId;
private String driverId;
private String deviceType;
public DeviceEvent(BasicEvent event, Long id, String driverId, String deviceType) {
super(event);
this.deviceId = id;
this.deviceType = deviceType;
this.driverId = driverId;
}
public String getDriverId() {
return driverId;
}
public void setDriverId(String driverId) {
this.driverId = driverId;
}
public void setDeviceId(DeviceId id) {
this.deviceId = id;
}
public void setDeviceType(String deviceType) {
this.deviceType = deviceType;
}
public DeviceId getDeviceId() {
return deviceId;
}
public String getDeviceType() {
return deviceType;
}
}
public class SystemEvent extends BasicEvent {
private Long systemId;
public SystemEvent(BasicEvent event, Long systemId) {
super(event);
this.systemId=systemId;
}
public Long getSystemId() {
return systemId;
}
public void setSystemId(Long systemId) {
this.systemId = systemId;
}
}
现在,一个事件可以是这3个类的组合,一个事件可以包含ZoneId和deviceId或deviceId和SystemId,并且我的类层次结构将爆炸。这个设计有什么解决方案吗?并使用装饰器可以解决这个问题之王?
答案 0 :(得分:1)
好的,因此您在考虑基于属性而不是其功能来分离类方面有更多思考。这种情况在oop周围很常见,但我认为这是错误的。
我认为您应该做的是抛弃充满吸气剂的接口,仅使用一种方法创建接口。考虑一下您需要事件对象做什么?也许通过电线发送?那么该方法是send()。也许另一个人负责发送它?那么您可能需要将事件的内容打印到流中,因此该方法将类似于print(OutputStream out)。
由于您提到一个事件可以是这3个事件的任意组合,所以我想说您重新考虑需要3个单独的类。您似乎只需要一个接受不同属性(例如在Map或其他内容中)的对象。如果您真的需要将它们分开,因为它们每个都具有不同的功能,但是在某一时刻您需要将它们的信息组合在一起,那么我建议您在此处说明打印机模式: https://www.yegor256.com/2016/04/05/printers-instead-of-getters.html 每个事件实现都有一个方法打印,该方法将自己的内容写入您定义的构建器类。然后,根据需要使用该构建器类。
Sandi Metz也有一个相关的演讲,涉及您提到的类层次结构问题。 https://youtu.be/OMPfEXIlTVE强烈推荐。
希望有帮助!