W jaki sposób posiadanie zbyt wielu zmiennych instancji prowadzi do duplikowania kodu?

19

Zgodnie z refaktoryzacją do wzorów :

Gdy klasa próbuje zrobić zbyt wiele, często pojawia się jako zbyt wiele zmiennych instancji. Gdy klasa ma zbyt wiele zmiennych instancji, zduplikowany kod nie może być daleko w tyle.

W jaki sposób posiadanie zbyt wielu zmiennych instancji prowadzi do duplikowania kodu?

q126y
źródło
2
Mówiąc prosto: nzmienne boolowskie na przykład tworzą wewnętrzną przestrzeń stanu 2^n. Najczęściej twój obiekt nie ma tak wielu obserwowalnych stanów , ale ponieważ wcisnąłeś cały ten stan w jeden obiekt, wewnętrznie nadal musisz sobie z nimi poradzić.
biziclop,

Odpowiedzi:

23

Posiadanie zbyt wielu zmiennych instancji nie jest bezpośrednio związane ze zduplikowanym kodem i odwrotnie. To stwierdzenie, w tej ogólności, jest fałszywe. Można wrzucić dwie osobne klasy bez zduplikowanego kodu w jedną klasę - co tworzy nową klasę z nieoddzielnymi obowiązkami i zbyt wieloma zmiennymi instancji, ale nadal nie ma zduplikowanego kodu.

Ale kiedy znajdziesz klasę ze zbyt dużą odpowiedzialnością w starszym kodzie, istnieje duże prawdopodobieństwo, że programista, który ją napisał, nie dbał o czysty kod lub zasady SOLID (przynajmniej nie w czasie, gdy pisał ten kod), więc jego nie jest mało prawdopodobne, że znajdziesz tam inny zapach pachnący jak zduplikowany kod.

Na przykład anty-wzorzec „kopiuj i wklej ponownie” jest często stosowany, kopiując starą metodę i wprowadzając do niej niewielkie modyfikacje, bez odpowiedniego refaktoryzacji. Czasami, aby to zadziałało, trzeba zduplikować zmienną składową i nieco ją zmodyfikować. Może to skutkować klasą ze zbyt wieloma zmiennymi instancji (bardziej precyzyjnie: zbyt wiele bardzo podobnych zmiennych instancji). W takiej sytuacji podobne zmienne instancji mogą być wskaźnikiem powtarzającego się kodu w innym miejscu klasy. Jednakże, jak zauważyłeś, jest to sztuczny przykład i nie wyciągnę z niego ogólnej reguły.

Doktor Brown
źródło
11

Zbyt wiele zmiennych instancji oznacza zbyt wiele stanów. Zbyt dużo stanów prowadzi do powielania kodu, który jest tylko nieco inny dla każdego ze stanów.

Jest to klasyczna pojedyncza konkretna klasa, która robi zbyt wiele rzeczy, które powinny być podklasami lub kompozycjami.

Znajdź kilka klas, które mają zbyt wiele zmiennych instancji, zobaczysz, że utrzymują zdecydowanie za dużo stanu i mają wiele zduplikowanych ścieżek kodu, które są tylko nieznacznie wyspecjalizowane dla każdego przypadku, ale są tak skomplikowane, że nie można ich rozdzielić na metody wielokrotnego użytku. Jest to również jedno z największych źródeł side effects.

Istnieje co najmniej jeden wyjątek, który nie należy do tej kategorii i jest łatwym sposobem zaradzenia temu. Immutableobiekty nie mają tego problemu, ponieważ są w stanie stałym, nie ma szans na zawiłe zarządzanie stanem ani na skutki uboczne.


źródło
7

Cytowane przez Ciebie stwierdzenie powinno być postrzegane w określonym kontekście.

Zgodnie z moim doświadczeniem nie mogę potwierdzić, że „wiele zmiennych instancji ogólnie wskazuje na powielony kod”. Zwróć też uwagę, że należy to do „zapachów kodowych” i istnieją rzekomo sprzeczne zapachy. Spójrz tutaj:

http://c2.com/cgi/wiki?CodeSmell

Zabawne jest, że „zbyt wiele zmiennych instancji” ma tak dobry zapach w kodzie, jak „zbyt mało zmiennych instancji”.

