Sprzężenie kodu wprowadzone przez DRY i OOD

14

Szukam wskazówek na temat łączenia DRY vs Code. Nie lubię powielać mojego kodu, a także nie lubię łączenia kodu między niepowiązanymi modułami. Dlatego zmieniam kod zduplikowanego kodu, jeśli znajdę identycznie zduplikowany kod rok po wprowadzeniu duplikacji. Jednak coraz częściej doświadczam sytuacji, w których świat rzeczywisty jest znacznie bardziej nieprzewidywalny, a po przeredagowaniu kodu pojawiają się sytuacje, które wymagają ponownego wykasowania kodu.

Na przykład, jeśli miałem kod do obsługi samochodów z benzyną, SUV-ów z benzyną, samochodów elektrycznych i SUV-ów elektrycznych, powiedzmy, że przebudowałem zduplikowany kod do hierarchii „benzyny” i hierarchii „elektrycznej”, obie pochodzące z hierarchii „pojazdu”. Jak na razie dobrze. A potem moja firma wprowadza samochód hybrydowy i hybrydowy Semi - które wymagałyby zasadniczych zmian w mojej oryginalnej hierarchii. Być może wymagałoby to „składu” między benzyną a hierarchiami elektrycznymi.

Wyraźne powielanie kodu jest złe, ponieważ wydłuża czas potrzebny na wdrożenie zmiany wspólnej dla wszystkich powyższych produktów. Ale refaktoryzacja wspólnego kodu sprawia, że ​​równie trudno jest wprowadzić odmiany specyficzne dla produktu i prowadzi do wielu „skoków klas”, gdy trzeba znaleźć linię kodu, aby naprawić błąd - jedna zmiana w klasie nadrzędnej wyższego poziomu mogłaby wywołać błędy regresji wyzwalacza wśród wszystkich potomków.

Jak znaleźć optymalną równowagę między OSUSZANIEM a niepożądanym sprzężeniem kodu?

użytkownik2549686
źródło
1
Zawsze dobrze jest nie ślepo przestrzegać zasad, ale najpierw angażować mózg.
gnasher729
dość uczciwe - stąd wytyczne, a nie zasady.
user2549686
Czy czytałeś stronę Wiki na DRY (lub OAOO, jak to się kiedyś nazywało)? wiki.c2.com/?OnceAndOnlyOnce Tam właśnie odbyło się wiele wstępnych dyskusji na ten temat. (Właściwie Ward wynalazł Wiki specjalnie do dyskusji na temat Wzorów i Praktyk.)
Jörg W Mittag
Bardzo powiązane odpowiedzi, nawet jeśli pytanie nie brzmi jak duplikat: softwareengineering.stackexchange.com/questions/300043/…
Hulk

Odpowiedzi:

8

powiedzmy, że zrefakturowałem zduplikowany kod do hierarchii „benzyny” i hierarchii „elektrycznej”, obie pochodzące z hierarchii „pojazdu”. Jak na razie dobrze.

A potem moja firma wprowadza samochód hybrydowy i hybrydowy Semi - które wymagałyby zasadniczych zmian w mojej oryginalnej hierarchii. Być może wymagałoby to „składu” między benzyną a hierarchiami elektrycznymi

Myślę, że jest to jeden z głównych powodów, dla których ludzie idą w kierunku kompozycji zamiast dziedziczenia.

Dziedziczenie zmusza cię do wielkiej restrukturyzacji, gdy masz konceptualną zmianę, taką jak ta, którą opisujesz.

Kiedy restrukturyzacja jest „zbyt duża / trudna”, ludzie piszą zduplikowany kod, aby tego uniknąć.

Zamiast zdalnie duplikować, przenosząc kod w górę łańcucha dziedziczenia, możesz przenieść go do klasy pomocniczej lub usługi, a następnie wstrzyknąć tę klasę jako część kompozycji, jeśli jest to wymagane.

