За последние несколько месяцев я несколько раз спотыкался о следующей технике / схеме. Тем не менее, я не могу найти конкретное имя, и я не уверен на 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()