Niepisane zasady przepisywania kodu innego członka zespołu [zamknięte]


40

Praktykujemy własność zbiorowego kodu. W moim rozumieniu oznacza to, że każdy programista może zmienić dowolny wiersz kodu w celu dodania funkcjonalności, refaktoryzacji, naprawy błędów lub ulepszenia projektów.

Ale co z całkowitym przepisaniem kodu od programisty, który wciąż jest w zespole? Czy powinienem go najpierw zapytać? Jaka jest najlepsza praktyka?


5
Nie widzę żadnej szkody w usuwaniu kodu, jeśli jest to konieczne - pod warunkiem, że korzystasz z kontroli źródła. Inne odpowiedzi na to pytanie dość dobrze opisują etykę usuwania kodu innej osoby.
Anonimowy

9
Nie sądzę, aby zostało to wyraźnie wymienione w żadnej z [doskonałych] odpowiedzi: nawet jeśli istniejący kod zasługuje na przepisanie, jeśli teraz działa , bardzo prawdopodobne jest, że przepisanie go będzie stratą czasu [pieniędzy]. Nauczyłem się, że w wielu scenariuszach szybkie i brudne rozwiązanie jest właściwym rozwiązaniem. Płacisz za pisanie kodu, więc powinieneś być tak wydajny, jak to możliwe. Nie potrzebujesz dobrze zaprojektowanego frameworka do czegoś, co będzie uruchamiane tylko kilka razy. Nie chcesz poświęcić tygodnia na zrobienie czegoś, co można by zrobić w ciągu jednego dnia przy użyciu złych praktyk projektowych. Wiele razy menedżerowie wolą takie podejście.
taz

9
@taz - Jest to podstawa wzoru Big Ball of Mud ( laputan.org/mud ).
Matthew Flynn

@MatthewFlynn - Świetny artykuł. Wyrażenie „Big Ball of Mud” pojawiło się tak wiele razy, że wydawało się, że jest to doświadczenie deja vu w „Praktyce” Allana Iversona ( youtube.com/watch?v=eGDBR2L5kzI ). ;-)
Happy Green Kid Naps

3
Potrzebuje więcej kontekstu. Dlaczego zmieniasz kod, jaki jest zakres zmiany - godziny, dni, tygodnie, miesiące pracy. Kto płaci za zmianę i czy jest ona naprawdę potrzebna. Kto zatwierdza potrzebę zmiany. Co przetwarzasz i dlaczego tak bardzo się nie udało, że na początku wpadłeś w ten bałagan.
mattnz

Odpowiedzi:


62

Myślę, że dobra komunikacja jest zawsze najlepszą praktyką. Porozmawiaj z programistą i sprawdź, czy istnieje powód, dla którego kodowanie jest takie, jakie jest. Być może zamierzali wrócić i zreformować to od wieków, być może zrobili to w ten sposób z bardzo ważnego powodu, albo obaj możecie nauczyć się czegoś z rozmowy.

Wejście i przepisywanie bez uprzedniej komunikacji to przepis na złą wolę.


1
Tak, nauczyłem się z doświadczenia, że ​​niektórzy programiści mogą się bardzo denerwować, jeśli naprawicie nawet błędy w kodzie bez pytania. Oczywiście, był to projekt bez śledzenia problemów i planowania zadań, i jestem zdumiony, że kiedykolwiek został wysłany.
puszysty

+1 za „rozmowę z deweloperem” - mamy błąd (cóż, przynajmniej jeden, prawdopodobnie więcej), którego klient oczekuje teraz ... I do tej pory został pochowany, że byłem jedynym, który niejasno wiedział, dlaczego został pozostawiony sam.
Izkata,

3
Zasadniczo nie zgadzam się z „dobrą komunikacją”, ale myślę, że ta odpowiedź jest trochę banalna. Pomijając wszystkie kłopotliwe pytania o to, jakie okoliczności doprowadziły do ​​tego pytania, naprawdę nie powinno mieć najmniejszego znaczenia, czy programista odpowie „tak”, czy „nie” na pytanie „czy mam przepisać kod?”. , ponieważ niekoniecznie będzie to najlepsza odpowiedź dla zespołu lub produktu. Jasne, należy spróbować dowiedzieć się wszystkiego o oryginalnych założeniach i decyzjach, ale skąd wiemy, że OP jeszcze tego nie zrobił?
Aaronaught,