Ale występują problemy ze zmiennymi instancji, czy to za mało, czy za dużo:

  1. Każda zmienna instancji może oznaczać pewien rodzaj statusu obiektu. Stati zawsze wymagają starannego leczenia. Musisz upewnić się, że pokryłeś wszystkie możliwe kombinacje statystyk, aby uniknąć nieoczekiwanego zachowania. Zawsze musisz teraz jasno: jaki status ma teraz mój obiekt? Z tego punktu widzenia wiele zmiennych instancji może wskazywać, że klasa stała się niemożliwa do utrzymania. Może to również wskazywać, że klasa wykonuje zbyt wiele zadań, ponieważ potrzebuje tak wielu statystyk.

  2. Każda zmienna instancji wymaga nadzoru, które metody zmieniają zmienną w jaki sposób. Nagle nie znasz już wszystkich kucharzy, którzy gotują. Jeden z nich, zaprogramowany ze zmęczeniem późną nocą, zepsuje twoją zupę. Znowu: zbyt wiele takich zmiennych spowoduje, że kod będzie trudny do penetracji.

  3. Druga strona: zbyt mało zmiennych instancji może powodować, że wiele metod musi obsługiwać informacje przy zbyt dużej ilości pracy i przy zbyt dużej liczbie parametrów. Czujesz to, jeśli nadajesz wielu swoim metodom pewien równy parametr, a wszystkie metody robią w ten sposób bardzo podobną rzecz. W takiej sytuacji kod zacznie się wzdęcia. Skończysz przewijanie wielu ekranów w górę i w dół, aby zebrać kilka prostych rzeczy. Tutaj refaktoryzacja może pomóc: wprowadzić jedną zmienną instancji i jedno jasne wejście do niej. Następnie uwolnij wszystkie metody.

  4. I na koniec: jeśli wiele zmiennych instancji klasy ma swój ustawiacz i getter, może to oznaczać, że inne klasy nie używają tej pierwszej klasy we właściwy sposób. Toczy się dyskusja na temat „ Dlaczego pobożni i rozgrywający są źli ”. Krótko mówiąc, jeśli klasa Rectangleoferuje kilka getX(), a korzysta z niej wiele innych klas rectangle.getX(), piszesz kod, który nie jest odporny na „efekt falowania” (jak daleko jest zmiana kodu wpływająca na inny kod). Po prostu zapytaj, co się stanie, jeśli zmienisz typ z intna double? Zgodnie z tą dyskusją wiele rectangle.getX()połączeń powinno w rzeczywistości być lepszymirectanlge.calculateThisThingForMe(). Tak więc, bardzo pośrednio, zduplikowany kod może wyłonić się z wielu zmiennych instancji, ponieważ wiele klas wokół używa wielu pobierających i ustawiających wykonujących bardzo podobne rzeczy, tj. Kopiowane rzeczy, które powinny być lepiej przenoszone wewnątrz klasy.

Wiele lub kilka zmiennych instancji pozostaje stałym kompromisem, zmieniając oba sposoby w trakcie rozwoju oprogramowania.

peter_the_oak
źródło
Cytat R-to-P jest zbyt ogólny i dlatego podoba mi się ta odpowiedź. Odejmuję to: jeśli ujawnimy wystarczającą liczbę właściwości, klient może i będzie je brać i pisać własną wersję danej funkcjonalności - # 4 powyżej. Problem może sięgać tak głęboko, jak skład obiektu - patrz nr 2: Widzę to zbyt często w naszym kodzie. (a) „dlaczego nie użyli klasy <wszystko> (aby skorygować część tego niezorganizowanego stanu)?” lub (b) „Dlaczego nie stworzyli nowej klasy? Nie mogę tego wszystkiego śledzić”. I z pewnością mamy kilka klas wewnętrznie duplikujących funkcjonalność z powodu braku spójnej klasy.
radarbob,
6

Mówiąc prosto: słaba separacja problemów w kodzie, prowadzi do kodu, który nie jest modułowy, prowadzi do słabego ponownego użycia, prowadzi do duplikacji kodu.

Jeśli nigdy nie spróbujesz powtórzyć funkcji, nie otrzymasz duplikatu kodu, a wiele zmiennych instancji nie będzie problemem.

Jeśli spróbujesz powtórzyć funkcjonalność, kodu monolitycznego, który nie jest modułowy, nie można ponownie użyć. Robi za dużo i może robić tylko to, co robi. Aby zrobić coś podobnego, ale nie tego samego, łatwiej jest wycinać i wklejać niż rozbijać monolityczny kod. Programiści z doświadczenia wiedzą, że powielony kod to droga do piekła.

Tak więc chociaż sama zmienna instancji nie jest główną przyczyną problemu, to silny „zapach”, że problem nadchodzi.

Język „nie może być daleko w tyle” jest słabszy niż stwierdzenie „z pewnością trzeba iść za”, więc autor nie twierdzi, że tak się musi stać, ale w końcu się wydarzy; jeśli chcesz ponownie użyć funkcji, ale nie możesz, ponieważ kod nie jest modułowy.

simbo1905
źródło