Witaj, programuję w C# ale postaram się w pseudokodzie/opisie przedstawić ideę, jak będzie trzeba to mogę napisać kod w C#, a nawet w javie ale piszę z "marszu".
Nasuwa się pytanie pierwsze, czy chcesz wiedzieć dokładnie, która reguła zwróciła błąd czy tylko, że jest błąd i np.: w stringu opis wszystkich reguł które się nie powiodły ale to zawsze będziesz mógł sobie zmienić.
Moja propozycja jest następująca oczywiście, zawsze możesz zrobić te jako klasy generyczne, czyli w zależności od typu.
Powiedzmy, że masz konkretną klasę Validator (można oczywiście dodać interfejsy kwestia detali), która ma metody walidacyjne, detale potem wszystko też zależy jak chcesz tego używać ale postaram się przedstawić koncepcję.
Dodatkowo mamy klasę ValidationRule, która jest pojedynczą regułą i ma powiedzmy metodę bool IsValid oraz właściwość string ValidationError ale oczywiście można to delikatnie zmienić, żeby zwracała ValidationResult (która ma bool Is Valid oraz string z błędem, kwestia smaku).
Załóżmy, że chcesz zwalidować swój input używając trzech reguł więc tworzysz, trzy konkretne klasy ValidationRule i przekazujesz je jako lista do konstruktora Validator, a następnie w metodzie IsValid sprawdzasz wszystkie reguły i zwracasz odpowiedni rezultat, a dodatkowo inną metodą (np ValidationErrors) jeśli IsValid jest false zwracasz string lub listę stringów lub ValidationResult(s) jako listę (kwestia implementacji) i wiesz dokładnie który element z listy i dlaczego spowodował błąd walidacji.
Oczywiście konkretna implementacja będzie zależeć od wielu szczegółów tego co chcesz i jak zrobić ale wydaje mi się, że przedstawiłem ogólne podejście.
BTW: SOLID to tylko drogowskaz/definicja/reguły/pomoc :-) jak nie wiesz co zrobić to używasz SOLID i wtedy prawie zawsze powinno być ok, ale od każdej reguły można odejść o ile wie się dlaczego i co to powoduje (to gdzieś w necie znalazłem w podobnym brzmieniu).