To, czy powstały projekt jest OOP, jest przedmiotem dyskusji

Ewan
źródło
1
+1 za wskazanie, że problemem jest dziedziczenie, a nie OSUSZANIE. Najłatwiejszym sposobem ponownego wykorzystania kodu jest usunięcie niepotrzebnych zależności, a zbyt często ludzie pomijają fakt, że klasa nadrzędna (i jej potomkowie) są zależnościami podczas korzystania z dziedziczenia. Tylko wtedy, gdy zmniejszysz lub wyeliminujesz zależności, faktycznie otrzymasz kod wielokrotnego użytku.
Greg Burghardt
3
To, czy powstały projekt jest OOP, jest przedmiotem dyskusji ”. Wszystko jest otwarte na debatę. Pytanie, które należy zadać, to: czy jest otwarta na rozsądną, racjonalną debatę? Odpowiedź brzmi nie. Myślę, że twój ostatni akapit odwraca uwagę od bardzo dobrej odpowiedzi.
David Arno
@davidarno nie podążam za tobą, czytam OOD w tytule jako Object Orientated Design? więc odpowiadam na to pytanie bez zastanawiania się podczas debaty
Ewan
1
@Ewan: Jestem tu z Davidem Arno. Wydaje mi się, że od ponad dwóch dekad wiadomo, że „jeśli nie ma dziedzictwa, to nie jest to OOP” jest błędem.
Doc Brown
Jezu, właśnie tego rodzaju dyskusji starałem się uniknąć. są poglądy po obu stronach, nie ma ostatecznej odpowiedzi
Ewan
3

Masz rację, postępując zgodnie z zasadą OSUSZANIA, możesz zwiększyć sprzężenie między niepowiązanymi w inny sposób modułami. Szczególnie w większych systemach oprogramowania może to prowadzić do sytuacji, w których nieprzestrzeganie DRY może być lepszą alternatywą.

Niestety, twój przykład nie nadaje się do wykazania tego - opisane tam problemy są spowodowane klasycznymi błędami niewłaściwego nieoptymalnego wykorzystania dziedziczenia. Jednak w przypadku tego, co napisałem powyżej, nie ma znaczenia, czy przekodujesz wspólny kod do wspólnej klasy podstawowej, czy do klasy pomocniczej (kompozycji). W obu przypadkach można być zmuszonym do umieszczenia wspólnego kodu w bibliotece L i odwołania się do tej biblioteki z dwóch wcześniej niepowiązanych programów A i B.

Załóżmy, że A i B były wcześniej zupełnie niezwiązane, mogą być wersjonowane, wydawane i wdrażane niezależnie. Jednak umieszczając wspólny kod we wspólnej bibliotece L, nowe wymagania dla A mogą wywoływać zmiany w L, co może teraz powodować zmiany w B. Tak więc powoduje to konieczność przeprowadzenia dodatkowych testów i prawdopodobnie nowej wersji i cyklu wdrażania dla B.

Jak więc poradzić sobie z tą sytuacją, jeśli nie chcesz zrezygnować z zasady OSUSZANIA? Istnieje kilka dobrze znanych taktyk:

  1. Zachowaj A, B i L jako część tego samego produktu, z jednym wspólnym numerem wersji, wspólnym procesem kompilacji, wydania i wdrożenia, o wysokim stopniu automatyzacji

  2. lub uczynić L samodzielnym produktem, z mniejszymi numerami wersji (bez niezgodnych zmian) i głównymi numerami wersji (być może zawierającymi przełomowe zmiany), i pozwól, aby A i B pozwoliły każdemu na odniesienie się do innej linii wersji L.

  3. Uczyń L tak SOLIDNY ​​jak to możliwe i dbaj o kompatybilność wsteczną. Im więcej modułów w L może być ponownie użytych bez modyfikacji (OCP), tym rzadziej wystąpią przełamujące zmiany. Inne zasady zawarte w „SOLID” pomagają w osiągnięciu tego celu.

  4. Używaj testów automatycznych szczególnie dla L, ale także dla A i B.

  5. Uważaj, co wkładasz w L. Logika biznesowa, która powinna istnieć tylko w jednym miejscu w systemie, jest dobrym kandydatem. Rzeczy, które po prostu „wyglądają podobnie” i mogą się różnić w przyszłości, są złymi kandydatami.