2
@Aaronaught - Pytanie, czy najpierw zapytać oryginalnego programistę, oznacza, że ​​OP jeszcze nie rozmawiał z oryginalnym programistą i dlatego nie próbował odkryć wszystkiego, co mógł. Mam nadzieję, że odpowiedź jest odwrotna do banalnej - jest fundamentalna.
Matthew Flynn

1
Jeśli faktycznie zajmujesz się zbiorowym posiadaniem kodu, masz prawo do zmiany, przepisania lub usunięcia dowolnego kodu, jeśli uznasz to za stosowne. Jest to szczególnie prawdziwe, jeśli wykonujesz programowanie w parach. Teraz, powiedziawszy to, przed poważną zmianą (jak przepisanie) kodu napisanego przez jakąś konkretną osobę, rozsądnie byłoby porozmawiać o tym z nimi. W większości przypadków, które widziałem (w tym z własnym kodem), ich odpowiedź brzmiała: „O tak, przepraszam! Ten kod jest katastrofą; po prostu nie zrobiłem tego dobrze. Oto kilka pomysłów, jak go poprawić , Proszę, biegnij z tym! "
Jeff Grigg

35

Samo założenie tego pytania budzi dla mnie szereg obaw, że nie sądzę, aby jakakolwiek z istniejących odpowiedzi należycie próbowała rozwiązać. Pozwól, że zadam ci kilka dalszych pytań:

  1. Czy jesteś absolutnie, pozytywnie pewien, że mówisz o przepisywaniu, a nie refaktoryzacji? Z definicji zmiany stylu lub struktury kodu, które skutkują ulepszoną (lub po prostu inną) implementacją bez zmian w zachowaniu zewnętrznym, są refaktorem, a nie przepisem. Złamanie monolitycznej 500-liniowej procedury na zestaw 50 podprogramów może wymagać napisania całkiem nowego kodu, ale nie jest to przepisanie. Termin przepisz oznacza wyrzucenie całego produktu lub funkcji i rozpoczęcie od nowa; nie należy tego lekceważyć.

  2. Jeśli zachowanie oryginalnego kodu jest tak błędne lub implementacja jest tak błędna, że ​​wymaga pełnoprawnego przepisania, dlaczego nie został złapany przez proces twojego zespołu i zajęty we właściwym kontekście (tj. Technicznie, a nie społecznie)? Zły lub wątpliwy kod powinien zostać szybko ujawniony zdrowemu zespołowi za pomocą testów, recenzji kodu, recenzji projektu itp. Czy masz je?

  3. Czy menedżer / kierownik techniczny jest świadomy problemu, a jeśli nie, dlaczego nie? Bez względu na to, jaki masz proces, za jakość kodu zwykle odpowiada kierownik ds. Rozwoju. Jest pierwszą osobą, o którą powinieneś zapytać - oczywiście nie w kontekście „tak i tak napisał bzdury”, ale po prostu „Myślę, że widzę tutaj poważny problem, czy możemy porozmawiać o przepisaniu?” Jeśli nie uzasadnia tego rodzaju dyskusji, to może też nie wymaga przepisania?

  4. Jeśli rozmiar i zakres szkodliwego kodu jest wystarczająco duży, aby uzasadnić poważną dyskusję na temat przepisania, dlaczego jest on własnością jednego dewelopera? Większość, jeśli nie wszystkie czasy, kiedy widziałem kod i myślałem o „przepisaniu”, zostało to zdeptane przez tuzin różnych osób, a zło jest bezpośrednim wynikiem nagromadzenia się niespójności stylowych, błędnych lub zmienionych założeń i starych dobrych modne hacki. Kod rośnie w czasie z powodu współwłasności.

    Chodzi mi o to, że to dziwne, że jedna osoba posiadałaby tak duży obszar kodu w środowisku, które podobno ćwiczy własność zbiorową. Czy inni boją się dotknąć kodu tego programisty? Czy boją się poruszyć ten temat? Być może istnieje podstawowy problem z dynamiką grupy lub konkretnie z tym deweloperem; jeśli tak, nie ignoruj ​​tego. Lub, alternatywnie, może to twój pierwszy raz pracuje nad tym projektem, a jeśli tak, to dlaczego pan myśli o przepisanie tak wcześnie w grze? Coś w tej sytuacji wydaje mi się nie pasować.

  5. Pytanie stanowi w akapicie pierwszym any developer can change any line of code to add functionality, to refactor, fix bugs or improve designs. Czy przepisywanie nie zrobi tych rzeczy? A może zrobi coś dodatkowego - a jeśli tak, to co? Zasadniczo, jakie powody, dla których chcesz przepisać i jak możesz być pewien, że przyniosą korzyści produktowi lub zespołowi? Nie musisz odpowiadać za mnie, ale lepiej, abyś miał kilka obiektywnych punktów do ustalenia, jeśli i kiedy zdecydujesz się omówić to z zespołem.

