Nie uważam za użyteczne debatowanie na temat tego, co stanowi i nie stanowi ani jednej odpowiedzialności, ani jednego powodu do zmiany. Zamiast tego zaproponowałbym zasadę minimalnego smutku:
Zasada minimalnego żalu: kod powinien dążyć do zminimalizowania prawdopodobieństwa wymaganej zmiany lub zmaksymalizować łatwość zmiany.
Jak to? Nie powinien zająć się naukowcem zajmującym się rakietami, aby dowiedzieć się, dlaczego może to pomóc w obniżeniu kosztów utrzymania, i mam nadzieję, że nie powinno to być punktem niekończącej się debaty, ale jak w przypadku SOLID ogólnie, nie jest to coś, co można stosować na ślepo. Jest to coś do rozważenia podczas równoważenia kompromisów.
Jeśli chodzi o prawdopodobieństwo wymagania zmian, spada to:
- Dobre testy (poprawiona niezawodność).
- Zaangażowanie tylko minimalnego kodu wymaganego do zrobienia czegoś konkretnego (może to obejmować zmniejszenie sprzężeń aferentnych).
- Po prostu uczynienie kodu niepoprawnym w tym, co robi (zobacz Make Badass Principle).
Jeśli chodzi o trudność wprowadzania zmian, idzie w górę z połączeniami odprowadzającymi. Testowanie wprowadza sprzężenie odprowadzające, ale poprawia niezawodność. Zrobione dobrze, ogólnie przynosi więcej korzyści niż szkody i jest całkowicie akceptowalne i promowane przez zasadę minimalnego smutku.
Zrób zasadę Badassa: klasy używane w wielu miejscach powinny być niesamowite. Powinny być niezawodne, wydajne, jeśli wiąże się to z ich jakością itp.
A zasada Make Badass jest powiązana z zasadą minimalnego smutku, ponieważ rzeczy badass będą miały mniejsze prawdopodobieństwo potrzeby zmian niż rzeczy, które są do kitu.
Zacząłbym od wskazania wyżej wspomnianego paradoksu, a następnie wskazania, że SRP jest wysoce zależny od poziomu szczegółowości, który chcesz wziąć pod uwagę, i jeśli posuniesz się wystarczająco daleko, każda klasa zawierająca więcej niż jedną właściwość lub jedną metodę narusza to.
Z punktu widzenia SRP klasa, która prawie nic nie robi, z pewnością miałaby tylko jeden (czasem zerowy) powód do zmiany:
class Float
{
public:
explicit Float(float val);
float get() const;
void set(float new_val);
};
To praktycznie nie ma powodów do zmiany! To lepsze niż SRP. To ZRP!
Poza tym sugerowałbym, że jest to rażące naruszenie zasady Make Badass. Jest to również absolutnie bezwartościowe. Coś, co robi tak niewiele, nie może mieć nadziei na bycie poważnym. Ma za mało informacji (TLI). I oczywiście, kiedy masz coś, co jest TLI, nie może zrobić nic naprawdę znaczącego, nawet z zawartymi w nim informacjami, więc musi wyciekać to do świata zewnętrznego w nadziei, że ktoś inny zrobi coś znaczącego i złego. I ta nieszczelność jest dobra w przypadku czegoś, co ma na celu jedynie agregację danych i nic więcej, ale ten próg jest różnicą, jak widzę, między „danymi” a „obiektami”.
Oczywiście coś, co jest TMI, jest również złe. Możemy umieścić całe nasze oprogramowanie w jednej klasie. Może nawet mieć tylko jedną run
metodę. I ktoś może nawet argumentować, że ma teraz jeden bardzo szeroki powód do zmiany: „Ta klasa będzie musiała zostać zmieniona tylko wtedy, gdy oprogramowanie wymaga poprawy”. Jestem głupi, ale oczywiście możemy sobie wyobrazić wszystkie problemy z konserwacją.
Istnieje więc równowaga co do ziarnistości lub szorstkości projektowanych obiektów. Często oceniam to na podstawie ilości informacji, które musisz wyciec do świata zewnętrznego i tego, jak wiele znaczących funkcji może wykonać. Często uznaję zasadę Bad Badass za pomocną w znalezieniu równowagi, łącząc ją z zasadą minimalnego smutku.