Należy zauważyć, że gdy A i B są opracowywane, utrzymywane i ewoluowane przez różne, niepowiązane ze sobą zespoły, zasada DRY staje się mniej ważna - DRY dotyczy możliwości konserwacji i rozwoju, ale pozwolenie dwóm różnym zespołom na indywidualne utrzymanie może być czasem bardziej skuteczne niż wiązanie ich produktów razem z powodu odrobiny ponownego użycia.

Ostatecznie jest to kompromis. Jeśli chcesz stosować zasadę DRY w większych systemach, musisz włożyć dużo więcej wysiłku w tworzenie solidnych komponentów wielokrotnego użytku - zwykle więcej niż się spodziewasz. Musisz ufać swojemu osądowi, kiedy jest tego warty, a kiedy nie.

Doktor Brown
źródło
1

SUSZENIE to kolejna reguła strukturalna. Oznacza to, że jeśli doprowadzisz go do skrajności, będzie tak źle, jakbyś go zignorował. Oto metafora, która wyciągnie cię ze strukturalnego zestawu umysłów.

Kochajcie swoje bliźniaki. Zabij klony.

Kiedy ślepo kopiujesz i wklejasz, aby uniknąć pisania na klawiaturze, bezmyślnie tworzysz klony. Pewnie robią, co chcesz, ale obciążają cię, ponieważ zmiana tego zachowania jest tak droga.

Kiedy reprodukujesz identyczne zachowanie z identycznym kodem z powodu innej odpowiedzialności, dzieje się tak, że masz taką samą potrzebę, ale może to podlegać różnym zmianom, masz bliźniaka, który powinien mieć swobodę zmiany i rozwijać się jako jednostka z upływem czasu.

Możesz skanować ich DNA (kod) według własnego uznania. Klony i bliźniaki są trudne do odróżnienia, jeśli wszystko, co robisz, to na nie patrzeć. Musisz zrozumieć kontekst, w którym żyją. Dlaczego się urodzili. Jaki będzie ich ostateczny los.

Powiedzmy, że pracujesz dla firmy ABC. Jest prowadzony przez trzech dyrektorów firmy, A, B i C. Wszyscy chcą, abyś tworzył oprogramowanie, ale każdy z nich ma swój dział. Wszyscy chcą, żebyś zaczął od drobnych. Po prostu wyślij na razie prosty komunikat. Więc piszesz „Hello World”.

Nienawidzi tego, chce, żebyś umieścił tam nazwę firmy.

B uwielbia to, chce, abyś zostawił to w spokoju i dodał nazwę firmy na ekranie powitalnym.

C chce tylko kalkulatora i pomyślał, że wiadomość jest tylko sposobem na rozpoczęcie pracy.

Jedno jest pewne, że ci faceci mają bardzo różne wyobrażenia na temat tego projektu. Czasami się zgodzą. Czasami pociągną cię w różnych kierunkach.

Kiedy duplikujesz kod, ponieważ tworzysz możliwość jego niezależnego zmieniania, tworzysz bliźniak. Kiedy powielasz kod, ponieważ pisanie jest trudne, a kopiowanie i wklejanie jest łatwe, tworzysz złe klony.

A, B i C to różne wzorce, które musi obsługiwać Twój kod. Żaden wiersz kodu nie może długo obsługiwać więcej niż jednego wzorca.

candied_orange
źródło
Przede wszystkim bardzo dziękuję wszystkim za wszystkie komentarze.
user2549686,