Wspolna klasa bazowa dla wspolnego kodu czy copy/paste?

0

Mam taka sytuacje, prosze o Wasze zdanie: sa 2 klasy, ktore maja pare metod o takiej samej sygnaturze, kod w nich jest w znacznym stopniu taki sam, plus jedna metoda robi cos dodatkowo w jednym miejscu, a druga w innym, w srodku metody (nie da sie przeniesc na poczatek lub na koniec, przestanie dzialac). Dodam ze nie jest to zadne API uzywane przez inne firmy / zespoly, to klasy tylko i wylacznie w naszej aplikacji. Ilosc tego kodu to jeden ekan, razem z komentarzami (niewiele), definicjami metod i importami.
Podejscie 1: moge wygmerac z tego wspolna klase bazowa, ktora bedzie trzymac wspolny kod, dodac pare metod ktore podklasy musza zaimplementowac i ich wywolania wstawic w strategiczne miejsca wspomnianych wyzej metod. Kilka metod musze wyodrebnic jako pomocnicze, ktore wlasciwe implementacje moga wolac, ale jako ze jezyk w ktorym to jest pisane (Objective C) nie ma protected, beda one musialy byc w naglowku czyli publiczne, czyli zabrudza interfejs. (Sa i na to sposoby, ale to wprowadziloby jeszcze wiecej komplikacji kodu.)
Podejscie 2: zostaje jak jest, czyli troche kodu skopiowane w obu klasach, pare metod identycznych, pare troszke sie rozniacych. Kod prosty bez zadnej magii.

Na pierwszy rzut oka podejscie 1 wydaje sie znacznie lepsze / poprawne, a podejscie 2 beznadziejne (copy/paste?), jednakze podejscie 1 znacznie skomplikowaloby dosc prosty kod. Jest go tez dosc malo.

Jakie jest Wasze zdanie? Refactoring i klasa bazowa no matter what, czy macie jakies dopuszczalne limity?

0

Może Template Method?

0

No tak, to jest wlasnie to podejscie ktore opisalem tylko nie podalem nazwy. I problem jest taki, ze np. pewna metoda wydladalaby tak:

wspolny kod
wspolny kod

metodaDoNadpisaniaA()

wspolny kod
wspolny kod

metodaDoNadpisaniaB()

wspolny kod
wspolny kod

w innej kolejnosc bylaby inna. Wlasnie to jest to co mam na mysli mowiac o 'komplikacji' kodu. Dla tych metod nie potrafilbym nawet znalezc dobrych generycznych nazw. Dodatkowo, klasa A mialaby jedna polowe tych metod do nadpisania pusta, a klasa B druga.

0

Niech sobie będą puste. Ważne, żeby nie kopiować wspólnego kodu, bo dzięki temu zmniejszasz szanse wystąpienia błędu.

0

Ogolnie to zgadzam sie z tym, tylko ten przypadek jakos mi smierdzi. Mam wrazenie, ze bedzie to robione na sile, nawtykane pelno jakichs dziwnych metod a'la template method pattern i caly kod bedzie skomplikowany. Tego wspolnego kodu jest tez nie az tak wiele. Mialem raczej nadzieje, ze powiecie cos w stylu 'no ok, sa przypadki ze copy paste nie jest taki zly'. Nigdy tego nie robicie? Nigdy?

0

Trochę wspólnego kodu, czyli ile? Jeśli to są trzy linijki, to można zostawić. Jeśli 50, to już nie.

0

Prawdziwego kodu jest 30-pare linijek, plus deklaracje metod itp. Patrzylem co sie stanei jak zrobie klase bazowa i dodam te metody do nadpisania, to kodu bedzie w sumie 2 razy wiecej.

0

Podstawowe pytanie - czy te klasy logicznie reprezentują to samo, tylko różnią się szczegółami zachowania? Bo jeśli służą do różnych celów, reprezentują różne byty, a tylko przez przypadek mają trochę wspólnego kodu, to ja bym wydzielił ten wspólny kod do czegoś trzeciego i niezależnie wywołał z tych klas, ale nie dziedziczył po jednej klasie bazowej. Czyli użyłbym kompozycji a nie dziedziczenia.

