【问题标题】:Class hierarchies exploding类层次结构爆炸式增长
【发布时间】:2020-06-17 19:05:39
【问题描述】:

我正在尝试为我的类层次结构找到一个解决方案,我认为它会爆炸 假设我有一个这样的事件接口

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,我的类层次结构将爆炸。这个设计有什么解决方案吗?使用装饰器可以解决这个问题吗?

【问题讨论】:

    标签: java inheritance design-patterns decorator


    【解决方案1】:

    好的,所以您更多地考虑基于属性而不是它们的功能来分离类。这在 oop 周围很常见,但我认为这是错误的。

    我认为你应该做的是抛弃充满 getter 的接口,只用一种方法创建一个。想想你需要事件对象做什么?也许通过电线发送?那么方法是send()。也许另一个人负责发送它?那么您可能需要将事件的内容打印到流中,因此该方法类似于 print(OutputStream out)。

    既然您提到事件可以是这 3 个的任意组合,我想说您重新考虑需要 3 个单独的类。您似乎只需要一个接受不同属性的人,例如地图或其他东西。如果您确实需要将它们分开,因为每个都有不同的功能,但在某一时刻您需要将它们的信息结合起来,那么我建议您使用此处解释的打印机模式: https://www.yegor256.com/2016/04/05/printers-instead-of-getters.html 每个事件实现都会有一个方法 print 将他们自己的内容写入您定义的构建器类。然后根据需要使用该构建器类。

    还有来自 Sandi Metz 的相关演讲,涉及您提到的类层次结构问题。 https://youtu.be/OMPfEXIlTVE 强烈推荐。

    希望对你有帮助!

    【讨论】:

    • 从行为上思考听起来不错。这些事件是从许多不同的外部系统收集的。我做了一些分解,我意识到来自这些系统的事件有一些共性,我在 Event 接口和 BasicEvent 类中推送了这些共性,但有些事件仅在某些属性上有所不同,而其他事件是其他属性的组合。我需要将事件保存为 json ,所以打印模式很有帮助,我在服务中而不是在 Event 类中执行此操作,我想触发事件,我为此创建了侦听器。
    猜你喜欢
    • 2020-06-19
    • 1970-01-01
    • 2018-08-07
    • 2017-12-10
    • 2017-09-27
    • 2020-11-23
    • 1970-01-01
    • 2018-04-27
    • 2020-07-30
    相关资源
    最近更新 更多