2018-01-09 13:13:19 +0000 2018-01-09 13:13:19 +0000
106
106
Advertisement

Jak mogę sobie poradzić z menedżerami, którzy nie zgadzają się na korzystanie z powszechnych wzorców projektowania oprogramowania?

Advertisement

Tło

Jestem inżynierem oprogramowania i praktykiem TDD w mojej firmie. Mój menadżer jest również odpowiedzialny za kodowanie (w razie potrzeby) i zarządzanie podwładnymi swojego inżyniera.

Ostatnio wdałem się w kilka gorących dyskusji z moim menadżerem na temat wykorzystania wzorców projektowania oprogramowania.

Problem

Często, gdy mam za zadanie zaimplementować funkcję i kod, jestem wyzywany przez mojego menadżera podczas recenzji kodu za wykorzystanie wspólnych wzorców projektowania oprogramowania. Uważa on, że jest to niepotrzebne i należy kodować tak “prosto” jak to tylko możliwe. Cytuję wprost, ponieważ wydaje się, że nie zgadzamy się z tym, jaki powinien być zakres “funkcji”. W wielu przypadkach funkcja nie jest tak “prosta”, jak uważa mój menedżer i wymaga użycia wzorców projektowych, aby oddzielić obowiązki i zminimalizować wpływ na (przeważnie niesprawdzoną) bazę kodu.

Istnieją dwa powszechne przypadki użycia, w których zastosuję wzorce projektowe, aby rozwiązać problem:

  • Wdrażanie nowych funkcji, które wymagają zmian w niesprawdzonej, dotychczasowej klasie

  • Poradzenie sobie z niepewnością poprzez połączenie niewiadomych

Dostaliśmy kilka argumentów z powodu podobnych spotkań projektowych. W jednym z gorących argumentów powiedziano mi nawet, że “[on] programuje od ponad 20 lat!”, co oznacza, że nie powinienem nawet ośmielać się kwestionować jego autorytetu.

Co starałem się złagodzić ten problem

  • Napisane szczegółowe komentarze na temat niektórych, nie tak oczywistych komponentów, dlaczego ich potrzebowałem i jakiemu celowi służą
  • Biernie pokazałem, że mój projekt jest znacznie bardziej przystosowany do zmian
  • Komponent, który zbudowałem ma znacznie mniejszą liczbę błędów niż większość innych komponentów
  • Właściwie przewidziałem zmianę wymagań, co doprowadziło do minimalnej zmiany kodu niezbędnej do spełnienia tego wymogu
  • Zgłosiłem swoje obawy z góry, kiedy jestem kwestionowany, wyjaśniając mój proces myślowy i rozumowanie
  • Jednak nadal jestem nagradzany za nadmiar kodu.
  • Nieformalnie omówił to z moimi kolegami i poprosił o ich opinie na osobności
  • Większość z nich docenia moje dobrze uzasadnione podejście i jeden nawet wspomniał, że wiele się ode mnie nauczył. Większość inżynierów lubi rozmawiać ze mną o swoich problemach z kodowaniem, ponieważ zazwyczaj mogę udzielić im przydatnych rad lub wskazać coś, co mogło im umknąć
  • Prowadzenie nieformalnych prezentacji w celu edukowania moich kolegów inżynierów (i menadżera) dlaczego stosuję wzór projektowy tu i ówdzie

Nie chcę zabrzmieć arogancko mówiąc, że moje umiejętności kodowania są absolutnie lepsze niż umiejętności mojego menadżera, ale naprawdę brakuje mi pomysłów, aby go przekonać, nawet po demonstracjach, wyjaśnieniach i obiektywnych rezultatach, które mu pokazano. Z jednej strony, chciałbym dostarczyć wolny od błędów, dobrze przetestowany i zaprojektowany kod. Z drugiej strony, ciągle jestem krytykowany za to, że mój projekt nie czuje się dobrze i z pewnością ‘skomplikował’ mój kod, zmuszając go do ‘zatwierdzenia’.

How can we find a middle ground?

  • *

Update

Ponieważ otrzymuję wiele komentarzy wspominających o moim dogmatycznym, nawet nadgorliwym podejściu do przestrzegania zasad inżynierii oprogramowania, myślę, że powinienem wyjaśnić:

Nie staram się być dogmatyczny ani nadgorliwy. I do dbam o to, aby ludzie czytali i rozumieli mój kod, czy używają/zrozumieli wzorce projektowe, czy nie. Poprosiłem o informację zwrotną od moich kolegów podczas recenzji kodu, czy rozumieją mój kod, czy też nie. Powiedzieli, że rozumieją i rozumieją, dlaczego projektuję komponent w taki sposób. Pewnego razu, moje użycie wzorców projektowych pomogło scentralizować logikę wyszukiwania konfiguracji w jednej lokalizacji, a nie rozłożyć ją na tuziny lokalizacji, które muszą być często zmieniane.

Szczerze mówiąc, jestem dość rozczarowany widząc tak wiele odpowiedzi z silnym stereotypem “Dlaczego wy inżynierowie nie możecie myśleć jak menedżerowie”. W ostatecznym rozrachunku można powiedzieć, że każda rzecz jest przesadnie inżynierska: Dlaczego oznaczać pola jako private zamiast eksponować wszystko, dlaczego test jednostkowy, jeśli żaden użytkownik nie ma zamiaru wykonać tylko jednej jednostki, itp.

Moją motywacją w używaniu wzorca projektowego lub w rzeczywistości jakiejkolwiek inżynierii oprogramowania jest minimalizowanie ryzyka i wypracowanie wartości dla firmy (na przykład poprzez ograniczenie niepotrzebnego rozprzestrzeniania się logiki w bazie kodu, tak aby można było nimi zarządzać w jednym miejscu).

Przepraszam, jeśli to brzmi jak rant. Szukam odpowiedzi w stylu “jak znaleźć środkowy grunt” zamiast protekcjonalnych odpowiedzi typu “inżynierowie myślą, że są inteligentni, stosując wzorce projektowe, których nikt nie rozumie”.

Advertisement
Advertisement

Odpowiedzi (11)

235
235
235
2018-01-09 13:48:28 +0000

Czy robienie tego w twój sposób kiedykolwiek pomogło? Czy choć raz zdarzyło się, że użyłeś indeksacji i iniekcji oraz dodatkowych interfejsów, a w ostatniej chwili doszło do skrętu i wszystko odbyło się gładko i pięknie, bez przeklinania? Nawet w poprzedniej pracy, jeśli nigdy nie byłeś w stanie popełnić tego kodu tutaj?

Zakładam, że było. Ćwiczenie opowiadania tej** historii. Jest konkretna i prawdziwa. To nie jest “x może się zdarzyć” albo “y może się zmienić”, ale “Dawno, dawno temu, robiłem to w ten sposób i oto jak to się stało.” Menedżerowie (mówię jako jeden z nich) są nieśmiali w kwestii wydawania pieniędzy (i zaufaj mi, piszesz bardziej skomplikowany kod, którego inni nie mogą zrozumieć przy pierwszym przejściu jest wydawanie pieniędzy) na to, co możliwe się stanie. Nie chcą finansować spekulacji, które mogą opierać się tylko na “nauce książki” i najnowszej modie na internet. Ale kiedy czerpiesz z własnego doświadczenia? To zupełnie inna sytuacja.

Nie jestem wielkim fanem fabryk, dostawców, wtryskiwaczy i tym podobnych. Zazwyczaj są one ustawione na rzeczy, które nigdy tak naprawdę się nie wydarzą (zmiana z MS SQL na Oracle) lub mają niewielki wpływ, gdy to robią (zmiana folderu, w którym pliki są zapisywane). Mają one swoje miejsce w układach, które są bardzo zmienne, w których wydaje się, że jesteś. Musisz więc pokazać, że mają takie miejsce. Wydajesz się pochodzić z pozycji, “To jest normalny sposób robienia rzeczy, a ja potrzebuję powodu, by tego nie robić.” Twój menedżer pochodzi z pozycji, “To nie jest normalne, normalne jest proste i proste. Daj mi dobry powód, żeby postawić kolejną warstwę na drodze.” Pracuj nad tym powodem. Pracuj nad historią sukcesu, w której ta dodatkowa warstwa zaoszczędziła dni lub tygodnie pracy. Uzasadnij swoją inżynierię, bo inaczej naprawdę jest to przeinżynieria.

157
157
157
2018-01-09 15:37:37 +0000

Ten cytat z jednego z twoich komentarzy niepokoi mnie:

Jako inżynier oprogramowania, drugą naturą staje się dla mnie “robienie rzeczy, które - być może - nie mają dobrego uzasadnienia na powierzchni”, jak łączenie się z niewiadomymi, o których wspomniałem. Konieczność ciągłego wyjaśniania się na tematy głęboko techniczne (i czasami mocno opiniotwórcze) drenuje mnie.

Widziałem kilka powtórzeń następującego cyklu życia:

  • Wykwalifikowany zespół programistów wymyśla inne podejście do programowania.
  • Jest postrzegany przez kilka lat, do dekady, jako coś, co powinno być używane powszechnie, pomimo wszelkich wad i ograniczeń. W tej fazie wystarczy powiedzieć “stosuję metodologię X”, nie analizując, czy X jest korzyścią netto.
  • Wychodzi z mody, ale jego najbardziej użyteczne pomysły pozostają jako część zestawu narzędzi programistycznych, aby zostać wyciągniętym i wykorzystanym za każdym razem, gdy przynoszą korzyści netto.

Według mnie zarówno TDD, jak i wzorce projektowe kręcą się wokół podziału pomiędzy drugim i trzecim etapem cyklu życia metodologii programowania. Jestem pewien, że TDD i wiele wzorców projektowych będzie miało długą i wartościową żywotność w zestawie narzędzi, które będą używane zawsze, gdy będą pomagać bardziej niż szkodzić. Myślę również, że mogą być one nadal nadużywane, z przyzwyczajenia, a nie celowo.

Powinieneś nigdy nie stosować wzorca projektowego, ponieważ jest to druga natura, lub mieć problem z wyjaśnieniem swojego użycia. Zamiast tego, przed zastosowaniem wzoru, należy zastanowić się nad jego kosztami i korzyściami w tej konkretnej sytuacji. Jeśli korzyści z niego płynące naprawdę przewyższają jego koszty, powinieneś wiedzieć dokładnie, dlaczego, więc wyjaśnienie kompromisu nie powinno Cię wyczerpać. Jeśli korzyści nie przeważają nad kosztami, nie używaj go. Ponownie, twoje własne myślenie o twoim projekcie powinno przygotować cię do odpowiedzi, jeśli zostaniesz zapytany, dlaczego nie użyłeś możliwego do zastosowania wzoru projektu.

Pamiętaj, że musisz myśleć o tych kompromisach w kategoriach ogólnej łatwości utrzymania programu, a nie tylko o tym, aby twój utwór działał szybko. Zbyt duża indykacja może utrudnić przyszłym programistom zorientowanie się, co tak naprawdę się dzieje.

52
Advertisement
52
52
2018-01-10 18:53:35 +0000
Advertisement

Czy jestem jedyną osobą zdenerwowaną tym, że w miejscu pracy tak bardzo skupiamy się na praktykach kodowania, a nie na faktycznym konflikcie w miejscu pracy? Przyjmę więc inne podejście.

Oto uogólnione aspekty Twojego problemu w moim rozumieniu:

  1. Znajdujesz się w kompetentnym obszarze, który wymaga współpracy

  2. Nie ma udokumentowanych procedur regulujących sposób, w jaki ta współpraca powinna być wykonywana

  3. Nie ma zgody co do tego, jak ta wspólna praca powinna być wykonywana

  4. Jednym z tych, którzy się nie zgadzają jest twój menedżer

Brzmi to tak, jakby twoja grupa musiała się zebrać i uzgodnić, jakie standardy i praktyki przyjmiesz i przyjmiesz je globalnie, na lepsze lub na gorsze. Ponieważ nie ma nic gorszego dla produktu niż zespół, który stale się kłóci, i nie ma nic gorszego dla twoich relacji z pracodawcą niż ciągłe odświeżanie argumentów z nimi.

Spróbuj więc zebrać swój zespół, aby uzgodnić pewne standardy i wykorzystać to spotkanie do przedstawienia argumentów na rzecz praktyk, które stosujesz. Jeśli je dostaniesz, to świetnie! Jeśli nie, to niech tak będzie. Twoim zadaniem nie jest pisanie pięknego kodu. Twoim zadaniem jest dostarczenie gotowego produktu. Jeśli Twój pracodawca (wcielony w życie przez Twojego menedżera) i mnogość Twojej grupy nalega, abyś zrobił to w określony sposób, to kim jesteś, aby je zdobyć?

