Jedną z metod osiągnięcia prawdziwej OCP mogą być następujące:
Zdefiniuj abstrakcyjną metodę Is
zmusić każdy konkretny podtyp ssaka, aby określić, czy jest to odpowiednie dla danej wartości wyliczenia:
abstract public class Mammal
{
public abstract void MakeSound();
public abstract bool Is(MammalTypes mammalType);
}
implementacje jest w podklasach wyglądałby następująco:
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;
}
}
To zostało zrobione, możemy teraz stworzyć MammalF actory klasa, że kiedy dany ssak skany ENUM wartosc poprzez dostępnych klas, a gdy znajdzie dopasowanie, zwraca instancję tej klasy:
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;
}
}
Ostateczne wykorzystanie będzie wyglądać następująco:
var mammalFactory = new MammalFactory();
var guessWhatMammal = mammalFactory.Create(MammalTypes.Cat);
To w pełni zgodne z OCP. Konieczne jest tylko utworzenie nowej klasy Mammal, aby była automatycznie połączona i gotowa do użycia w aplikacji. (Nie ma potrzeby modyfikowania czegokolwiek innego we wniosku, z wyjątkiem samego wyliczenia)
istnieją pewne problemy z tego podejścia:
- tylko skanuje aktualnie realizuje montaż dla typów ssak
- ma aby utworzyć instancję ssaka za każdym razem musi sprawdzić, czy typ jest odpowiedni
Chociaż te problemy można rozwiązać, jedno pozostało: złożoność.
To skomplikowane, ponieważ:
- mamy podwoiła ilość kodu potrzebna
- auto-okablowanie może być mylące dla osób nowych w projekcie
myślę zawarcia jest to: wzorce projektowe nie są ścisłymi regułami. Nie warto robić czegoś tylko po to, aby dopasować się do danego projektu. Zamiast tego musimy być pragmatyczni i znaleźć idealną równowagę między zgodnością wzoru a użytecznością/prostotą/czytelnością. To w dużej mierze zależy od problemu, który próbujemy rozwiązać, aw wielu przypadkach może to być oświadczenie, które przedstawiłeś w pytaniu.
To ** NIE ** Obiekt zorientowany. Klasa bazowa nie powinna być świadoma klas pochodnych. – gdoron
Trudno wyobrazić sobie, co zrobiłeś. Dodaj kod, który napisałeś do swojego pytania. – Abbas