Найкорисніше застосування, яке я знайшов, - це на заводах-реалізаторах. У багатьох випадках корисно створювати класи, які можна змінювати всередині фабрики, але незмінні для зовнішніх класів. Це може бути легко реалізовано в Java за допомогою внутрішніх класів, зробивши поля та їх сеттерів приватними та оголивши гетерів як публічних членів. Однак у C # мені довелося використовувати явні інтерфейси, щоб досягти того самого. Я поясню далі:
У Java внутрішній клас І зовнішній клас можуть отримати доступ до приватних членів один одного, що має тотальний сенс, оскільки класи дуже тісно пов'язані між собою. Вони знаходяться в одному файлі коду і, ймовірно, розроблені тим же розробником. Це означає, що приватні поля та методи у внутрішньому класі все ще можуть отримати доступ до фабрики для зміни своїх значень. Але зовнішні класи не зможуть отримати доступ до цих полів, за винятком своїх громадських організацій.
Однак у C # зовнішні класи не можуть отримати доступ до приватних членів внутрішніх класів, тому ця концепція не застосовується безпосередньо. Я використовував явний інтерфейс як спосіб вирішення, визначаючи приватний інтерфейс у зовнішньому класі та явно реалізуючи його у внутрішньому класі. Таким чином, лише зовнішній клас може отримати доступ до методів цього інтерфейсу так само, як це робиться в Java (але вони повинні бути методами, а не полями).
Приклад:
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;
}
}
Саме для цього я б використовував явні інтерфейси.