Un metodo per raggiungere la vera OCP potrebbe essere il seguente:
definire un metodo astratto Is
per forzare ogni sottotipo concreto di Mammifero per specificare se sia opportuno per un dato valore della enum:
abstract public class Mammal
{
public abstract void MakeSound();
public abstract bool Is(MammalTypes mammalType);
}
le implementazioni di Is nelle sottoclassi sarebbe simile:
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;
}
}
fatto questo, possiamo ora creare un MammalF Classe actory che, quando somministrato un mammifero scansioni valore enum attraverso le classi disponibili e, quando trova una corrispondenza, restituisce un'istanza di quella classe:
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;
}
}
L'utilizzo finale sarà simile a questa:
var mammalFactory = new MammalFactory();
var guessWhatMammal = mammalFactory.Create(MammalTypes.Cat);
Questo è pienamente conforme a OCP. È necessario solo creare una nuova classe Mammal per essere automaticamente cablata e pronta all'uso all'interno dell'applicazione. (Non c'è bisogno di modificare qualsiasi altra cosa nella domanda, fatta eccezione per l'enumerazione stessa)
ci sono alcuni problemi con questo approccio:
- sottopone a scansione solo l'assemblea in corso di esecuzione per i tipi di mammiferi
- ha per creare un'istanza di Mammifero ogni volta che ha bisogno di verificare se tale tipo sia opportuno
anche se questi problemi possono essere affrontati, uno è ancora a sinistra: complessità.
Questo è complessa perché:
- abbiamo raddoppiato la quantità di codice necessaria
- l'auto-cablaggio potrebbe essere fonte di confusione per chi ancora non conosce il progetto
penso alla conclusione è questo: i modelli di design non sono regole severe. Non vale la pena fare qualcosa solo per conformarsi a un determinato progetto. Invece, dobbiamo essere pragmatici e trovare quel perfetto equilibrio tra conformità del modello e utilità/semplicità/leggibilità. Ciò dipende in gran parte dal problema che tentiamo di risolvere e in molti casi potrebbe benissimo essere la dichiarazione switch
presentata nella domanda.
È ** NON ** Orientato agli oggetti. La classe base non dovrebbe essere a conoscenza delle sue classi derivate. – gdoron
È difficile visualizzare ciò che hai fatto. Aggiungi il codice che hai scritto alla tua domanda. – Abbas