Naprawdę uważam, że na to pytanie wiąże się ogromna ilość kontekstu i nie należy na nie odpowiadać bez bardzo jasnego zrozumienia tego kontekstu. „Prawidłowa” odpowiedź całkowicie zależy od zespołu, produktu, organizacji, osobowości, procesu, zakresu oryginalnego kodu, zakresu zmian i tak dalej. Jest to, IMO, problem, który absolutnie musisz rozwiązać ze swoim zespołem , a nie na internetowej stronie pytań i odpowiedzi.


3
+1 Jedyna poprawna odpowiedź w tej dyskusji.
mattnz

Z mojego doświadczenia na temat zespołów XP posiadających zbiorowe prawa własności do kodu (i programowania w parach) jest to, że główne zmiany w projekcie lub „przepisywaniu” części systemu zwykle wymagają dyskusji z większością zespołu (wszystkich, którym to zależy). Dzięki krytycznej funkcjonalności rdzenia, istniejący projekt jest najlepszym, co zespół mógł wówczas zrobić. Jeśli nie można tego łatwo zmienić, pomocne jest zapoznanie się z pomysłami wszystkich na temat tego, co według nich należy zrobić, oraz na różne sposoby, które można poprawić. Jeśli nie możesz osiągnąć konsensusu, wypróbuj kilka „skoków” lub eksperymentów w celu zebrania informacji.
Jeff Grigg

11

Dlaczego edytujesz kod?

Czy są jakieś błędy, czy jest to bardziej podstawowa wada projektowa?

W pierwszym przypadku martwię się o przepisanie w celu naprawienia drobnych błędów w kodzie.

W tym drugim przypadku, podczas gdy spodziewałem się, że „mój” kod został potencjalnie przepisany, byłbym szczęśliwy, że tak się stanie.

To jest kwestia zbiorowego posiadania kodu - kod, który piszesz, może zostać zmodyfikowany, a nawet zastąpiony, jeśli pojawi się coś lepszego.


3
To jedyna jak dotąd odpowiedź, z którą mogę się zgodzić. Jeśli coś trzeba przepisać, przepisuję to. Nie chcę nawet zobaczyć, kto był oryginalnym autorem; dlaczego powinienem? Zakładając, że są testy ( testy, prawda?), I zakładając, że ich cel jest dość jasny lub wyjaśniony przez komentarze (jeśli nie, to zdecydowanie musi iść), to dość szybko się dowiem, czy coś zepsułem. Oczywiście mówię o przepisywaniu kilku klas, a nie całego frameworka, ale jeśli przepisanie jest tak duże, to bardziej dotyczy to planowania / planowania projektu niż kwestii współwłasności.
Aaronaught,

6

Ogólnie, jeśli wszyscy zgadzacie się, że wszyscy jesteście odpowiedzialni za kod, wówczas można przepisać dowolny kod, jeśli jest to poprawa. Przedyskutuj to z innym programistą jako grzeczność. Mogą istnieć ważne powody, dla których jest napisane w określony sposób. Na poziomie osobistym wielu programistów inwestuje emocjonalnie w to, co produkuje i, jak powiedzieli inni, nie chcesz złej woli.

W szczególności zależy to nieco od dynamiki zespołu. Starszy programista, który ma zamiar przepisać kod młodszego programisty, powinien prawdopodobnie dokonać przeglądu kodu (mojej witryny) przed zwykłym przepisaniem. W ten sposób młodszy programista może uczyć się na podstawie sytuacji.


5

