Un método para lograr una verdadera OCP podría ser el siguiente:
definir un método abstracto Is
para forzar cada subtipo concreto de los Mamíferos para especificar si es apropiado para un determinado valor de la enumeración:
abstract public class Mammal
{
public abstract void MakeSound();
public abstract bool Is(MammalTypes mammalType);
}
las implementaciones de está en las subclases se vería así:
class Cat : Mammal
{
// other specific members
public override bool Is(MammalTypes mammalType)
{
return mammalType == MammalTypes.Cat;
}
}
class Dog : Mammal
{
// other specific members
public override bool Is(MammalTypes mammalType)
{
return mammalType == MammalTypes.Dog;
}
}
hecho esto, ahora podemos crear un MammalF clase actory que, cuando se administra a un mamífero exploraciones valor de enumeración a través de las clases disponibles y, cuando se encuentra una coincidencia, devuelve una instancia de esa clase:
public class MammalFactory
{
private readonly IEnumerable<Type> _mammalTypes;
public MammalFactory()
{
var currentAssembly = Assembly.GetExecutingAssembly();
_mammalTypes = currentAssembly.GetTypes()
.Where(t => typeof(Mammal).IsAssignableFrom(t) && !t.IsAbstract);
}
public Mammal Create(MammalTypes mammalType)
{
return _mammalTypes
.Select(type => CreateSpecific(type, mammalType))
.First(mammal => mammal != null);
}
public Mammal CreateSpecific(Type type, MammalTypes mammalEnumType)
{
var mammalInstance = (Mammal)Activator.CreateInstance(type);
return mammalInstance.Is(mammalEnumType) ? mammalInstance : null;
}
}
El uso final se verá así:
var mammalFactory = new MammalFactory();
var guessWhatMammal = mammalFactory.Create(MammalTypes.Cat);
Esto cumple completamente con OCP. Solo es necesario crear una nueva clase de Mamíferos para que se conecte automáticamente y esté lista para usar dentro de la aplicación. (No es necesario modificar nada en la aplicación, a excepción de la enumeración en sí)
Hay algunos problemas con este enfoque:
- que sólo analiza el conjunto se está ejecutando actualmente para este tipo de mamíferos
- tiene para crear una instancia de Mamíferos cada vez que se necesita para probar si ese tipo es apropiado
Aunque estos problemas pueden resolverse, uno está todavía queda: complejidad.
Esto es complejo porque:
- hemos duplicado la cantidad de código necesario
- la auto-cableado podría ser confuso para la gente nueva al proyecto
creo que la conclusión es esto: los patrones de diseño no son reglas estrictas. No vale la pena hacer algo solo para conformarse a un diseño dado. En su lugar, tenemos que ser pragmáticos y encontrar el equilibrio perfecto entre la conformidad del patrón y la utilidad/simplicidad/legibilidad. Esto depende en gran medida del problema que intentamos resolver y en muchos casos podría ser la declaración switch
que presentó en la pregunta.
** NO ** Objeto orientado. La clase base no debe ser consciente de sus clases derivadas. – gdoron
Es difícil visualizar lo que has hecho. Por favor, agregue el código que ha escrito a su pregunta. – Abbas