Załóżmy, że mamy kolekcję, która jest poprawna tylko wtedy gdy jej składowe elementy spełniają pewne wymogi. Wymogiem wobec tych elementów jest warunek by wszystkie jego pola (wartości liczbowe) były większe od zera. Teraz rozpatrzmy funkcję Add. Chcemy do kolekcji dodać nowy element ale chcemy wiedzieć czy element ten jest poprawny, żeby nie "uszkodzić" kolekcji. Czy funkcja Add oprócz dodawania elementu powinna najpierw sprawdzać jego poprawność? Czy to nie jest naruszenie zasady SRP? Klient może nie oczekiwać, że funkcja, która z nazwy zajmuje się dodawaniem będzie jeszcze walidować obiekt.
Oprócz tego potrzebna jest oddzielna funkcja która sprawdza poprawność obiektu: Validate.Gdzie powinna być zaimplementowana ta funkcja? W kolekcji? Ale walidacja obiektów, nie leży w granicach obowiązków kolekcji. Zatem funkcja Validate powinna być zaimplementowana w klasie Element. Dobrze myślę?
Jeżeli funkcja Add w kolekcji będzie tylko dodawać elementy bez ich walidowania, natomiast klasa element będzie zawierać funkcję Validate to wymuszamy by klient za każdym razem najpierw sprawdził element: element.Validate(), a dopiero potem mógł go dodać do kolekcji: list.Add(element). Problemem jest, że za każdym razem trzeba powtórzyć tę czynność, narażamy klienta na to, że po prostu zapomni to zrobić. Czy zatem kolekcja powinna być wyposażona w funkcję ValidateAndAdd(), zamiast Add()?
ValidateAndAdd(Element el)
{
el.Validate();
Add(el); // funkcja prywatna, dzięki czemu zabezpieczamy się, że w kolekcji nie znajdzie się nieprawidłowy obiekt
}
Ok, jeżeli wybiorę podejście ValidateAndAdd, to czy dobrym rozwiązaniem jest rzucanie wyjątku gdy element nie przejdzie walidacji? Czy zamiast tego funkcja powinna zwracać true/false?
ValidateAndAdd(Element el)
{
if (!el.Validate())
throw new ElementValidationException();
Add(el); // funkcja prywatna
}