In welchem ​​Namespace sollten Sie Schnittstellen in Bezug auf ihre Implementierer setzen?

StackOverflow https://stackoverflow.com/questions/146777

  •  02-07-2019
  •  | 
  •  

Frage

Insbesondere dann, wenn Sie eine Schnittstelle / Implementierer Paar erstellen, und es gibt keine übergeordneten organisatorischen Anliegen (wie die Schnittstelle in einer anderen Baugruppe also gehen sollte, wie die s # Architektur empfohlen) zu tun haben Sie eine Standard-Art und Weise zu organisieren, sie in Ihrem Namensraum / Benennungsschema?

Dies ist offensichtlich eine Meinung anhand Frage, aber ich denke, dass einige Leute über dieses mehr gedacht haben, und wir können alle profitieren von ihren Schlussfolgerungen.

War es hilfreich?

Lösung

Die Antwort hängt von Ihren Absichten.

  • Wenn Sie die Verbraucher Ihrer Namensräume beabsichtigen die Schnittstellen über die konkreten Implementierungen zu verwenden, würde ich empfehlen, Ihre Schnittstellen in dem Top-Level-Namespace mit den Implementierungen in einem Kind-Namensraum mit
  • Wenn die Verbraucher beide zu verwenden sind, hat sie im gleichen Namensraum.
  • Wenn die Schnittstelle für überwiegend spezialisierten Gebrauch ist, wie neue Implementierungen zu schaffen, sollte sie in einem Kind Namensraum wie Design oder Component mit.

Ich bin sicher, es gibt auch andere Optionen, aber wie bei den meisten Namespace Probleme, es kommt auf die Anwendungsfälle des Projekts und die Klassen und Schnittstellen enthält.

Andere Tipps

Ich halte in der Regel die Schnittstelle im gleichen Namensraum wie die konkreten Typen.

Aber das ist nur meine Meinung, und Namespace-Layout ist sehr subjektiv.

Animals
|
| - IAnimal
| - Dog
| - Cat
Plants
|
| - IPlant
| - Cactus

Sie haben wirklich nichts zu gewinnen, indem eine oder zwei Arten aus dem Hauptnamensraum zu bewegen, aber Sie tun, um die Voraussetzung für eine weitere Verwendung Anweisung hinzufügen.

Was ich in der Regel tun, ist ein Schnittstellen-Namensraum auf hohem Niveau in meiner Hierarchie zu erstellen und alle Schnittstellen in dort setzen (ich nicht die Mühe zu nisten anderen Namespaces in dort als ich dann mit vielen Namensräume mit nur einer Schnittstelle enden würde ).

Interfaces
|--IAnimal
|--IVegetable
|--IMineral
MineralImplementor
Organisms
|--AnimalImplementor
|--VegetableImplementor

Dies ist nur die Art und Weise, dass ich es in der Vergangenheit getan habe, und ich habe nicht viele Probleme mit ihm, wenn auch zugegebenermaßen könnte es andere verwirrend sein, mit meinen Projekten Hinsetzen. Ich bin sehr gespannt zu sehen, was andere Leute tun.

Ich ziehe meine Schnittstellen und Implementierungsklassen im gleichen Namensraum zu halten. Wenn möglich, gebe ich den Implementierungsklassen interne Sichtbarkeit und biete eine Fabrik (in der Regel in Form einer statischen Factory-Methode, dass die Delegierten zu einer Arbeiter-Klasse, mit einem internen Verfahren, die einen Unit-Tests in einem Freund Montag ermöglicht einen anderen Arbeitnehmer zu ersetzen, produziert stubs). Natürlich, wenn die konkrete Klasse öffentlich sein muss - zum Beispiel, wenn es eine abstrakte Basisklasse ist, dann ist das in Ordnung; Ich keinen Grund, ein ABC in seinem eigenen Namensraum zu setzen.

Auf einer Seite zur Kenntnis, ich mag nicht stark .NET Konvention Schnittstelle Namen prefacing mit dem Buchstaben ‚I‘ Die Sache, die (I) Foo-Interface-Modelle sind nicht IFoo , es ist einfach ein foo . Also warum kann ich nicht nennen es einfach Foo? Ich nenne dann die Implementierungsklassen speziell zum Beispiel AbstractFoo, MemoryOptimizedFoo, SimpleFoo, StubFoo usw.

(. Net) Ich neige dazu, Schnittstellen in einer separaten „gemeinsamen“ Versammlung zu halten, damit ich diese Schnittstelle in mehreren Anwendungen verwenden kann und noch häufiger in den Serverkomponenten meiner apps.

In Bezug auf Namespaces, halte ich sie in BusinessCommon.Interfaces.

Ich tue dies, um sicherzustellen, dass weder ich noch meine Entwickler versucht sind, die Implementierungen direkt Bezug zu nehmen.

Ich hasse es, wenn ich Schnittstellen und Implementierungen im gleichen Namensraum / Montage finden. Bitte tun Sie das nicht, wenn das Projekt weiterentwickelt, es ist ein Schmerz in den Arsch zu Refactoring ist.

Wenn ich eine Schnittstelle verweisen, möchte ich es implementieren, nicht alle ihre Implementierungen erhalten.

Was könnte ich zulässig ist die Schnittstelle mit der Abhängigkeit Klasse zu setzen ( Klasse, die die Schnittstelle verweist ).

EDIT: @ Josh, ich juste der letzte Satz von mir gelesen, es ist verwirrend! natürlich sowohl die Abhängigkeit Klasse und die, die es die Schnittstelle Referenz implementiert. Um mich klar zu machen, werde ich Beispiele:

Acceptable:

Interface + Umsetzung:

namespace A;

   Interface IMyInterface
   {
       void MyMethod();
   }

namespace A;

   Interface MyDependentClass
   {
       private IMyInterface inject;

       public MyDependentClass(IMyInterface inject)
       {
           this.inject = inject;
       }

       public void DoJob()
       {
           //Bla bla
           inject.MyMethod();
       }
   }

Die Implementierung Klasse:

namespace B;

   Interface MyImplementing : IMyInterface
   {
       public void MyMethod()
       {
           Console.WriteLine("hello world");
       }
   }

Nicht zulässig:

namespace A;

   Interface IMyInterface
   {
       void MyMethod();
   }

namespace A;

   Interface MyImplementing : IMyInterface
   {
       public void MyMethod()
       {
           Console.WriteLine("hello world");
       }
   }

Und bitte nicht schaffen ein Projekt / Müll für Ihre Schnittstellen! Beispiel: ShittyProject.Interfaces. Sie haben den Punkt verpasst!

Stellen Sie eine DLL erstellt für Ihre Schnittstellen reserviert (200 MB). Wenn Sie eine einzelne Schnittstelle mit zwei Linie Codes hinzuzufügen haben, Ihre Benutzer 200 MB aktualisieren nur für zwei stumme signaturs!

Trennen Sie die Schnittstellen in irgendeiner Weise (Projekte in Eclipse, etc.), so dass es einfach ist, nur die Schnittstellen zu implementieren. Auf diese Weise können Sie Ihre externe API zur Verfügung zu stellen, ohne Implementierungen zu bieten. Dies ermöglicht abhängige Projekte mit einem Minimum von Externen zu bauen. Offensichtlich gilt dies mehr für größere Projekte, aber das Konzept ist in allen Fällen gut.

Ich trenne sie normalerweise in zwei getrennte Baugruppen. Einer der üblichen Gründe für eine Schnittstelle ist eine Reihe von Objekten zu einem gewissen Subsystem Ihrer Software gleich aussehen zu lassen. Zum Beispiel habe ich alle meine Berichte die IReport Schnittstellen implementieren. IReport wird nur verwendet, wird nicht in den Druck verwendet, sondern für die Vorschau und für jeden Bericht einzelne Optionen auswählen. Schließlich habe ich eine Sammlung von IReport in Dialog zu verwenden, in dem der Benutzer auswählt, welche Berichte (und Konfigurieren von Optionen) sie drucken möchten.

Die Berichte befinden sich in einer separaten Assembly und dem IReport, die Vorschau-Engine, Druckmaschine, Bericht Auswahl befindet sich in ihrer jeweiligen Kernanordnung und / oder UI-Montag.

Wenn Sie die Factory-Klasse verwenden, um eine Liste der verfügbaren Berichte in dem Bericht Montag zurückzukehren, um die Software mit neuem Bericht Aktualisierung wird nur eine Frage des neuen Bericht Montag über das Original zu kopieren. Sie können sogar das Reflection-API verwenden, nur die Liste der Baugruppen für jeden Bericht Fabriken zu scannen und zu der Liste der Berichte auf diese Weise zu bauen.

Sie können auch diese Techniken auf Dateien anwenden. Meine eigene Software läuft eine Metallschneidemaschine, so dass wir diese Idee für die Form und Fitting-Bibliotheken verwenden wir neben unserer Software zu verkaufen.

Auch die Klassen einen Kern-Schnittstelle implementieren sollten in einer separaten Assembly befinden, so dass Sie die getrennt von dem Rest der Software aktualisieren.

Ich gebe meine eigene Erfahrung, die gegen andere Antworten ist.

Ich neige dazu, alle meine Schnittstellen in das Paket legen sie gehört. Dies gewährt, dass, wenn ich ein Paket in einem anderen Projekt verschiebe ich das alles, was haben muss das Paket ohne Änderungen ausgeführt sein.

Für mich alle Hilfsfunktionen und Bedienfunktionen, die einen Teil der Funktionalität einer Klasse sind, soll in den gleichen Namensraum wie die der Klasse gehen, weil sie Teil der öffentlichen API von diesem Namespace bilden.

Wenn Sie gemeinsame Implementierungen haben, die die gleiche Schnittstelle in verschiedenen Paketen teilen müssen Sie wahrscheinlich Ihr Projekt Refactoring.

Manchmal sehe ich, dass es von Schnittstellen in einem Projekt viel ist, die eher in einer abstrakten Implementierung umgesetzt werden konnten, dass eine Schnittstelle.

Also, fragen Sie sich, wenn Sie wirklich einen Typ oder eine Struktur zu modellieren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top