Jednakże, brzmi to tak, jakby większość Twojego zespołu zgadzała się z Tobą, więc podczas tych dyskusji powinno stać się dość oczywiste, że Twój menedżer jest tym dziwnym. Jeśli ta osoba nadal odmawia zmiany na konsensus zespołowy, to jest to dysfunkcja, której nie możemy pomóc Ci rozwiązać (inna niż polecenie przeniesienia się do innego zespołu).

23
23
23
2018-01-09 19:58:25 +0000

Niestety, on jest twoim menadżerem, a ty nie piszesz kodu w sposób, w jaki on chce, żebyś go napisał. Jeśli jest menedżerem, może nie planować wyjścia z firmy w ciągu 2-3 lat, jak większość deweloperów planuje. Piszesz kod, który będzie trudniejszy do naprawienia dla swoich zastępców, dlatego też jest ci ciężko go zbudować w ten sposób.

Jeśli mogę przyjąć tutaj założenie, wiedząc doskonale, że mogę być daleko od celu, po co piszesz ten materiał? Byłbym raczej zaskoczony, gdyby to było coś więcej niż aplikacje LOB. Wzorce projektowe prawdopodobnie zbytnio komplikują jakiś kod dla aplikacji LOB, który nie musi być szczególnie skomplikowany.

W ciągu 10 lat mojego rozwoju, prawdziwa strategia/wzorzec fabryczny był potrzebny tylko trzy razy, z czego dwa z nich pochodzą z pracy:

  • W aplikacji, która wyświetlała informacje o produkcie, gdzie niektóre z tych produktów były w zasadzie paczką mniejszych produktów w pudełku, użyliśmy strategii, aby określić, która fabryka była potrzebna do przekształcenia informacji o produkcie (wymaganych przez klucz) w widok. Nie było to zbyt chwalebne, ale spełniło swoją rolę. Jeśli pozwolę sobie dopasować twoją skromną chusteczkę o robakach, w całej mojej kadencji nigdy nie mieliśmy tam ani jednego robaka! (jeden został zgłoszony po moim wyjściu, ale okazał się być błędem użytkownika :)).
  • W aplikacji, która pokazywała użytkownikom, gdzie mają się udać na zajęcia, na które uczęszczali, użyliśmy fabryki i abstrakcji, aby umożliwić szybkie przejście między API Bing Maps a Google Maps. Wynikało to z faktu, że oba te elementy miały swój koszt/korzyść, a firma nie robiła postępów określając, z którego z nich skorzystać. W końcu dowiedzieliśmy się z naszego biura domowego, że mieliśmy już klucz API dla jednego z nich i mogliśmy obrócić się w ostatniej sekundzie do tego API, tuż przed uruchomieniem.

A trzeci to projekt, z którym mam do czynienia, czyli monitoring serwerów dla serwerów Windows:

  • używam interfejsu do wyprowadzania danych z monitoringu i dla samych monitorów. Monitory są wysoce konfigurowalne (w oparciu o ustawienia aplikacji). Implementacja danych wyjściowych różni się w zależności od tego, czy testuję nowy monitor, czy zamierzam go wdrożyć, tak że IOutputInterface ma ConsoleOutput i SqlOutput jako implementacje, które mogą się różnić.

Zauważ, że mój osobisty projekt od razu częściej korzysta z wzorców i inwersji kontroli (IoC) niż moje projekty robocze.

Jeśli po tym wszystkim mogę dać Ci jakąś radę, niech tak będzie: Praca to praca, a jeśli chcesz robić rzeczy po swojemu, to spróbuj znaleźć szczęśliwe medium. Ludzie z branży technicznej na ogół nie zostają długo w miejscach i nie warto wdawać się w bójkę z kierownictwem o to, jak to się robi. Niech Twoje osobiste projekty domowe będą stosem wzorów, ile tylko chcesz.

9
Advertisement
9
9
2018-01-10 06:54:37 +0000
Advertisement

Łatwe rozwiązanie: Rzuć.

Twarde rozwiązanie: w każdej nieporozumieniu, połowa winy leży po twojej stronie.

