Разрывается иерархия классов - PullRequest
0 голосов
/ 05 марта 2020

Я пытаюсь найти решение для своих иерархий классов, которое, как мне кажется, взорвется. Скажите, что у меня есть такой интерфейс событий

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, и мои иерархии классов взорвутся. есть ли решение для этого дизайна? и использование декоратора может решить эту проблему?

1 Ответ

1 голос
/ 06 марта 2020

Хорошо, значит, вы думаете больше о разделении классов на основе атрибутов, а не их функциональности. Это очень часто можно увидеть вокруг oop, но я думаю, что это неправильно.

То, что я думаю, вы должны сделать, это угробить интерфейс, полный геттеров, и создать его только одним методом. Подумайте, для чего вам нужен объект события? может отправить его по проводам? тогда метод send (). Может быть, другой парень отвечает за его отправку? тогда вам может потребоваться распечатать содержимое события в потоке, чтобы метод был похож на print (OutputStream out).

Поскольку вы упомянули, что событие может быть любой комбинацией этих трех, я бы сказал, что вам нужно пересмотреть необходимость в трех отдельных классах. Кажется, вам нужен только один, который принимает различные свойства, как на карте или что-то еще Если вам действительно нужно разделить их, потому что каждый из них имеет разные функциональные возможности, но в какой-то момент вам необходимо объединить информацию обо всех них, то я бы предложил шаблон принтера, объясненный здесь: https://www.yegor256.com/2016/04/05/printers-instead-of-getters.html Каждая реализация события будет есть метод print, который записывает их собственный контент в определяемый вами класс построителя. Затем вы используете тот класс строителей, который вам нужен.

Также есть сообщение от Sandi Metz, касающееся упомянутой вами проблемы иерархии классов. https://youtu.be/OMPfEXIlTVE Настоятельно рекомендуется.

Надеюсь, это поможет!

...