Objekt-orientierte design-Muster zu vermeiden, if/then/else-Anweisungen
Weil ich bin relativ neu OOP /C# ich weiß nicht das richtige Muster um dieses Problem zu lösen:
Muss ich bauen, eine plugin-Architektur für verschiedene IO-Anbietern.
Der host liest die benötigten Provider-name /- Typ aus der config, dann sollte der provider instanziieren und parametrieren.
Also ich habe im Grunde diese Schnittstellen:
public interface IoProvider //(Base interface, all Providers implements this)
{
void Initialize();
void Execute();
}
public interface IFileProvider: IoProvider
{
string PropertyA { get; set; }
}
public interface ISmtpProvider : IoProvider
{
string PropertyB { get; set; }
string PropertyC { get; set; }
}
Wie Sie sehen sind die abgeleiteten, spezialisierten IO Anbieter haben verschiedene zusätzliche parameter, um die Eigenschaften, die die Basis-Schnittstelle nicht haben.
Zu vermeiden, if/then/else-oder switch-Anweisungen meine Idee war die Verwendung eines factory-pattern.
Aber wenn verstehe ich das richtig löst es nicht mein if/then/else " - problem, da auf dem client habe ich zu prüfen, den abgeleiteten Typ um den korrekten Parametern.
So dass der Programmablauf auf dem Host wäre so etwas wie dieses:
Host-config liest, bekommt den Namen/Typ der benötigten Provider
Host fordert Fabrik und bekommt der Anbieter
Aber, wie dies zu vermeiden ist es, ein Muster zu lösen, das ohne wenn/dann/sonst?
If (provider == typeOf(IFileProvider))
PropertyA = value
else if (provider == typeOf(ISmtpProvider))
PropertyB = value
PropertyC = value
Elseif …
- was ist falsch mit
if/else
? - Ich mag Karten, die für diese Art der Sache, aber die Fabriken haben oft große switch-Anweisungen. Warum hast du das Bedürfnis, es zu entfernen?
- ich habe gelernt, das ist schlecht coding style. es gibt nicht nur 2 Arten von Anbietern, im moment gibt es 5 verschiedene Anbieter.
- warum ist es schlechter Stil? Was ist das problem, dass das versuchen zu vermeiden? Wie ist eine Konfigurationsdatei, in verschiedenen seiner Auswirkungen in der Praxis als eine große switch-Anweisung?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie ersetzen
switch
- Anweisung mit Polymorphismus. Nur dass es jedem Anbieter selbst zu konfigurieren von config. Dies ist die beste option, weil jeder Anbieter weiß, welche Werte zu suchen:Sollte diese Methode existiert in Basis-Schnittstelle:
Und die einzelnen Anbieter implementieren:
Wichtigste Vorteil dieses Ansatzes ist, dass Sie nur an einer Stelle ändern, wenn neue Anbieter Hinzugefügt, um Ihre Anwendung - fügen Sie einfach neue Anbieter-Klasse, die weiß, wie man selbst zu konfigurieren. Sie brauchen nicht zu ändern, host-Implementierung. Und Ihre Gastgeber erfüllen OCP Prinzip offen für Erweiterung (Sie können hinzufügen, neue Anbieter), aber geschlossen für änderung (Sie müssen Sie nicht ändern bestehenden code beim neuen Anbieter Hinzugefügt).
Außerdem können Sie einige Konfigurations-Objekt zu
Configure(IConfiguration config)
dieser Methode (es wird Ihr code getestet, und nicht abhängig von statischenConfigurationManager
).provider.Configure(ConfigurationManager.AppSettings);
.Wenn du tot bist setzen auf das loswerden von der if/else-Anweisungen, können Sie vielleicht einen loader in Ihre Basis-Klasse, die Sie alle übergeben die Parameter an, und haben dann jede Klasse überladen ist, und verwenden Sie nur die Parameter, die Sie braucht.
Werde ich die Art und Weise, dass das eine wünschenswert prasseln nur, wenn alle Ihre abgeleiteten Klassen sind garantiert verwenden Sie die gleiche kleine Sammlung von Parametern, auf verschiedene Weise. Ansonsten, die
if
/else
Aussagen sind wahrscheinlich wünschenswertDu am Ende immer bis zum Ende verwenden eine bedingte Anweisung.
Sicher, Sie können einige Bibliothek zu abstrahieren, diese. Wie ein Dependency Injection-Bibliothek und basiert in einigen Konstruktoren können Sie in der Lage sein, dies zu tun, ohne ifs.
Aber...
Seine wirklich nicht Wert, du wirst noch eine Menge von Komplexität, um den code kurz zu machen es mehr elegant und die vor-und Nachteile es in der Regel nicht Wert.
Thats nicht zu sagen, dass Sie etwas nicht tun können besser. Das Schießen aus der Hüfte, ich möchte hinzufügen, eine Methode, wie dies für die Schnittstelle.
void Init(Dictionary-Parameter), und in jede Anwendung, die Sie Lesen, aus dem Wörterbuch und initialisieren Sie die erforderlichen Eigenschaften