Weź trochę wolnego czasu, przestudiuj jak pracują inne zespoły, dowiedz się gdzie niedopasowanie impedancji jest między tobą a drugą stroną. Porozmawiaj z nimi osobiście, wcześnie i często. Jeśli zrobisz to dobrze, obie strony nauczą się rozumieć obawy i referencje drugiej strony, a oni nauczą się cenić Twój wkład, doświadczenie i mocne opinie. Oto kilka obszarów do rozważenia:

  • produkt wysokiej jakości vs. czas wprowadzenia na rynek
  • dobry produkt vs. dobry kod
  • kod inteligentny vs. kod zrozumiały
  • kultura firmy z góry na dół vs. kultura inżynierska z dołu

Jeśli to nie działa dobrze, weź pod uwagę inną rolę w zespole, inny zespół w firmie lub wreszcie inną firmę.

9
9
9
2018-01-10 03:54:04 +0000

Jeśli stawisz czoła tym ludziom na głowie, napotkasz największy opór, konik polny. Byłem najbardziej skuteczny w wprowadzaniu zmian, gdy strategicznie trafiałem we właściwe punkty nacisku. Wymaga to dużo cierpliwości i poddania się. Muszę najpierw przystosować się do nich przed zastosowaniem nacisku w słabych punktach.

Opróżnij swój umysł, bądź bezkształtny. Bezkształtna, jak woda. Jeśli włożysz wodę do filiżanki, to stanie się ona filiżanką. … Teraz woda może płynąć lub może się rozbić. - Bruce Lee

Posłuchaj ich i zadaj wiele pytań. Genuinely słuchanie kogoś odbiera mu chęć oporu. Zrozumieć, co motywuje ich myślenie, a następnie mówić ich językiem. Ponieważ twoje przekonania są osiowe, w tym momencie prawdopodobnie odzwierciedlają twój upór, pogardę i frustrację. Ponieważ jesteś podwładnym, to on decyduje, aby nie łączyć twojej długości fali, a na tobie spoczywa obowiązek zbudowania mostu.

Jak go zobaczysz, zobaczysz siebie. Jak go będziesz traktował, będziesz traktował samego siebie. Jak będziesz o nim myśleć, będziesz myśleć o sobie. Nigdy o tym nie zapominaj, bo w nim odnajdziesz siebie lub się zatracisz. - Helen Schucman

Mistrz Wing Chun Kung Fu wciągnie swojego przeciwnika i zamknie dystans zanim zacznie szukać i atakować linię środkową, gdzie jest najbardziej bezbronny. Nie kłóć się z drobiazgami tylko po to aby wygrać, znajdź linię środkową większego problemu i skup się na nim.

Codziennie mam do czynienia z inżynierami, którzy odmawiają retoolowania lub uczenia się nowych paradygmatów programowania i dostaję jakąś formę argumentu “byłem tu od czasów kart pamięci” więcej razy niż mogę zliczyć. Szacuję, że przegrałem 80% bitew, ale te 20%…woh…Dokonałem dużych zmian. Mogę brzmieć niejasno, ale zrób kilka badań google'a nad niektórymi z tych słów kluczowych, a dostaniesz to, o co mi chodzi.

Spróbuj też dostać się na nowy projekt _squirrel, który możesz zrobić po swojemu. Jeśli to naprawdę działa i pozwala zaoszczędzić czas lub pieniądze, ludzie przyjdą do twojego sposobu myślenia. Jeśli nie ma nowego projektu, stwórz go w swoim wolnym czasie, aby rozwiązać punkt bólu, który firma ma i nikt nie jest zainteresowany poświęceniem czasu na jego rozwiązanie.

8
Advertisement
8
8
2018-01-09 13:21:09 +0000
Advertisement

Co powinienem zrobić?

W inżynierii oprogramowania, to jak dobrze napisany jest kod (lub nadpisany) zawsze podlega pewnej interpretacji (opinii). Dla mnie podejmujesz kroki, które zrobiłbym na twoim miejscu, ale ostatecznie to twój menedżer musi widzieć światło…pokazuj mu je dalej.

Kontynuowałbym, tak bolesne, jak to może być, aby zrobić dokładnie to, co robisz i punktować zwrot z inwestycji w używanie wzorca projektowego, gdzie możesz, nie sprawiając, że twój menedżer wygląda bad.

Nie zmieniaj tego, co robisz bez względu na to, że czujesz się zagrożony gorszym niż nagana. Cały czas pokazuj im korzyści płynące z używania wzorca, a w końcu powinny się pojawić.

