Frage

Angenommen, ich eine Klasse ‚Anwendung‘ haben. Um initialisiert zu werden, dass bestimmte Einstellungen im Konstruktor. Nehmen wir an, dass die Zahl der Einstellungen so viele, dass es überzeugend ist sie in eine eigene Klasse zu setzen.

Vergleichen Sie die folgenden zwei Implementierungen dieses Szenario.

Die Umsetzung 1:

class Application 
{
   Application(ApplicationSettings settings) 
   {
       //Do initialisation here
   }
}

class ApplicationSettings 
{
   //Settings related methods and properties here
}

Implementierung 2:

class Application 
{
   Application(Application.Settings settings) 
   {
       //Do initialisation here
   }

   class Settings 
   {
      //Settings related methods and properties here
   }
}

Für mich ist der zweite Ansatz sehr viel besser. Es ist besser lesbar, weil sie stark die Beziehung zwischen den beiden Klassen betont. Wenn ich Code schreiben, überall Application-Klasse instanziiert wird der zweite Ansatz geht schönere zu suchen.

Nun stellen Sie sich vor der Settings-Klasse selbst wiederum etwas ähnlich „verwandte“ Klasse hatte und diese Klasse wiederum tat das auch. Gehen Sie nur drei solche Ebene und die Klassennamen werden in dem ‚nicht-verschachtelten‘ Fall aus der Hand heraus. Wenn Sie Nest jedoch bleiben die Dinge noch elegant.

Trotz der oben Ich habe Leute lesen auf Stackoverflow sagen, dass verschachtelte Klassen gerechtfertigt sind nur dann, wenn sie nach außen nicht sichtbar sind; das heißt, wenn sie nur für die interne Umsetzung der enthaltenden Klasse verwendet werden. Die häufigsten zitierte Einwand ist Blähungen die Größe der Quelldatei der Klasse enthält, aber partielle Klassen ist die perfekte Lösung für dieses Problem.

Meine Frage ist, warum sind wir vorsichtig bei der Verwendung von verschachtelten Klassen „öffentlich ausgesetzt“? Gibt es noch andere Argumente gegen eine solche Verwendung?

War es hilfreich?

Lösung

Ich denke, es ist in Ordnung. Dies ist im Grunde die Erbauer und verschachtelte Klassen funktioniert ziemlich gut. Sie können damit auch der Baumeister Zugang private Mitglieder der äußeren Klasse, die sehr nützlich sein kann. Zum Beispiel können Sie eine Build-Methode auf dem Erbauer haben, die einen privaten Konstruktor auf der äußeren Klasse aufruft, die eine Instanz des Builder nimmt:

public class Outer
{
    private Outer(Builder builder)
    {
        // Copy stuff
    }

    public class Builder
    {
        public Outer Build()
        {
            return new Outer(this);
        }
    }
}

Das stellt sicher, dass der nur Art und Weise eine Instanz der äußeren Klasse des Gebäudes ist über den Erbauer.

Ich benutze ein Muster sehr ähnlich wie dies in meinen C # Port Protocol Buffers.

Andere Tipps

Sie können die Namensräume verwenden, um Dinge zu beziehen, die sind ... Zusammenhang stehen.

Zum Beispiel:

namespace Diner
{
    public class Sandwich
    {
        public Sandwich(Filling filling) { }
    }

    public class Filling { }
}

Dies hat den Vorteil gegenüber der Verwendung Klassen, als ob sie Namespaces waren ist, dass Sie die Verwendung using auf der rufenden Seite optional kann, um die Dinge abzukürzen:

using Diner;

...

var sandwich = new Sandwich(new Filling());

Wenn Sie die Sandwich Klasse verwenden, als ob es ein Namensraum für Filling waren, haben Sie den vollständigen Namen Sandwich.Filling verwenden, um Filling zu beziehen.

Und wie wollen Sie schlafen in der Nacht, dass das Wissen?

Sie können prüfen wollen, was Microsoft hat zu sagen zum Thema . Im Grunde ist es eine Frage des Stils würde ich sagen.

Ein weiteres praktisches Beispiel, das ich für eine gültige Verwendung öffentlicher verschachtelter Klassen ist in MVC-Muster, wenn ich ein Ansichtsmodell mit einer IEnumerable Eigenschaft verwenden. zum Beispiel:

public class OrderViewModel
{
public int OrderId{ get; set; }
public IEnumerable<Product> Products{ get; set; }

public class Product {
public string ProductName{ get; set; }
public decimal ProductPrice{ get; set; }
}

}

Ich benutze es, weil ich nicht Product Klasse will außerhalb wiederverwendet werden, da es für dieses spezifische Ansichtsmodell nur besonders angefertigt wird, die es enthält. Aber ich kann es nicht privat machen, weil die Produkte Eigentum öffentlich ist.

Ich verwende in erster Linie verschachtelte Klassen für die Feinabstimmung Zugriff auf die verschachtelte und / oder der Container-Klasse.

Eine Sache zu erinnern ist, dass eine verschachtelte Klassendefinition im Grunde ein Klassenmitglied ist, und private Container aller Zugriff auf die Variablen hat.

Sie können auch diese Nutzung einer bestimmten Klasse steuern.

Beispiel:

public abstract class Outer
{
  protected class Inner
  {
  }
}

Nun, in diesem Fall der Benutzer (die Klasse) kann nur die innere Klasse zugreifen, wenn er implementiert Außen.

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