За останні кілька місяців я кілька разів наткнувся на наступну техніку / зразок. Однак я не можу знайти конкретне ім’я, і я не впевнений на всі 100 своїх переваг та недоліків.
Схема має такий вигляд:
В інтерфейсі Java набір загальних методів визначається як зазвичай. Однак, використовуючи внутрішній клас, екземпляр за замовчуванням просочується через інтерфейс.
public interface Vehicle {
public void accelerate();
public void decelerate();
public static class Default {
public static Vehicle getInstance() {
return new Car(); // or use Spring to retrieve an instance
}
}
}
Для мене, здається, найбільша перевага полягає в тому, що розробнику потрібно знати лише про інтерфейс, а не про його реалізацію, наприклад, якщо він швидко хоче створити екземпляр.
Vehicle someVehicle = Vehicle.Default.getInstance();
someVehicle.accelerate();
Крім того, я бачив, як ця методика використовується разом із Spring для динамічного надання примірників залежно від конфігурації. У зв'язку з цим також виглядає, що це може допомогти з модуляризацією.
Тим не менш, я не можу похитнутись від відчуття, що це неправильне використання інтерфейсу, оскільки він з'єднує інтерфейс з однією з його реалізацій. (Принцип інверсії залежності і т. Д. ) Чи не може хто-небудь пояснити мені, як називається ця методика, а також її переваги та недоліки?
Оновлення:
Через деякий час для розгляду я повторно перевірив і помітив, що наступна однотонна версія шаблону використовується набагато частіше. У цій версії публічний статичний екземпляр відкривається через інтерфейс, який ініціалізується лише один раз (через те, що поле є остаточним). Крім того, екземпляр майже завжди отримується за допомогою Spring або загальної фабрики, яка від'єднує інтерфейс від реалізації.
public interface Vehicle {
public void accelerate();
public void decelerate();
public static class Default {
public static final Vehicle INSTANCE = getInstance();
private static Vehicle getInstance() {
return new Car(); // or use Spring/factory here
}
}
}
// Which allows to retrieve a singleton instance using...
Vehicle someVehicle = Vehicle.Default.INSTANCE;
Коротше кажучи: здається, що це власний однотонний / заводський візерунок, який в основному дозволяє викрити екземпляр або синглтон через його інтерфейс. Щодо недоліків, деякі з них були названі у відповідях та коментарях нижче. Поки що перевага, здається, полягає в його зручності.
Vehicle.Default
слід перемістити в область імен пакетів як заводський клас, наприклад VehicleFactory
.
Vehicle.Default.getInstance() != Vehicle.Default.getInstance()