0

Dam zatem wiecej informacji. Jest to projekt iOS, gdzie jak wiadomo sa ekrany itp. Aplikacja nie wyglada jak standardowa aplikacja iOS, nie uzywa rowniez systemowych popupow itp. Zamiast tego, mamy 2 radzaje popupow: modal dialogi i 'overlaye'.
Modalne dialogi przykrywaja prawie caly ekran (ogolnie, wszystko w aplikacji jest dosc duze, ona ma byc uzywana przez kierowce samochodu, wiec musi byc latwo trafic w przyciski itp.), i ich funkcjonalnosc widoczna na zewnatrz to pokazanie (z animacja fade-in lub bez), zamkniecie (fade-out lub bez), oraz mozna zainstalowac w nich tzw. dialog delagate (ci co programuja na iOS wiedza o co biega, dla tych co nie - to powiedzmy jakby listener, ale moze byc tylko jeden), ktory ma callbacki wywolywane zaraz przed zamknieciem i zaraz po zamknieciu, wraz z informacja co bylo przyczyna zamkniecia (ok, cancel, close, etc.). Ma metode close oraz closeWithReason(reason), i ten reason jest przekazywany do delegata.
Overlaye rowniez przykrywaja caly ekran, ale inaczej - jest to po prostu taki jakby lightbox, czarny kolor z alpha 0.8, z jakims tekstem posrodku, ktory informuje dlaczego dany ekran nie moze czegostam wykonac (np. nie mozemy pokazac informacji o RPM silnika jesli silnik jest wylaczony...). Dodatkowo, overlaye moga pozwolic zeby pewne guziki z ekranu ktory przykrywaja dalo sie kliknac. Takie guziki i inne kontrolki jakby 'przeswituja' przez overlay. Overlaye mozna pokazac i zamknac (rowniez fade-in, fade-out), ale tylko programistycznie, uzytkownik nie moze tego zrobic; nie maja zadnego delegata.
Istnieje tez troszke kodu pomocniczego, ktory pozwala spytac czy dany dialog/overlay jest aktualnie widoczny, oraz usuwanie go z 'hostujacego' ekranu itp. Niewiele w sumie tego, ze 3 metody. Do tego kod animacji fade-in i fade-out.

Jak wiec widac, sa to dosc zblizone rzeczy i pomysl byl taki, zeby wyodrebnic klase Popup, z niej dziedziczy Dialog oraz Overlay i tylko nadpisac / rozszerzyc pewne metody. Nawet zrefaktorowalem ten kod i zrobilem to co chcialem, ale wynik byl duzo bardziej skomplikowany niz aktualny prymitywny kod, rzeklbym: clumsy. Jakies metody z d**y ktore klasy musza nadpisac, metody ktore teraz sa proste nagle zrobily sie bardziej skompilkowane (zazwyczaj tak jest ze zrobienie czegos generycznym i elastycznym robi kod trudniejszym, takie moje doswiadczenia), jak juz wspomnialem, w Obj-C normalnie nie ma czegos takiego jak metody protected, a wiec musialem zrobic pewne metody public, i zasmiecaja interfejs itp. itd.
Ostatecznie, podjalem decyzje zostawic to jak jest i nie wyodrebniac wspolnej klasy bazowej. Raz, ze tego kodu wiele nie jest; dwa, ze to tylko 2 klasy, i jakbym mial zrobic jakis trzeci typ popupu to na bank ten kod generyczny i tak by nie pasowal, trzeba by znowu 'ugenerycznic'. Uznalem ze szkoda zachodu i z pelna swiadomoscia stwierdzam, ze moim zdaniem w tym wypadku copy-paste jest zwyczajnie prostszym, lepszym rozwiazaniem. Bede sie smalil w programistycznym piekle?

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