Tak naprawdę nie ma znaczenia, czy oryginalny programista jest w zespole, czy nie, a nawet jeśli jesteś oryginalnym programistą. Kompletne przepisanie jakiegokolwiek wspólnego kodu powinien być prowadzony przez zespół, z następujących powodów:

  • To zajmuje dużo czasu. Jeśli ktoś pracuje nad powiązaną zmianą, nie chcesz tracić czasu.
  • Inni ludzie mają inną perspektywę. Nawet jeśli programujesz 20 lat, ktoś inny może wiedzieć o interakcjach z kodem, którego rzadko dotykasz.
  • Inni programiści są „klientami” kodu źródłowego. Kod źródłowy jest napisany do czytania przez innych programistów. Mogą mieć wymagania dotyczące architektury, dane wejściowe dotyczące stylu lub żądania funkcji, których chcieli w tym kodzie, ale nie mieli czasu. Nie chcesz dokończyć refaktora tylko po to, aby dowiedzieć się, że inny programista potrzebuje refaktoryzacji w inny sposób.

4

Jak powiedział Matthew Flynn, najpierw trzeba porozmawiać z deweloperem. Początkowy programista może powiedzieć ważne rzeczy o funkcjonalności i wyjaśnić, dlaczego podano to lub inne rozwiązanie.

Ale przed refaktoryzacją lub ponownym zapisaniem kodu wykonaj kopię zapasową lub gałąź zawierającą ten kod. Jeśli stary kod działa dobrze, pozostanie szansa na jego odzyskanie.

Jeśli masz system kontroli źródła (który, jak zakładam, masz), to jeśli to możliwe, refaktoryzuj cały kod, a dopiero potem, gdy będziesz pewien, że działa poprawnie, sprawdź to.

Nie usuwaj starego kodu, przynajmniej przed upewnieniem się, że nowy kod działa poprawnie. Ale pozostawienie starego kodu na zawsze nie jest dobrą rzeczą. Sugeruję, aby usunąć kod jakiś czas później, na przykład w miesiąc po przejściu testu.


2
„Sugeruję usunięcie kodu jakiś czas później” - gdzie powinien on zostać w międzyczasie? W komentowanym bloku? Do tego służy kontrola źródła, aby zachować kopię zapasową całego zmienionego / usuniętego kodu w celu łatwego wyszukiwania, przy jednoczesnym utrzymaniu bieżącego kodu źródłowego w czystości.
dj18,

@ dj18, zwykle utrzymuję komentarz w komentarzu przez pewien czas, aby był bardziej widoczny, aby każdy, kto zajmuje się kodem, mógł zobaczyć, że został on zmodyfikowany od razu. Poza tym łatwiej jest spojrzeć w ten sposób, gdy kod jest właśnie edytowany
superM

1
To kolejna funkcja prawidłowego systemu kontroli wersji: możesz zobaczyć, kiedy zmiany zostały zaewidencjonowane, porównać wersje, aby zobaczyć dokładnie, co zmieniło się od jednego zameldowania do następnego, i powiązać komentarze z zameldowaniami, aby wyjaśnić, dlaczego wprowadzono modyfikację. Jeśli tak ważne jest, aby inni wiedzieli od razu, że fragment kodu został zmieniony, być może wyślij powiadomienie e-mailem, zamiast czekać, aż inni programiści zorientują się na twoje komentarze.
dj18,

2
Wiedza, że ​​ta odpowiedź powinna zostać uzyskana od pierwotnego programisty, powinna znajdować się w kodzie lub przynajmniej w towarzyszących komentarzach lub dokumentacji. Jeśli jest to ważna informacja, nie należy jej wyciszać w mózgu, a polityka rozwoju nie powinna tego zachęcać. A dlaczego nie usunąć starego kodu? Możesz go odzyskać, jeśli naprawdę potrzebujesz; to właśnie kontroli wersji jest za .
Aaronaught,

1
@Aaronaught: Myślę, że superM miał na myśli „tu smoki” lub „wyciągnięte wnioski”. Podczas gdy pułapki powinny być dość oczywiste dla doświadczonego programisty, subtelne wybory są mniej oczywiste i mogą nie być dobrze udokumentowane. (Zgadzam się, że to złe znaki, którymi należy się zająć.)
rwong,

2

