Jakie są główne zalety posiadania czystych modeli POCO? Rozumiem, że modele powinny być czyste i proste, ale zazwyczaj lubię utrzymywać utrzymanie obiektów potomnych w klasach modeli. Na przykład, jeśli mam a ClassA
i ClassB
zdefiniowane w następujący sposób:
public class ClassA
{
public string MyProp { get; set; }
public IEnumerable<ClassB> Children { get; }
public void AddChild(ClassB newChild) { /*... */ }
public void RemoveChild(ClassB child) { /* ... */ }
}
public class ClassB
{
public string SomeProp { get; set; }
}
Czy jest coś z natury nie tak z metodami dodawania i usuwania? Czy zamiast tego powinienem po prostu odsłonić listę i pozwolić kodowi klienta na dodanie tego, co przechodzi odpowiedzialność za proste sprawdzanie poprawności danych, np. Nie jest zerowe i nie może być duplikowane do innej klasy?
Każda pomoc jest mile widziana, dzięki.
AddChild(ClassB newChild) => Children.Add(newChild ?? new NullClassB())
Odpowiedzi:
Twoje dwa pytania nie są ze sobą powiązane.
Czysty POCO nie jest zależny od jakiegoś frameworku, konwencji, […] rzeczy lub ściśle związany z jakimś obiektem, który jest podobnie zależny. Innymi słowy, świat może całkowicie zmienić się wokół POCO i po prostu robi to, co robi, bez opieki. Nie możesz go zepsuć, aktualizując framework, przenosząc go do nowego systemu lub śmiesznie na niego patrząc. Po prostu działa. Jedyne zależności to rzeczy, o które wyraźnie prosi.
POCO to nic innego jak pomysł POJO. J został zmieniony na C, ponieważ ludzie patrzą na ciebie śmiesznie, gdy wyjaśnisz pojęcie, które ma nazwę Java w nazwie, jeśli ci ludzie używają C #. Pomysł nie zależy od języka. Mogliby po prostu nazwać to Plain Old Objects. Ale kto chce się chwalić używanie POO?
Pozwolę Fowlerowi wyjaśnić pochodzenie:
Co do twojego drugiego pytania:
Nie lubię
A
bezpośrednio wiedziećB
. Ale to jest DIP , a nie POJO .źródło
B
dla uproszczenia, idealnie byłyby to oba zaimplementować interfejsy. AleA
wciąż ma listęIInterfaceB
. Czy coś jest nie tak z tąAddChild
metodą, jeśli dzieci są luźno powiązane poprzez referencje interfejsu?Za pomocą opcji Dodaj i usuń wdrażasz
Collection<T>
funkcje. Zadaj sobie pytanie, dlaczego używaszIEnumerable<T>
zamiastList<T>
lub jakiejś innej zmiennej klasy? Najwyraźniej nie dlatego, że twoja kolekcja powinna być tylko do odczytu.Jedynym powodem, dla którego mogę wymyślić, jest to, że chcesz kontrolować metody dostępu, które chcesz opublikować. W takim przypadku fajniej byłoby stworzyć własną klasę kolekcji, obudować listę, wdrożyć wybrane metody Dodaj i usuń oraz zaimplementuj
IEnumerable<T>
. Następnie użyj tego zamiastIEnumerable<T>
dla typu kolekcji dla dzieci.Ale wydaje mi się,
List<ClassB>
że prawdopodobnie po prostu dobrze ci służy.źródło
Co
AddChild
dodaje do iRemoveChild
usuwa? Jeśli pochodzi z bazy danych (lub innego rodzaju magazynu trwałości), masz rodzaj rekordu aktywnego. Niekoniecznie zawsze jest to zła rzecz, ale zdecydowanie zbliża się do zmartwień o ramy, konwencje, zależności itp., Jak wspomina @CandiedOrange.Jednocześnie jaki byłby sens unikania zależności od klasy A do klasy B (lub przynajmniej interfejsu B), jeśli wszystkie są w tej samej aplikacji? W domenie świata rzeczywistego, którą modeluje twoja aplikacja, rzeczy zależą od siebie. Obiekty świata rzeczywistego zrobić mieć kolekcje innych obiektów, które „należą” do nich. Całkowicie właściwe jest reprezentowanie tych relacji w kodzie.
Jedynym powodem, dla którego staje się to trochę skomplikowane, jest to, że wydaje się, że musisz dokładnie zarządzać sposobem, w jaki klasa B zostaje skojarzona i odłączona od klasy A. Musisz więc wdrożyć małe zachowanie. Możesz albo zaimplementować go w klasie (co jest całkowicie „legalne”; patrz /programming//a/725365/44586 ), albo możesz mieć jakąś odrębną klasę, która zawiera takie zachowanie. Rób to, co najbardziej odpowiada twoim indywidualnym okolicznościom.
W każdym razie POJO / POCO jest tak naprawdę OOP, jak miało być, bez ozdób i bez obciążeń. Postępuj zgodnie z zasadami OOP, a będziesz bezpieczny.
źródło