Piszę dużo kodu, który obejmuje trzy podstawowe kroki.
- Zdobądź skądś dane.
- Przekształć te dane.
- Umieść te dane gdzieś.
Zazwyczaj używam trzech rodzajów zajęć - zainspirowanych ich wzorami projektowymi.
- Fabryki - aby zbudować obiekt z jakiegoś zasobu.
- Mediatorzy - aby skorzystać z fabryki, przeprowadzić transformację, a następnie użyć dowódcy.
- Dowódcy - aby umieścić te dane gdzie indziej.
Moje klasy wydają mi się być dość małe, często pojedyncza (publiczna) metoda, np. Uzyskiwanie danych, przekształcanie danych, wykonywanie pracy, zapisywanie danych. Prowadzi to do mnożenia klas, ale ogólnie działa dobrze.
Tam, gdzie walczę, kiedy przychodzę na testy, kończę na ściśle powiązanych testach. Na przykład;
- Factory - odczytuje pliki z dysku.
- Commander - zapisuje pliki na dysk.
Nie mogę przetestować jednego bez drugiego. Mógłbym również napisać dodatkowy kod „testowy”, aby wykonać odczyt / zapis dysku, ale potem się powtarzam.
Patrząc na .Net, klasa File ma inne podejście, łączy obowiązki (mojej) fabryki i dowódcy. Posiada funkcje tworzenia, usuwania, istnienia i odczytu wszystkich w jednym miejscu.
Czy powinienem podążać za przykładem .Net i łączyć - szczególnie w przypadku zasobów zewnętrznych - moje klasy razem? Kod nadal jest sprzężony, ale jest bardziej celowy - dzieje się to w oryginalnej implementacji, a nie w testach.
Czy mój problem polega tutaj na tym, że zastosowałem zasadę jednej odpowiedzialności w sposób nadmiernie nadgorliwy? Mam osobne klasy odpowiedzialne za czytanie i pisanie. Kiedy mogłem mieć połączoną klasę, która jest odpowiedzialna za zarządzanie konkretnym zasobem, np. Dyskiem systemowym.
Looking at .Net, the File class takes a different approach, it combines the responsibilities (of my) factory and commander together. It has functions for Create, Delete, Exists, and Read all in one place.
- Pamiętaj, że łączysz „odpowiedzialność” z „rzeczą do zrobienia”. Odpowiedzialność jest bardziej jak „obszar troski”. Obowiązkiem klasy File jest wykonywanie operacji na plikach.
File
bibliotece z C # jest, jak wiemy, File
klasa może być po prostu fasadą, umieszczając wszystkie operacje na plikach w jednym miejscu - w klasie, ale może wewnętrznie używać podobnych klas do odczytu / zapisu do twojej, co by faktycznie zawierają bardziej skomplikowaną logikę do obsługi plików. Taka klasa File
nadal przestrzegałaby SRP, ponieważ proces faktycznej pracy z systemem plików zostałby zaabsorbowany za inną warstwą - najprawdopodobniej z interfejsem ujednolicającym. Nie mówię, że tak jest, ale może być. :)