Jaki jest jego zakres?

  • Jeśli przerabiasz kilka linii w celu zwiększenia wydajności, po prostu zrób to. Może zapytaj, czy istnieje jakieś niebezpieczeństwo wymazania subtelnego zachowania. Zgłoś zmianę podczas scrum lub e-mailem po jej zakończeniu, chyba że jest to naprawdę trywialne (poprawianie literówki).

  • Jeśli przerabiasz klasę o przyzwoitych rozmiarach, prawdopodobnie powinieneś poprosić o upewnienie się, że rozumiesz projekt / zachowanie. Poinformuj ludzi z wyprzedzeniem, aby każdy, kto może pracować w tym samym obszarze, mógł się z tobą zapoznać i skoordynować.

  • Jeśli przerabiasz większy system, zdecydowanie powinieneś współpracować ze swoim zespołem, aby uświadomić im zmiany i zaplanować projekt.


1

Jeśli są tam twoi oryginalni pisarze, skontaktuj się z nimi. Nie TYLKO etykieta, ale dodatkowe informacje, na wypadek, gdyby były przypadki lub okoliczności, o których nie jesteś świadomy. Czasami powiedzą ci coś cennego.

Mamy bezwzględną kontrolę kodu. Obecnie mam mnóstwo rzeczy, które wymagają przeglądu i konserwacji, a nawet nie mam nikogo, z kim mógłby dokonać przeglądu kodu. Poprzedni pisarze (oprócz moi) nie zawracali sobie głowy komentowaniem żadnego kodu. I odeszli z firmy. Nie ma nikogo, kto mógłby zapytać o kod.

Kiedy piszę ponownie, komentuję, komentując to, a także datę i imię / inicjały oraz powód komentowania. Komentuję nowy kod, z nazwą lub inicjałami, datą, powodem dodania itp.

Dodatkowe komentarze są umieszczane w nagłówku pakietu (er, zwykle), wskazując, jakie funkcje / procs / SQL / itp. zostały zmienione wraz z datą. Ułatwia to wyszukiwanie sekcji, które zostały zmienione, a te sekcje mają pełną dokumentację.

Komentarze są tanie. Daty będą wskaźnikiem tego, co się zmieniło, a po liczbie x (dni / zmiany / nowe zatrudnienia / wycofania) kod można wyczyścić ze starych komentarzy, a pozostała część jest nową linią bazową.


1

Z moich obserwacji wynika, że ​​ogólna praktyka: nigdy nie usuwaj kodu. Po prostu to skomentuj i zachowaj.

Moją praktyką jest komentowanie go podczas zastępowania. (Głównie w celach informacyjnych.) Następnie usuń go przy ostatnim zatwierdzeniu zmiany roboczej. (Wymaga to kontroli wersji i zrozumienia, jak cofać zmiany).

Kiedy znajduję stary skomentowany kod, próbuję go usunąć w osobnym zatwierdzeniu z odpowiednimi komentarzami. Ułatwia to przywrócenie lub sprawdzenie zmiany w razie potrzeby.

W przypadku wszystkich zmian powinieneś mieć możliwość korzystania z historii zmian w celu ustalenia programistów, którzy utworzyli kod. (Pomaga tutaj historia wersji z adnotacjami.) Skontaktuj się z nimi, jeśli to możliwe, aby zobaczyć, dlaczego kod jest taki, jaki jest. W wielu projektach czas czyszczenia po prostu nie występuje i rzeczy pozostają w tyle. Sprawdź narzędzie do śledzenia błędów, aby sprawdzić, czy istnieje zapis wymaganego czyszczenia. Czasami zmiany wymagają oczyszczenia w wersji lub dwóch później.

Jeśli zmieniasz kod, powód powinien być uzasadniony. Skontaktuj się z oryginalnym programistą, aby dowiedzieć się, dlaczego kod jest taki, jaki jest. Jeśli istnieje uzasadniony powód, aby tego nie naprawiać, dodaj komentarz wyjaśniający, dlaczego nie został naprawiony lub dlaczego nie należy go zmieniać. Pozwoli to zaoszczędzić czas następnemu deweloperowi.

Tagi takie jak FixMe, ToDo, Bug i Hack mogą być użyte do wskazania kodu, który można później zmienić. (Dopuszczalne jest oznaczanie ograniczeń jako Błąd i nie naprawianie ich, jeśli nie zostaną uruchomione w wymaganych warunkach.) Może to być błąd, jeśli program księgowania domu przepełnia się przy 20 milionach dolarów, ale nie marnowałbym dużo czasu na naprawianie to.

