2016-05-12 5 views
2

Ich kam gerade zu einem Problem mit dem Entwerfen einer Schnittstelle, deren Methoden variable Anzahl von Eingabeargumenten haben können.Entwerfen einer Java-Schnittstelle: eine Methode mit variabler Anzahl von Parametern

Das Problem ist, für die Klassen, die diese Schnittstelle implementieren, erfordern sie unterschiedliche Anzahl von Eingabeargumenten.

public class FoobarA implements FoobarSerialization<FoobarA> { 
    @Override 
    public Foobar serialize(FoobarA obj, int bar) { 
     //... 
    } 
} 


public class FoobarB implements FoobarSerialization<FoobarB> { 
    @Override 
    public Foobar serialize(FoobarB obj, Date date, String str) { 
     //... 
    } 
} 

Gibt es ein gutes Design oder einen echten Weg, um dieses Problem zu lösen? Ich weiß, dass die Methode in der Schnittstelle kann als deklariert werden:

Foobar serialize(T... obj); 

Aber ich bin nicht sicher, ob dies eine gute Praxis war eine Schnittstelle so zu entwerfen.

Irgendwelche Gedanken?

Update: Meine Absicht, eine Schnittstelle zu verwenden, kam aus der Sammlung von Klassen, die für verschiedene Zwecke serialisiert und deserialisiert werden müssen. Sie dienen als Komponenten unter derselben Domäne. Aber ihre Serialisierungsmethoden sind ziemlich unterschiedlich, insbesondere in Anbetracht ihrer Abhängigkeiten von Objekten und Diensten, die keine gemeinsamen Merkmale oder Klassen teilen.

Ich denke, die richtige Frage hier zu stellen ist: Was ist der beste Ansatz, wenn es eine Reihe von Klassen gibt, die die gleichen Verhaltensweisen teilen (Serialisierung, Deserialisierung, DoSomething usw.), aber unterschiedliche Eingabeargumente haben?

+1

Dies ist nicht die Art von Dingen, die Sie eine Schnittstelle für haben sollten. Der Vorteil einer Schnittstelle besteht darin, dass Sie, wenn Sie eine Instanz der Schnittstelle haben, diese immer mit den gleichen Argumenten aufrufen können, und das ist hier nicht der Fall. –

+0

@LouisWasserman Einverstanden. Es scheint keine gute Idee zu sein, in solchen Fällen eine Schnittstelle zu verwenden. Was ist das Beste, was du hier benutzen kannst? –

+0

Die beste Sache zu verwenden ist nichts. Schreiben Sie einfach die Methoden direkt; Versuche keine verführerische Erbmagie. –

Antwort

0

Ihre Laufleistung kann variieren, aber normalerweise verwirrend verwenden (z. B. die gleiche Anzahl, aber verschiedene Arten von Argumenten) von Methoden mit dem gleichen Namen sollte vermieden werden. Obwohl man sich der Methodenüberladung bedienen kann, wird es als weniger wünschenswert betrachtet. Wenn die Liste der Parameter verwaltbar ist, sollten Sie die Methode anders benennen, um Mehrdeutigkeiten zu vermeiden. Siehe Item 26 in Effective Java 2.

Die Vararg Methoden sind in Ordnung, aber in Java, die beste Praxis ist zumindest ein konkretes Argument durch eine variable Anzahl von Argumentendes gleichen Typs gefolgt angeben. Dies ist möglicherweise in Ihrem Fall nicht anwendbar, da es für eine Methode wie public Foobar serialize(FoobarB obj, Date date, String str); keine Vararg-Syntax gibt. Es könnte akzeptabel sein, eine Syntax wie (Object ... objects) zu verwenden, aber diese Praxis ist nicht als allgemein anwendbar. Vergleichen Sie dies mit einer Methode wie printf, die in der Lage ist, eine variable Anzahl von Argumenten jeden Typs (einschließlich Primitiven) an einen Ausgabestrom auszugeben.

5

Zusammensetzung Muster zur Rettung.

In Ihrem speziellen Fall I-Schnittstelle, die nur 1 Parameter akzeptiert schaffen würde:

public interface Serializer<T> { 

    Foobar serialize(T object); 

} 

Nun, wenn Sie mehrere Felder benötigen, serialisiert, Sie ein Objekt nur erstellen, die alle Felder, die Sie serialisieren müssen hat:

class FoobarBundle { 

    String stringField; 
    int intField; 
    byte[] arrayField; 

    /* ... */ 

} 

und schreiben Haufen Serializer: FoobarBundleSerializer, StringSerializer, IntegerSerializer, ByteArraySerializer.Am Ende kombinieren Sie alle Serializer in FoobarBundleSerializer wie folgt: