Bien desde su publicación, incluso si no está claramente indicado, parece que desea que la clase abstracta juegue dos roles diferentes. Las funciones son:
- el papel de la fábrica abstracta para un servicio (Singleton) que puede tener múltiples sustituibles implementaciones,
- el papel de interfaz de servicio ,
además desea que el el servicio ser singleton impone 'singletoness' en toda la familia de clases, por alguna razón no es suficiente para que guarde en caché la instancia del servicio.
Esto está bien.
Alguien dirá que huele muy mal porque "viola la separación de las preocupaciones" y "los singleton y las pruebas unitarias no van bien juntas".
Alguien más dirá que está bien porque le da la responsabilidad de instanciar a los niños correctos en la familia y también expone una interfaz más fluida en general ya que no necesita mediación de una fábrica que no hace más que exponer un método estático
Lo que está mal es que después de que desee que los niños sean los responsables de seleccionar qué implementación debe devolver el método de fábrica principal. Está mal en términos de diseño porque está delegando a todos los niños lo que simplemente puede ser empujado hacia arriba y centralizado en la superclase abstracta y también muestra que están mezclando patrones que se usan en diferentes contextos, Abstract Factory (padres deciden qué familia de las clases que recibirán los clientes) y el Método de Fábrica (las fábricas secundarias seleccionan qué obtendrán los clientes).
Método de fábrica no solo no es necesario, sino que tampoco es posible con los métodos de fábrica, ya que se centra en la implementación o anulación de métodos de "instancia". No existe una anulación para métodos estáticos, ni para un constructor.
Volviendo a la idea inicial buena o mala de un singleton abstracto que selecciona qué comportamiento exponer hay varias maneras de resolver el problema inicial, Uno podría ser el siguiente, se ve mal, pero creo que está cerca de lo Estabas buscando:
public abstract class A{
public static A getInstance(){
if (...)
return B.getInstance();
return C.getInstance();
}
public abstract void doSomething();
public abstract void doSomethingElse();
}
public class B extends A{
private static B instance=new B();
private B(){
}
public static B getInstance(){
return instance;
}
public void doSomething(){
...
}
...
}
//do similarly for class C
El padre también podría utilizar la reflexión.
Solución más amigable y amigable con la extensión es simplemente tener hijos que no sean simples pero empacados en un paquete interno que documentará como padre "privado" y abstracto que puede exponer el gettonstate estático "singleton mimiking"() y guardará en memoria caché las instancias de los hijos que imponen que los clientes siempre obtengan la misma instancia de servicio.
El propósito del constructor privado en Singleton es evitar que alguien más lo instancia. Lo he logrado aquí: no se puede crear una instancia de una clase abstracta, y la subclase tiene un constructor privado. – Simon
No obliga a que la subclase sea solo abstracta y solo tenga un constructor privado. – BalusC
Singleton no _require_ un constructor privado (ver mi respuesta para una solución a esta pregunta con un constructor público). – ryvantage