Przedwczesne wprowadzanie złożoności poprzez wdrażanie wzorców projektowych przed ich użyciem nie jest dobrą praktyką.
Ale jeśli zastosujesz się do wszystkich (lub nawet większości) zasad SOLID i zastosujesz wspólne wzorce projektowe, wprowadzisz trochę złożoności w miarę dodawania lub zmieniania funkcji i wymagań, aby zachować łatwość konserwacji i elastyczność w razie potrzeby.
Jednak kiedy ta złożoność zostanie wprowadzona i działa jak mistrz, kiedy ją usuniesz?
Przykład. Mam aplikację napisaną dla klienta. Pierwotnie stworzony tam, gdzie istnieje kilka sposobów na podwyżki dla pracowników. Użyłem wzorca strategii i fabryki, aby cały proces był ładny i czysty. Z biegiem czasu niektóre metody podnoszenia zostały dodane lub usunięte przez właściciela aplikacji.
Czas płynie, a nowy właściciel przejmuje kontrolę. Ten nowy właściciel ma twardy nos, wszystko jest proste i ma tylko jeden sposób na podbicie.
Złożoność wymagana przez wzorzec strategii nie jest już potrzebna. Gdybym wiedział, gdzie to kodować z obecnych wymagań, nie wprowadziłbym tej dodatkowej złożoności (ale upewnij się, że mógłbym wprowadzić ją przy niewielkiej lub żadnej pracy, jeśli zajdzie taka potrzeba).
Czy mogę teraz usunąć wdrożenie strategii? Nie sądzę, aby ten nowy właściciel kiedykolwiek zmienił sposób przyznawania podwyżek. Ale sama aplikacja wykazała, że może się to zdarzyć.
Oczywiście jest to tylko jeden przykład w aplikacji, w której nowy właściciel przejmuje i upraszcza wiele procesów. Mogłem usunąć dziesiątki klas, interfejsów i fabryk i uprościć całą aplikację. Zauważ, że obecna implementacja działa dobrze, a właściciel jest z niej zadowolony (i zdziwiony, a nawet bardziej szczęśliwy, że mogłem tak szybko wprowadzić jej zmiany z powodu omawianej złożoności).
Przyznaję, że niewielka część tych wątpliwości wynika z tego, że jest wysoce prawdopodobne, że nowy właściciel już mnie nie wykorzysta. Nie obchodzi mnie to, że ktoś to przejmie, ponieważ nie był to duży generator dochodów.
Ale dbam o 2 (powiązane) rzeczy
Obchodzi mnie trochę, że nowy opiekun będzie musiał przemyśleć nieco trudniej, próbując zrozumieć kod. Złożoność jest złożonością i nie chcę rozgniewać psycho-maniaka, który mnie ściga.
Ale jeszcze bardziej martwię się o to, że konkurencja widzi tę złożoność i myślę, że po prostu wdrażam wzorce projektowe, aby wypełnić moje godziny pracy. Następnie rozpowszechniam tę pogłoskę, aby zaszkodzić mojej drugiej firmie. (Słyszałem o tym.)
Więc...
Ogólnie rzecz biorąc, czy wcześniej potrzebna złożoność powinna zostać usunięta, nawet jeśli działa, a historycznie wykazano potrzebę złożoności, ale nie masz żadnych wskazówek, że będzie ona potrzebna w przyszłości?
Nawet jeśli odpowiedź na powyższe pytanie brzmi „nie”, czy mądrze jest usunąć tę „niepotrzebną” złożoność, przekazując projekt konkurentowi (lub nieznajomemu)?
źródło
Często mówi się: „Jeśli się nie zepsuło, nie naprawiaj go”.
Za tą regułą kryje się kilka uzasadnień. Niektóre z nich mogą polegać na tym, że „uproszczenie” grozi wprowadzeniem nowych, różnych i być może większych błędów, może zająć coraz więcej czasu na rozwój od innych cenniejszych przedsięwzięć i może być całkowicie niewłaściwą zmianą w przypadku nieoczekiwanej przyszłej okazji biznesowej, która powstaje.
Jeśli istnieje wystarczająca wartość biznesowa, aby ten kod był przenośny i łatwiejszy w utrzymaniu, zdecyduj, czy ta wartość jest naprawdę wystarczająca, aby uznać obecny kod za „uszkodzony”. Może tak być, jeśli planowana jest duża ekspansja biznesowa lub podejrzewasz ukryty błąd ukryty w złożoności, który może doprowadzić do upadku firmy.
źródło
Przede wszystkim, jeśli aplikacja została już raz przejęta przez nowego właściciela, może się to powtórzyć. I kolejny właściciel może znów zacząć korzystać ze złożoności, z której obecnie nie korzysta.
Poza tym nietrywialne zmiany w działającym kodzie zawsze pociągają za sobą ryzyko, dlatego (jak zauważyli inni) klient powinien się z nimi zgodzić (i za nie zapłacić). Jeśli obecna „dodatkowa” złożoność nie powoduje zauważalnej, mierzalnej wady (takiej jak problemy z wydajnością), nie ma silnego powodu, aby ją usunąć.
(Potencjalni) klienci, którzy (nie) zatrudniają cię wyłącznie na podstawie plotek konkurencji, i tak nie są tego warte, chyba że desperacko potrzebujesz dochodu. Masz dobre i logiczne powody, dla których wdrożyłeś aplikację tak, jak to zrobiłeś, i każdy poważny klient może to zrozumieć. Ktoś, kto nie zadaje ci pytania - lub nawet nie zadaje sobie trudu - prawdopodobnie sprawi ci po drodze więcej kłopotów niż praca.
źródło
Nie.
Nie. Po co marnować czas na naprawę niskiego priorytetu? Brak szkody dla kodu tam pozostającego.
Co do pytania: kiedy należy usunąć złożoność?
Uważam, że jeśli się nie zepsuło, nie naprawiaj tego .
źródło
Aby móc usunąć złożoność, muszą być spełnione następujące warunki:
źródło
Myślę, że działa tu coś większego ... Skalowalność
To, o czym mówisz, nazywa się skalowalnością . Nie ma znaczenia, czy kodowanie jest skomplikowane, ma znaczenie, czy aplikacja może ewoluować w oparciu o nowe reguły biznesowe lub zmienione reguły biznesowe. Co się stanie, jeśli następny właściciel chce czegoś zupełnie innego.
Mówię więc: zachowaj kod i udokumentuj go. Jest to funkcja, z której można korzystać z aplikacji.
źródło
Usunięcie złożoności wymaga wysiłku i ryzyka. Jeśli jest to więcej niż dodatkowy wysiłek i ryzyko związane z utrzymaniem zbyt złożonego kodu, należy go zachować. W przeciwnym razie usuniesz go. Trudno jednak oszacować te ryzyko.
Dodam, że można zmniejszyć ryzyko trudniejszej konserwacji, dokumentując, dlaczego w kodzie użyto strategii wzorca projektowego. Osobiście uważam, że każdy wzorzec projektowy powinien być identyfikowalny z wyraźnym wymogiem (funkcjonalnym lub niefunkcjonalnym).
Twój scenariusz rezygnacji z rywalizacji o godziny wypełnienia jest właśnie powodem, dla którego powinieneś udokumentować złożoność. Jeśli udokumentujesz i uzasadnisz (z konkretnymi wymaganiami klienta) użycie dowolnego wzoru, jesteś objęty ubezpieczeniem. Jeśli nie możesz usprawiedliwić wzoru wymaganiem klienta, wygląda to na nadprojekt lub zapalenie wzoru.
Jeśli wymagania się zmienią, możesz uzasadnić pozostawienie go ze względu na ryzyko złamania kodu (lub nakładu pracy, aby chirurgicznie usunąć wzór).
Myślę, że dobrze jest rozróżnić przypadkową złożoność od zasadniczej złożoności , ponieważ wzorce często obejmują oba.
Oznacza to, że wymóg obsługi różnych algorytmów przy podejmowaniu decyzji o podwyżce jest istotną złożonością (część problemu do rozwiązania). Utrzymanie swojego kodu jest ułatwione przez wzorzec strategii, ale zakodowane jeśli / wtedy alternatywą dla strategii nadal będzie działać. Przeprowadziłem ćwiczenia na kursach magisterskich, w których studenci znajdują możliwości zastosowania strategii w projektach typu open source. Złożoność niekoniecznie jest lepsza / gorsza przy stosowaniu strategii (ponieważ jest to niezbędna złożoność). Czasami może być jeszcze trudniej zrozumieć strategię, ponieważ kod dzieli się na wiele klas z polimorfizmem, a nie na jeden duży blok if / then / else.
Idealnie wzór działa, gdy korzyści, które zapewnia, przewyższają koszty jego wad. Ponownie, ilościowe określenie tych rzeczy jest trudne. Często wzorzec uszczęśliwia dewelopera (nie tylko dlatego, że ułatwia dodawanie nowej strategii przebijania, ale także pozwala deweloperom na ciepłe kłótnie, aby wiedzieć, że wzór został zastosowany). Trudno jest pokazać klientom, w jaki sposób przynoszą im korzyści.
Klient nie dba o szczegóły, a nawet go nie rozumie. W przypadku nowej właścicielki stosującej KISS w swoich procesach, to redukuje istotną złożoność, która powinna mieć również wpływ na oprogramowanie.
źródło