W miarę jak kontynuujesz walkę, próbuj zdobyć innych sojuszników w zespole. W ten sposób nie jesteś jedynym słyszalnym głosem opowiadającym się za wzorem.

W pewnym momencie jednak jeśli odmówią Ci wyboru, czy to środowisko jest dla Ciebie odpowiednie. Nie sądzę, że jeszcze tam jesteś, ale być może będziesz musiał przejść do środowiska bardziej akceptowalnego dla dobrych praktyk kodowania.

Pamiętaj, że ta walka, w której uczestniczysz jest maratonem. Jeśli chcesz zmienić kulturę kodowania, to od Ciebie będzie zależało, czy zademonstrujesz wartość wzorca.

5
5
5
2018-01-12 18:58:58 +0000

Po pierwsze, na podstawie podanych informacji nie możemy stwierdzić, kto ma rację. W rzeczywistości, gdybym został wezwany do przeprowadzenia audytu projektu, nadal mógłbym mieć trudności z podjęciem decyzji, kto ma rację, ponieważ można by projektować z myślą o różnych celach. Ale przypuszczam, że szef zna cele lepiej niż ty.

Po drugie, twoje pytanie: “Jak mogę przekonać mojego szefa?” Odpowiedź brzmi, że prawdopodobnie nie możesz. W końcu, to on jest szefem. Jedyny raz, kiedy przekonałem szefa do zmiany jego pomysłów na inżynierię oprogramowania, to po tym, jak spędziliśmy rok na łataniu nierzetelnego oprogramowania, które zostało napisane tak, jak on tego chciał, i powiedzieliśmy mu, że nie możemy uczynić go niezawodnym, chyba że zaprojektujemy je inaczej.

3
Advertisement
3
3
2018-01-14 16:40:57 +0000
Advertisement

Nie wiemy, kto jest tutaj z technicznego punktu widzenia - może to być menedżer utknięty głęboko w przeszłości, albo nowy deweloper ślepo wierzący w ten szum.

Ale on jest twoim menedżerem, a ty nie masz do czynienia z menedżerem, masz do czynienia z jego odmową zrobienia tego, co you uważasz za najlepsze, i nalega na zrobienie tego, co he uważa za najlepsze. I to jest normalny stan rzeczy, że twój menedżer podejmuje decyzję. Jest to również normalny stan rzeczy, że ostatecznie to on jest odpowiedzialny za sukces lub porażkę, a nie ty. On ma władzę. I ma rację, nie powinieneś kwestionować jego autorytetu. Możesz kwestionować, czy on ma rację, ale nie jego autorytet. Więc albo się nim zajmujesz, albo zmieniasz się w firmę, która robi rzeczy po swojemu.

W międzyczasie, zamiast myśleć, że rzeczy nie idą tak, jak chcesz, zastanów się, jak stworzyć najlepszy jakościowo kod, który możesz w ramach swoich ograniczeń. Wiele rzeczy można zrobić na różne sposoby. Jest “proste, źle zaprojektowane” i “proste, dobrze zaprojektowane”. Przejdź do tego drugiego.

1
1
1
2018-01-14 20:06:06 +0000

Doświadczenie pozwala ocenić, czy korzyści z wzorca projektowego są możliwe i prawdopodobne w przyszłości. Jeśli przełożony rozpoznaje wzór i nadal go odrzuca, prawdopodobnie rozpoznaje przypadek, gdy zastosowanie tego lub podobnego wzoru nie opłaca się. Czasami doświadczenie jest sprzeczne z zasadami lub bardziej prawdopodobne, że są one interpretowane.

Znana jest opinia, że krótszy i prostszy kod jest łatwiejszy do zrozumienia i bardziej otwarty na istotne zmiany.

0
0
0
2018-01-10 10:09:55 +0000

Proponuję programowanie w parze i wzajemną weryfikację. To pomoże twoim współpracownikom lepiej zrozumieć twój kod, ponieważ musisz wyjaśnić why i how jak to robisz, a nie po fakcie.

Albo nauczą się od ciebie i zobaczą dlaczego to jest mądre, albo dowiesz się, że najlepsi programiści piszący kod inni mogą go utrzymać.

Advertisement

Pytania pokrewne

19
20
21
19
3
Advertisement
Advertisement