L'applicazione più utile che ho trovato è con le fabbriche di implementazione. In molti casi, è utile creare classi mutabili all'interno della fabbrica ma non modificabili per classi esterne. Questo può essere facilmente implementato in Java usando classi interne, rendendo privati i campi e i loro setter e esponendo i getter come membri pubblici. Tuttavia in C #, ho dovuto usare interfacce esplicite per ottenere la stessa cosa. Spiegherò ulteriormente:
In Java, la classe interna AND la classe esterna possono accedere a membri privati l'una dell'altra, il che ha perfettamente senso poiché le classi sono strettamente correlate. Sono nello stesso file di codice e sono probabilmente sviluppati dallo stesso sviluppatore. Ciò significa che i campi e i metodi privati nella classe interna possono ancora essere utilizzati dalla fabbrica per modificare i loro valori. Ma le classi esterne non potranno accedere a questi campi se non attraverso i loro getter pubblici.
Tuttavia, in C #, le classi esterne non possono accedere ai membri privati delle classi interne in modo tale che il concetto non sia direttamente applicabile. Ho usato un'interfaccia esplicita come soluzione alternativa definendo un'interfaccia privata nella classe esterna e implementandola esplicitamente nella classe interna. In questo modo, solo la classe esterna può accedere ai metodi in questa interfaccia nello stesso modo in cui viene eseguita in Java (ma devono essere metodi, non campi).
Esempio:
public class Factory
{
// factory method to create a hard-coded Mazda Tribute car.
public static Car CreateCar()
{
Car car = new Car();
// the Factory class can modify the model because it has access to
// the private ICarSetters interface
((ICarSetters)car).model = "Mazda Tribute";
return car;
}
// define a private interface containing the setters.
private interface ICarSetters
{
// define the setter in the private interface
string model { set; }
}
// This is the inner class. It has a member "model" that should not be modified
// but clients, but should be modified by the factory.
public class Car: ICarSetters
{
// explicitly implement the setter
string ICarSetters.model { set; }
// create a public getter
public string model { get; }
}
}
class Client
{
public Client()
{
Factory.Car car = Factory.CreateCar();
// can only read model because only the getter is public
// and ICarSetters is private to Factory
string model = car.model;
}
}
Questo è ciò per cui utilizzerei interfacce esplicite.