Я использовал внутреннее перечисление в интерфейсе, описывающем стратегию для сохранения контроля над экземпляром (каждая стратегия - Синглтон).
public interface VectorizeStrategy {
/**
* Keep instance control from here.
*
* Concrete classes constructors should be package private.
*/
enum ConcreteStrategy implements VectorizeStrategy {
DEFAULT (new VectorizeImpl());
private final VectorizeStrategy INSTANCE;
ConcreteStrategy(VectorizeStrategy concreteStrategy) {
INSTANCE = concreteStrategy;
}
@Override
public VectorImageGridIntersections processImage(MarvinImage img) {
return INSTANCE.processImage(img);
}
}
/**
* Should perform edge Detection in order to have lines, that can be vectorized.
*
* @param img An Image suitable for edge detection.
*
* @return the VectorImageGridIntersections representing img's vectors
* intersections with the grids.
*/
VectorImageGridIntersections processImage(MarvinImage img);
}
Тот факт, что enum реализует стратегию, удобен для того, чтобы класс enum мог выступать в качестве прокси для своего вложенного экземпляра. который также реализует интерфейс.
это своего рода стратегия EnumProxy: P код кода выглядит следующим образом:
VectorizeStrategy.ConcreteStrategy.DEFAULT.processImage(img);
Если бы он не реализовал интерфейс, он был бы:
VectorizeStrategy.ConcreteStrategy.DEFAULT.getInstance().processImage(img);