ЛОР, а как ты предпочитаешь реализовывать подобного рода конструкции?
Казалось бы doSpecificComplexTask() нужно сделать методом Link и переопределить его в каждом наследнике, но что если в этом методе может быть довольно нетривиальной код, который хочется держать отдельно от данных (например, работа с сетью, базой, etc...). Т.е. хочется, чтобы класс Link был скорее структурой?
Visitor - очень громоздко, instanceof - в Java говорят плохой стиль. Хотя если разобраться, то чем Pattern Matching из Scala не instanceof?
Да, это ООП головного мозга.
Java:
public interface Entity {
String getId();
String getMessaage();
Link getLink();
}
public interface Link {
void accept(Visitor visitor);
static interface Visitor {
visit(UrlLink link);
visit(SomethingElseLink link);
visit(EvenMoreLink link);
}
static abstract class UrlLink() implements Link {
void accept(Visitor visitor) { visitor.accept(this); }
URL getURL();
}
static abstract class SomethingElseLink() implements Link {
void accept(Visitor visitor) { visitor.accept(this); }
SomethingElse getSomethingElse();
AndSomethingElse getAndSomethingElse();
}
static abstract class EvenMoreLink() implements Link {
void accept(Visitor visitor) { visitor.accept(this); }
EvenMore getEvenMore();
}
}
// Variant 1
class SpecificVisitor implements Link.Visitor { ... }
SpecificVisitor visitor = new SpecificVisitor();
entity.getLink().accept(visitor);
// Variant 2
Link link = entity.getLink();
if (link instanceof UrlLink) { doSpecificComplexTask(...); }
if (link instanceof SomethingElseLink) { doSpecificComplexTask(...); }
if (link instanceof EvenMoreLink) { doSpecificComplexTask(...); }
Scala:
class Entity(id: String, message: String, link: Link)
trait Link
case class UrlLink(url: URL)
case class SomethingElseLink(se: SomethingElse, ase: AndSomethingElse)
case class EvenMoreLink(em: EvenMore)
entity match {
case UrlLink(url) => doSpecificComplexTask(url)
case SomethingElseLink(se, ase) => doSpecificComplexTask(se, ase)
case EvenMoreLink(em) => doSpecificComplexTask(em)
}