2012-12-19 2 views
8

Ich versuche ein Framework zu erstellen, das es Menschen ermöglicht, unsere Kernfunktionalität durch die Implementierung einer Schnittstelle zu erweitern. Unten ist ein dumbed down-Beispiel für diese Schnittstelle.Methode Parameter vs Parameter Objekt

public interface MyInterface 
{ 
    IData GetData(string p1, char p2, double p3); 
} 

Vor kurzem haben wir beschlossen, diese Schnittstelle zu ändern (Ich weiß, ich soll nicht abhängig Code brechen, aber die Wahrheit ist, dass wir diese Schnittstelle implementieren noch keine dritten Parteien haben, so haben wir eine Chance für ein "Do-Over", um diese Schnittstelle korrekt zu implementieren).

Wir müssen dieser Schnittstelle zwei weitere Parameter hinzufügen, damit unsere Software korrekt funktioniert. Zwei Möglichkeiten, wir denken von hinzufügen, sie nur auf die Signatur wie folgt aus:

public interface MyInterface 
{ 
    IData GetData(string p1, char p2, double p3, bool p4, DateTime p5); 
} 

oder durch die Schaffung eines Parameter-Objekt wie dieses

public class MyParameters 
{ 
    public bool p4 { get; set; } 
    public DateTime p5 { get; set; } 
} 

und das Hinzufügen von ihnen bis zum Ende des Verfahrens wie so :

public interface MyInterface 
{ 
    IData GetData(string p1, char p2, double p3, MyParameters p4); 
} 

ich bin für eine Art von Führung, auf dem Weg, um die „die meisten“ richtigen Weg zu gehen. Ich kann Pro und Contra in beiden Kategorien sehen, aber ich möchte nicht, dass meine Vorurteile mich auf den falschen Weg führen.

Einige meiner wichtigsten Anliegen sind:

  • Erweiterbarkeit der Software - ich möchte der Benutzer in der Lage sein zu tun, was ich noch nicht gedacht haben, durch die Schnittstelle
  • Wartbarkeit Implementierung - Idealerweise ich möchte nie den Code zu berühren haben, die für den Aufruf von GetData() erneut
  • Saubere API verantwortlich ist - ich will nicht die Lösung, die ich bei Ankunft zu einem 3rd-Party-Entwickler machen
  • erschaudern

Ich weiß nicht einmal, welche Frage ich online stellen sollte, um Anleitungen für dieses Problem zu erhalten. Ich habe das Gefühl, dass die Antwort "hängt davon ab" (auf Dinge wie wie p1-p5 zu dem Zweck der GetData() -Funktion), aber kann jemand mich auf eine Liste von Fragen zeigen, die ich bitten sollte, um mich zu bewerten ob eine Lösung besser ist als die andere?

Verwandte: Post 1 Post 2

Antwort

2

Lassen Sie mich versuchen, diese zu beantworten. Lassen Sie uns Ihre Bewertung verschiedener Optionen:

1) Wenn die unter Schnittstelle

public interface MyInterface 
{ 
    IData GetData(string p1, char p2, double p3); 
} 

gebrochen:

a) und sollte nicht verwendet werden, dann sollten Sie die Implementierer es neu zu schreiben erzwingen. Ändern Sie die Methodendefinition.

public interface MyInterface 
{ 
    IData GetData(something else); 
} 

b), aber Sie müssen nur die Benutzer ermutigen, neue Definition zu verwenden, dann können Sie eine neue Überlastung schaffen sie die erste ist obsolet zu erzählen.

public interface MyInterface 
{ 
    //xml to tell them this is deprecated. 
    IData GetData(string p1, char p2, double p3); 
    IData GetData(string p1, char p2, double p3, and whatever); 
} 

Über Ihre neue Definition gibt es keine One-Stop-Lösung, die jemand ohne zu wissen, über das Modell geben kann, aber man fragt sich,

