Optionale Funktionen: Standardmethode oder separate Schnittstelle

8

Spezielle Schnittstellen scheinen eine gute Möglichkeit zu sein, die optionalen Funktionen in einer domänenspezifischen Typhierarchie bereitzustellen. Sie behindern jedoch die Verwendung von Dekorations- und Verbundmustern, was auch in dieser Art von Hierarchie üblich ist.

Insbesondere möchte wahrscheinlich niemand einen Dekorator / Verbund für jede mögliche Kombination dieser Schnittstellen implementieren. Daher implementieren sie häufig alle optionalen Schnittstellen und verwenden die Typprüfung, um die Anrufe selektiv weiterzuleiten, was den Zweck der getrennten Schnittstellen zunichte macht.

Eine Alternative, die das Java Collection-Framework verwendet, besteht darin, alle Operationen in den Basistyp aufzunehmen und sie einfach mit Dummy-Implementierungen zu füllen. Standardmethoden in Java 8 erleichtern diese Verwendung weiter.

In gewisser Weise fühlt sich dies wie die Debatte um nullbare Spalten in der Datenbankwelt an. Gibt es ein starkes Argument gegen den praktischeren letzteren Ansatz?

billc.cn
quelle
Sind Sie auf Java oder die JVM beschränkt? Weil Scala dies ordentlich gelöst hat
Frank
@Frank Ich würde davon träumen, Scala oder eine andere Sprache mit Merkmalen verwenden zu können, aber leider ist die Verwendung von Java 8 bereits ein großer Sprung für mein Unternehmen ...
billc.cn

Antworten:

2

Eine Lösung für dieses Problem, das ich in der Vergangenheit verwendet habe (wo eine große Anzahl von Dekorateuren einer relativ einfachen Basis mit vielen möglichen Schnittstellen Funktionen hinzufügt), besteht darin, eine Basisklasse sowohl für die Dekorateure als auch für die Klassen zu haben, die sie umschließen, unabhängig davon Schnittstelle, die sie implementieren, für die eine Methode deklariert ist (unter Verwendung der Java-Syntax):

    public <T> T findImplementation (Class<T> cls) {
       if (cls.isAssignableFrom(getClass())
           return cls.cast(this);
      return wrapped.findImplementation (cls);
   }

Offensichtlich geben Nicht-Dekorator-Implementierungen null zurück, anstatt die Anforderung weiterzuleiten, da es in diesem Fall keine Möglichkeit gibt, sie weiterzugeben.

Jules
quelle
Sehr interessante Lösung. (Ich getWrappedInstance()habe meiner
Typhierarchie
1

Die Herausforderung bei der Alternative besteht darin, dass das Hinzufügen / Ändern / Entfernen optionaler Funktionen schwieriger wird. Wenn wir beispielsweise ein neues optionales Feature hinzufügen, müssen wir jetzt die Basisklasse und dann alle Unterklassen ändern, um das Feature oder das Nicht-Feature hinzuzufügen. Dies kann etwas gemildert werden, wenn es einen vernünftigen Standard gibt, z. B. ein No-Op, sodass nur die Untertypen, die die Funktion unterstützen, die erforderlichen Teile überschreiben müssen. Wenn diese optionalen Funktionen nur wenige, relativ stabil sind und sich wahrscheinlich nicht ändern, kann es ausreichend sein, sie nur dem Supertyp hinzuzufügen. Wenn nicht, kann die Wartung unhandlich werden.

Das gebräuchlichste Entwurfsmuster zum Wiederherstellen des Typs vom Supertyp ist das Besuchermuster . Dies kann in Ihrer Situation schwierig sein, da ein einzelnes Objekt möglicherweise mehrere Schnittstellen implementiert, dies kann jedoch mit einigen Änderungen möglich sein.

cbojar
quelle