Zmiany w przeglądzie kodu powinny zostać wprowadzone przez pierwotnego programistę, jeśli jest to właściwe do zmodyfikowania kodu.


2
Prawie zanotowałem to, dopóki nie zobaczyłem „Następnie usuń to przy ostatnim zatwierdzeniu”.
Joshua Drake

1

Prawdopodobnie zależy to od tego, dlaczego przepisanie jest konieczne. Jeśli dzieje się tak dlatego, że występują problemy z tym, co zostało napisane, i zawsze były z tym problemy, wówczas konieczne jest mówienie o tym, aby zminimalizować częstotliwość poprawiania kodu w przyszłości.

W tym przypadku sugeruję sparowanie podczas naprawy kodu. W ten sposób stanowi dobry przykład stanów pośrednich i (mam nadzieję) pewien kontekst, dlaczego przepisany kod jest lepszy. Również (choćby jako ćwiczenie osobiste) spróbuj przefakturować kod, aby był lepszy bez całkowitego przepisywania. Będzie trudniej, ale dobrze dla ciebie.

Z drugiej strony, są inne czasy, kiedy wymagane jest przepisanie:

  • Zespół wiele się nauczył od czasu napisania kodu, a twórcy, którzy go napisali, teraz napisaliby go inaczej, nawet bez twojej wiedzy.

  • Nowy wymóg dotyczący funkcji zmienia sytuację tak, że celowe mini-przepisanie jest właściwe.

W takich przypadkach prawdopodobnie nie zawracałbym sobie głowy rozmową.

Myśląc o tym, wydaje mi się, że im dłużej kod istnieje, tym mniej prawdopodobne jest, że konieczna jest rozmowa.


1

Myślę, że @aaronaught podniósł kilka dobrych punktów, co naprawdę prowadzi do odpowiedzi, którą chciałem udzielić, a mianowicie, że tak naprawdę zależy to od tego, kto dokonuje zmiany (i dlaczego) i kto napisał kod.

Z mojego osobistego doświadczenia kod jest zwykle zmieniany, ponieważ albo nie działa zgodnie z przeznaczeniem, albo po prostu musisz rozszerzyć to, co faktycznie robi.

W środowisku deweloperskim zespołu nie powinieneś (i być może nie będziesz w stanie) rozmawiać z oryginalnym programistą, wszystko powinno być z kodu usunięte.

To prowadzi do pytania, które pochłania większość mojego czasu, co zamierzał pierwotny programista, i to właśnie to pytanie najczęściej prowadzi do usunięcia kodu, i dlatego powinniśmy komentować wszystko, a niedoświadczeni młodsi programiści najbardziej często upadają.

Każdy programista, który zmienia czyjś kod (refaktoryzacja) naprawdę powinien, dzięki uprzejmości i poćwiczyć kopiowanie tego samego stylu kodowania już istniejącego kodu, i najpierw podejmij kroki, aby dowiedzieć się, jak działał oryginalny kod i co próbował do osiągnięcia i faktycznie do osiągnięcia. Często to samo w sobie identyfikuje błędy, ale z pewnością zmusza ludzi do znoszenia bólu, jaki następna osoba będzie miała na twój kod.

W moim zespole każdy może usuwać, refaktoryzować lub przepisywać cokolwiek, a „własność” postrzegam jako praktykę, która rodzi lenistwo, tak jakby jedna osoba na pewno była powiadamiana o jakichkolwiek zmianach, dlaczego miałaby sprawić, by kod był czytelny.

Krótko mówiąc, nie, nie powinieneś pytać oryginalnego autora kodu, a jeśli patrzysz na kod, który robisz, oznacza to, że albo jego kod nie jest wystarczająco czytelny, albo musisz poprawić Twoje umiejętności. Jednak uważam, że dobrym rozwiązaniem jest pozostawienie oryginalnego kodu na miejscu, skomentowane, dopóki nie masz absolutnej pewności, że podczas przepisywania nie przypadkowo usunąłeś wymaganą funkcjonalność. Nikt nie jest idealny.


-2

Często kod jest napisany w określony sposób z określonego powodu. Powiadomienie autora o zmianie zawsze działa najlepiej.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.