Я прохожу дюжину учебных пособий, которые мне очень мало помогают, потому что производственный код не является животным, птицей или человеком. Не оружие типа стрельбы или стрельбы, о котором гораздо сложнее рассуждать.
Итак, возвращаясь к реальности, сценарий:
service 1 обменивается сообщениями с service 2 через Kafka, сообщения сериализуются / десериализуются с помощью Jackson, класс модели распределяется между службами как jar.
Теперь часть чумы, кульминация зла:
@JsonTypeInfo(
use = Id.NAME,
property = "type",
visible = true
)
@JsonSubTypes({@Type(
value = InternalTextContent.class,
name = "text"
), @Type(
value = InternalImageContent.class,
name = "image"
), @Type(
value = InternalAudioContent.class,
name = "audio"
), @Type(
value = InternalCustomContent.class,
name = "custom"
)})
public abstract class InternalContent {
@JsonIgnore
private ContentType type;
public InternalContent() {
}
Очевидно, что когда придет время работать с этим контентом, у нас будет что-то вроде:
message.getInternalContent
, что приводит к множеству switch
операторов, if
условий, instanceof
и ожиданию этого ... удручающее повсюду
И это только один пример свойств, который содержит оберточный объект. Ясно, что я не могу добавить полиморфное поведение к InternalContent, потому что привет, он внутри jar.
Что здесь пошло не так? Это даже неправильно?
Как добавить полиморфное поведение? Чтобы добавить новый смягчающий слой, мне все еще нужно instanceof
на некоторой фабрике, чтобы создать новый тип семейства полиморфных объектов, которые можно редактировать, чтобы добавить желаемое поведение? Даже не уверен, что это будет лучше, это просто пахнет и заставляет меня хотеть стрелять в адвокатов, которые бросают слепое заявление, как instanceof
с унижением - это кодовый запах, "мучающий таких людей, как я, которые искренне заботятся, что заставляет меня задуматься, если они когда-либо работал над реальным проектом. Я намеренно добавил детали системной среды, чтобы понять, как моделировать не только код, но и взаимодействие между системами. Каковы возможные варианты редизайна для достижения решения «по книге»?
Пока что я могу думать о том, что модель совместного использования домена является грехом. Но затем, если я использую разные классы самообслуживания для представления одних и тех же вещей для сериализации / десериализации, я собираю гибкость, но теряю контракт и увеличиваю непредсказуемость. Что технически происходит с HTTP-контрактами.
Должен ли я отправлять разные типы сообщений с разными структурами по проводам вместо попыток совмещать общие части и подтипы для необычных в одном типе сообщения?
Чтобы бросить больше песка в ОО, Pivotal я считаю лучшим среди лучших:
https://github.com/spring-projects/spring-security/blob/master/core/src/main/java/org/springframework/security/authentication/dao/AbstractUserDetailsAuthenticationProvider.java
public boolean supports(Class<?> authentication) {
return (UsernamePasswordAuthenticationToken.class
.isAssignableFrom(authentication));
}
AuhenticationManager имеет список AuthenticationProviders, подобный этому, и выбирает правильный на основе описанного выше метода. Это нарушает полиморфизм? Иногда все это выглядит как шумиха ...