Interfejsy nad implementacje

0

Dobrzy programiści najpierw się zastanawiają, czy potrzebne będzie dziedziczenie czy kompozycja, czy dziedziczenie w ogóle ma sens w danym przypadku - a ma go raczej w niewielu, a potem to implementują. W przeciwnym razie wychodzą albo kosmicznie koszmarne hierarchie dziedziczenia albo programowanie przez permutacje.

Wolę refaktorować kod który już istnieje niż ten który dopiero sobie wyobrażam. W ten sposób efekty są zwykle lepsze i przychodzą szybciej. Projektowanie daleko naprzód śmierdzi trochę waterfallem. Zamiast kombinować od początku, poprogramuję sobie tak jak mi wygodnie, a w momencie kiedy zorientuję się, że kompozycja ma sens to ją wprowadzam i gitara.

0

No cóż jak dla mnie kilka klas i kilka godzin naprzód to ani nie jest daleko, ani też żaden z tego waterfall.

0

Masz projekty na kilka godzin? Kompozycja może zacząć mieć sens np 5 lat po stworzeniu hierarchii klas.

2

Nie, ja nie planuję implementacji tasków, które dostanę za 5 lat, tylko aktualnego.
Nie wiem, co próbujesz udowodnić, ale robisz to chyba wbrew całej branży.

1

Świetnie że jesteś całą branżą i że podajesz przykłady. Ja tam z powodzeniem okazjonalnie zamieniam dziedziczenie na kompozycję i nie widzę problemu. Niedawno nawet zrobiłem dość ekstremalną wersję takiego refaktoru tutaj: https://github.com/tarsa/SortAlgoBox/commit/34ff7f432c6338200c9755815ee7463a62348ecd (to jest projekt hobbystyczny, więc dlatego pozwoliłem sobie załatwić wiele rzeczy jednym commitem). Miałem gotowy kod z lekką eksplozją hierarchii dziedziczenia ("zawrotne" 10 prostych klas w problematycznej hierarchii - tutaj: https://github.com/tarsa/SortAlgoBox/tree/623a8eb3e8877d047fe52f6a4ae52a4c68d5033c/core/main_scala/pl/tarsa/sortalgobox/core/common/agents ), miałem gotowych klientów do tych klas, miałem testy itd, więc miałem co analizować. Po przerobieniu na kompozycję aktualnie kod stał się bardziej skomplikowany niż wcześniej, ale bardziej elastyczny. Dorabianie kolejnych klientów rzadziej będzie wymagać rozbudowywania hierarchii klas. Mimo wszystko gdybym od razu pchał się w kompozycję to kod mógłby się stać niepotrzebnie skomplikowany, bo sposobów na uogólnianie hierarchii dziedziczenia czy kompozycji jest wiele.

Wolę podejście jak w TDD, gdzie logikę tworzy się na bieżąco, bez głębszego zastanawiania się jak kod powinien wyglądać za X-dziesiąt iteracji red-green-refactor, bo im bardziej wybiegamy w przyszłość tym mniej nasze przewidywania się pokrywają z rzeczywistością. U mnie po prostu tworzenie kodu w głowie się nie sprawdza, tak samo u większości innych ludzi i stąd mamy metodyki zwinne, zorientowane na klepanie kodu aktualnie potrzebnego, a nie potrzebnego kiedyś tam. Nie wiem jak u ciebie. Kiedyś miałeś stronkę z własnymi programami, ale chyba się ich wstydzisz. Przykładów też nie podajesz. Co ja mam niby wyciągnąć z twojego biadolenia? Widzisz gdzieś problem, a nie potrafisz go konkretnie opisać.

Reorganizację kodu po jego napisaniu stosuje się też w przypadku mikroserwisów. Najpierw rozbudowuje się istniejący mikroserwis, a potem wydziela z niego osobny, przenosząc do niego już napisany kod (przed wydzieleniem jednak przerabia się kod tak, by zminimalizować złożoność przyszłego API). No chyba, że interfejs mikroserwisu tak czy siak będzie banalny i oczywisty, to wtedy można zacząć od postawienia pustego mikroserwisu.

0
Wibowit napisał(a):

Po przerobieniu na kompozycję aktualnie kod stał się bardziej skomplikowany niż wcześniej, ale bardziej elastyczny. Dorabianie kolejnych klientów rzadziej będzie wymagać rozbudowywania hierarchii klas.

I o to głównie chodzi w używaniu kompozycji zamiast dziedziczenia, bo daje ona zwyczajnie większą elastyczność. Do tego łatwiej czyta się kod (nie trzeba skakać od rodzica do dziecka i z powrotem), nie ma też ryzyka, że w klasie bazowej znajdą się metody potrzebne tylko połowie dzieci.

U mnie po prostu tworzenie kodu w głowie się nie sprawdza, tak samo u większości innych ludzi i stąd mamy metodyki zwinne, zorientowane na klepanie kodu aktualnie potrzebnego, a nie potrzebnego kiedyś tam.

W sensie siadasz i po prostu uderzasz w klawiaturę, bez przemyślenia struktury kodu, który chcesz zaimplementować w ciągu najbliższego czasu (kilku godzin)?

Przykładów też nie podajesz. Co ja mam niby wyciągnąć z twojego biadolenia? Widzisz gdzieś problem, a nie potrafisz go konkretnie opisać.

Bo mi się aż tak znowu nie chce tłumaczyć wiedzy powszechnej. Poczytaj sobie sam: https://www.google.pl/search?q=why+inheritance+is+bad&oq=why+inheritance+is+bad

1

W sensie siadasz i po prostu uderzasz w klawiaturę, bez przemyślenia struktury kodu, który chcesz zaimplementować w ciągu najbliższego czasu (kilku godzin)?

Rzadko kiedy w ciągu kilku godzin udaje mi się wyprodukować takie hierarchie dziedziczenia, żeby był jakiś zysk z przerobienia ich na kompozycję. W zasadzie to nawet nie przypominam sobie takich sytuacji. Prędzej w ciągu kilku dni coś takiego może się zdarzyć. Ale nawet wtedy wolę refaktorować kod już po napisaniu i rozwiązaniu nieprzewidzianych problemów. Refaktor jest wtedy dość szybkim procesem.

Nie wiem jakie masz doświadczenia. Być może klepiesz jakieś proste formatki i tam jest oczywiste co trzeba zrobić w N-tej formatce. Ja często nie jestem w stanie sobie wyobrazić jak rozwiązanie zadania ma się integrować z systemem (bo nie znam danego kawałka systemu na wylot) i to dopiero w trakcie rozwiązywania wychodzi. Jak w takiej sytuacji mam zaprojektować hierarchię dziedziczenia czy kompozycji na starcie?

0

Refaktoring gównokodu jest szybszy niż pisanie dobrego kodu od razu. Uśmiałem się.

0

Refaktoring gównokodu jest szybszy niż pisanie dobrego kodu od razu. Uśmiałem się.

Pokaż mi swój kod to zobaczymy czym jest g**no.

0

@Wibowit: niepotrzebnie się unosisz

1 użytkowników online, w tym zalogowanych: 0, gości: 1