I) "Die Parameter können sich eine Einheit darstellen, wenn kombiniert ? Bedeutet es etwas in der realen Welt, eine Einheit Ihrer Parameter zu haben? "Wenn ja, machen Sie es so. Wenn nicht, nicht. Ich denke, man sollte sich darauf verlassen, in so abstrakten Ebenen zu denken, wenn man sich in einem solchen Dilemma befindet. Ich bin mir nicht sicher, was ist der Punkt in Clubbing bool p4 und DateTime p5. Sie sollten jene Parameter vereinsamen, die selbst etwas im wirklichen Leben darstellen. Wenn keine Kombination von diesen Sinn ergibt, dann belasse es als solches. Sie werden mehr Erfolg haben, wenn Sie solch ein Clubbing so logisch denken lassen. Wohlgemerkt, Sie überlassen Ihre Definition anderen Programmierern, und um ihre Arbeit zu erleichtern, sollte Ihre Methodensignatur sehr, sehr logisch sein.

II) Kann die Klasse mehr tun, als nur Daten zu speichern? Klasse sollte hier Option sein.

III) Muss ich nur die Klassendefinition und nicht die Implementierung davon kontrollieren? In diesem Fall definieren Sie einfach eine öffentliche Schnittstelle Ihrer Eingaben und überlassen Sie die Implementierung dem Kunden.

IV) Sollten zukünftige Änderungen an meiner Schnittstelle nicht bestehende Implementierung brechen? Überladung ist Ihr Weg zu gehen.

Nehmen wir an, Sie haben zwei Möglichkeiten, lassen Sie die Unterschrift flach, oder zum Club.

1) ohne clubbing:

a) weniger Code, Reduzierung der anderen Schicht.

b) Keine Notwendigkeit, eine andere Klasse der Öffentlichkeit zugänglich zu machen.

2) Mit Clubbing:

a) Gewährt ein besseres Verständnis des Modells in die Funktion zu gehen - Ihre Absicht ist klar.

b) In Zukunft einfach skalierbar, wenn Sie optionale Details zum Konstruieren der neu gebildeten Klasse hinzufügen müssen. Können sagen, Sie eine Klasse haben

class Input { 
    string p1; char p2; double p3; 

    public Input(string p1, char p2, double p3){ 
    } 
} 

und Schnittstelle

public interface MyInterface 
{ 
    IData GetData(Input p1); 
} 

Jetzt sollten Sie optionale Details wie ein Bool und ein Datetime hinzuzufügen. Da sie optional sind, müssen Sie sie nicht im Konstruktor erzwingen. Sie können immer noch den gleichen Konstruktor haben und dem Benutzer die Berechtigung geben, diese außerhalb des Konstruktors zu ändern.

class Input { 
    string p1; char p2; double p3; bool p4; DateTime p5; 

    public Input(string p1, char p2, double p3){ 
    } 
} 

Schnittstelle kann immer noch die gleiche sein. Wie gesagt, der Anstoß, etwas von dieser Art abzuleiten, hängt leider von Ihrem Modell ab. Kurz gesagt, wenn eine Gruppierung etwas bedeuten kann, machen Sie daraus eine Klasse oder Schnittstelle (je nachdem, wer die Logik steuert).

2

Warum nicht den ganzen Weg gehen:

public Interface IParameters 
{ 
    string p1 {get; set;} 
    char p2 {get; set;} 
    double p3 {get; set;} 
    bool p4 { get; set; } 
    DateTime p5 { get; set; } 
} 

public interface MyInterface 
{ 
    IData GetData(IParameters p); 
} 
+0

Hört sich gut an, eine Schnittstelle für den Parametertyp zu haben, aber bedenken Sie, dass die Schnittstellen nicht versioniert werden können. Wenn sich die API ausbreitet, kann niemand dem Parametertyp zusätzliche Funktionalität hinzufügen (ohne einen weiteren Parameter hinzuzufügen) Codes. –