Pozostaję w środowisku, w którym ludzie wierzą:
- Generics Java to funkcja używana wyłącznie do pisania bibliotek, a nie do prawdziwego kodowania.
- C ++ jest językiem programowania OO;
template
jest funkcją opcjonalną i możliwą do uniknięcia
Chociaż osoby te polegają w dużej mierze na bibliotekach napisanych przy użyciu programowania ogólnego (np. STL, kontenery Java). Jeśli napiszę kod za pomocą template
s lub generics
, recenzent kodu najprawdopodobniej go odrzuci i skomentuje, aby napisać go w sposób „właściwy / zrozumiały / elegancki” .
Taka mentalność ma zastosowanie od zwykłego programisty do najwyższego rangą menedżera. Nie ma wyjścia, ponieważ w 90% przypadków ludzie ci lobbują.
Jaki jest najlepszy sposób ( nie wymaganie od gardła ) wyjaśniania, praktyczne podejście do pisania kodu, które stanowi OO i ogólne programowanie jednocześnie?
Odpowiedzi:
Nadal są ludzie na świecie, którzy nie używają jave generics w „zwykłym kodowaniu”. Mogę w to uwierzyć za pomocą szablonów C ++, ale ogólne? Nie są nawet trudne do nauczenia / używania. Poważnie najlepsze funkcje Java i C ++ to odpowiednio ogólne i szablony.
Najlepszym sposobem, aby przekonać ludzi do rzeczy, jest przekonujący argument, nie grożenie i racja.
Dopóki nie robisz czegoś takiego jak używanie szablonów jako języka programowania, parametryczny polimorfizm (generyczne / szablony) jest prawie na pewno dobry.
1. Unika kopiowania kodu.
To oczywiste, ale kod polimorficzny jest kodem ogólnym. Dlatego nazywa się to lekami generycznymi.
2. Obsługuje lepsze sprawdzanie statyczne.
Bez polimorfizm parametryczny skończyć pisanie takich rzeczy
public Object clone()
lubpublic boolean equals(object b)
które są nie tylko obrzydliwości, mają typy, które nie dostarczają informacji o tym, co robią, i zawsze kończy się wyrzucanie wyjątków w każdym miejscu. Alternatywa dla parametrycznego polimorfizmu jest rzucana wszędzie3. Nieparametryczny polimorfizm OOP zasadniczo nie jest w stanie poprawnie obsługiwać „metod binarnych”.
Używasz ich często.
4. To najlepsza praktyka
W Javie stosowanie ogólnych jest uważane za najlepszą praktykę (patrz Efektywna Java autorstwa Josh Bloch). Główni myśliciele C ++, tacy jak Sutter i Alexandrescu, również zachęcają do korzystania z szablonów do rozwiązywania różnych problemów.
5. Pasuje do paradygmatu OO.
Ludzie często tego nie zauważają, ale kombinacja podtypów i rodzajów generuje system DUŻO bardziej wyrazisty i zorientowany obiektowo niż jakikolwiek inny system z jednym z nich.
Rozważ miksy Scali. Są to miłe funkcje, które pozwalają łączyć obiekty z części składowych. Ogólne i szablony mogą symulować niektóre z tych korzyści. Załóżmy na przykład, że jeden z twoich obiektów korzysta z bazy danych. Dobry projekt pozwoliłby ci wydzielić dostęp do bazy danych do osobnej klasy. Jeśli zrobisz to dobrze, nie tylko pozwala to na wyśmiewanie magazynu danych (klucz do testowalności), ale także oznacza, że możesz dodawać alternatywne implementacje, takie jak ta nowa baza danych bez sql. Tutaj jednak możesz mieć problem, bez względu na to, z której implementacji korzystasz, uzyskasz różne możliwości obiektu biznesowego.
Generics na ratunek!
Teraz możesz zacząć statycznie różnicować swoje
Business
obiekty w oparciu o możliwość korzystania z funkcji specyficznych dla bazy danych. Nadal potrzebujesz sprawdzania czasu wykonywania i przesyłania, ale możesz zacząć budować DUŻO lepszy kod.i
6. Normalny kod nie istnieje.
Istnieją tylko trzy rzeczy we wszechświecie programowania:
Jeśli nie myślisz o swoim kodzie, jakby był biblioteką, masz poważne kłopoty, gdy zmieniają się wymagania dotyczące twojego projektu. Architektura jest (prawdopodobnie) sztuką projektowania dobrych interfejsów API.
Uważam to podejście za oszałamiające. Po przyzwyczajeniu się do programowania z typami sparametryzowanymi, nieużywanie ich sprawia, że wszystko jest uciążliwe. I Java i C ++ mają kilka trudnych miejsc, które pomagają naprawić.
źródło
normal code
nie istnieje i że istnieją tylko trzy rodzaje:libraries
,configurations
ibad code
. Jest to rozumowanie idealistyczne, choć wciąż musisz wyjaśnić to swoim kolegom, którzy mogą nie być tak idealistyczni jak ty. Zgadzam się jednak, że używanie sparametryzowanych typów jest po prostu niesamowite, kiedy się zorientujesz.Jest to wyspecjalizowana forma bardziej ogólnego pytania „jak przekonać swoich przełożonych do korzystania z nowszej i lepszej technologii / sposobu tworzenia rzeczy?”
Niestety nie sądzę, że możesz i nie jestem pewien, czy powinieneś. Jest to z definicji ich wybór, ponieważ płacą ci za robienie rzeczy w określony przez siebie sposób, a nie w dowolny sposób. Najlepsze, co możesz zrobić, to zasugerować, że ta technologia jest dostępna, wiele osób jej używa i wydaje się, że jest to droga przyszłości. Możesz nawet wspomnieć o fakcie, który oni oczywiście powinni już wiedzieć: że najlepiej jest, aby ludzie nie dopuścili do stagnacji swoich umiejętności. Ale to wszystko: jeśli tego nie kupią, nic nie możesz zrobić.
Mogą mieć inne względy, których ty nie masz, ponieważ nie myślisz na ich poziomie. Myślisz jako inżynier, mogą myśleć bardziej w kategoriach biznesowych, a nawet zasobów ludzkich.
Czy leki generyczne (lub cokolwiek innego) zwiększą wartość swojego produktu? Prawdopodobnie nie.
Czy leki generyczne (lub cokolwiek innego) utrudnią ludziom, których już zatrudniali, wykonywanie swojej pracy? Tak.
Czy leki generyczne skrócą czas wprowadzania produktów na rynek? Może byłby to jedyny inżynier. Ale jeśli cała grupa inżynierów musi zostać przeszkolona w zakresie generycznych, zanim w domu zostanie napisany inny wiersz kodu, nie.
Warto rozważyć zmianę pracy. W mojej ostatniej pracy jako pierwsza korzystałem z generycznych w Javie i na szczęście nie mieli z tym problemu; wyrazili zaniepokojenie, że generycy sprawiają, że kod „jest trudniejszy do odczytania”, ale pozwalają mi na to. Znajdź taką pracę.
źródło
Przekazałbym zalety generyczne recenzentowi kodu i innym współpracownikom przed każdą recenzją:
1) Umożliwiając ci określenie typów, na które działa klasa ogólna lub metoda ogólna, funkcja ogólna przenosi ciężar bezpieczeństwa typu z Ciebie na kompilator. Nie ma potrzeby pisania kodu w celu przetestowania poprawnego typu danych, ponieważ jest on wymuszany w czasie kompilacji. Konieczność rzutowania typu i możliwość wystąpienia błędów w czasie wykonywania są zmniejszone.
2) Produkty generyczne zapewniają bezpieczeństwo typu bez kosztów wielu implementacji.
Zatem [1] i [2] zmniejszają ryzyko błędu w kodzie. Oszczędza to czas programisty, a tym samym pieniądze firmy.
Jeśli czytelność jest problemem, niezręczność korzystania z typów ogólnych może być zagrożona. Jest to jeden z powodów, dla których warto rozszerzyć wytyczne dotyczące kodowania. Można to zrobić w kontekście dnia roboczego, a nie tylko w celu rozszerzenia bibliotek (jednak pomysłem jest refaktoryzacja w trakcie pracy i zaznaczenie potencjalnych metod dla bibliotek w kodzie, aby ułatwić ich późniejsze rozpoznanie). Dlatego nie byłoby powodu, aby nie używać ich w kontekście dnia roboczego.
Dodałbym kilka stwierdzeń o tym, jak inni programiści nie mają problemów z generycznymi: Generics są szeroko stosowane w Javie i wielu innych językach, takich jak C #. Dla każdego poważnego programisty życie byłoby trudne bez tego rodzaju bezpiecznych elementów konstrukcyjnych.
Niemniej jednak możesz wziąć pod uwagę, że niektórzy deweloperzy mogą nie być do zera. Zarząd mógł podjąć świadomą decyzję o ochronie projektów w przeszłości, tym samym chroniąc tych ludzi przed niebezpiecznymi obszarami. W tym przypadku zarówno niewinni, jak i winni zwykle ponoszą winę, ponieważ rzadko przeprowadza się wystarczającą analizę lub mikro-zarządzanie.
Jeśli przedstawisz dobry argument i nie otrzymasz w zamian uzasadnionej odpowiedzi, potajemnie zacznij szukać innej firmy, która poważnie traktuje programowanie.
źródło
O ile nie jesteś architektem / specjalistą technologicznym, trudno będzie wprowadzić nakaz używania ogólnych / szablonów. Naprawdę powinieneś zaproponować ogólne / szablonowe rozwiązanie na długo przed przeglądem kodu, najlepiej przed jego wdrożeniem.
Co możesz zrobić, to zademonstrować, dlaczego w niektórych przypadkach powinieneś użyć generycznego. Jeśli potrafisz wykazać korzyści, twoi koledzy mogą się zgodzić. Możliwe powody, dla których warto używać ogólnych / szablonów, to:
W ostatnim projekcie Java z powodzeniem dodałem ogólną klasę abstrakcyjną, ponieważ spełnia ona pewne podstawowe rzeczy: ułatwiała pracę innym członkom zespołu, egzekwowała wzorzec zaproponowany przez architekta i zawierała wspólny kod, którego programiści nie musieli kopiuj i wklej. Był to prosty wzorzec, który architekt napisał o tych dość kompetentnych ludziach, którzy nadal się mylili (z powodu złożoności rzeczywistego systemu w grze), ale ogólne znaki wskazują, do której klasy idzie.
Oczywiście nie mogę pochwalić się prawdziwym przykładem bez naruszenia umowy o zachowaniu poufności. Ale jako przykład tego, co zrobiłem, byłoby zrobienie wzorca strategii i egzekwowanie go za pomocą generyków. Oto wzorzec strategii:
Aby programiści mogli wymusić ten wzorzec, możesz dodać typ ogólny
Context
, że powinien używać czegoś, co maStrategy
typ. Pod względem kodu wyglądałoby to mniej więcej tak:O ile mi wiadomo, możesz to zrobić w dowolny sposób. Upewnij się, że możesz przetestować swój projekt ogólny / szablon za pomocą testów jednostkowych, aby sprawdzić, czy działa, aby mieć pewność co do projektu kodu.
Jeśli twoim kolegom nie podoba się ten pomysł, nie bierz go do siebie, być może nie było dla nich tak łatwego rozwiązania, jak ci się wydawało. Dlatego powinieneś zaproponować ogólne / szablonowe rozwiązanie przed jego wdrożeniem. Nadal musisz współpracować z kolegami, aby rozwiązać rzeczywisty problem w inny sposób.
źródło
Zawsze istnieje kilka sposobów na zrobienie tego samego. Jeśli korzystanie z szablonów jest niewłaściwe użycie szablonów, powinno to zakończyć się niepowodzeniem przeglądu kodu.
Jeśli jednak kod nie przejdzie przeglądu, ponieważ nie rozumieją szablonów, problem jest innego rodzaju. W takim przypadku doradzaj im (w miły sposób), aby nauczyli się szablonów.
źródło
To, z czym masz do czynienia, to zbiór uprzedzeń. Ludzie wolą status quo, rozwinęło się przemyślenie grupy, a spór toczył się kilka razy, aby ludzie zakorzenili się w swoich przekonaniach.
Jedną z najbardziej skutecznych strategii jest skupienie się na niewielkim zwycięstwie. W książce przeczytałem następujący przykład : autor był zagorzałym użytkownikiem spoza Apple. Nie lubiła ich i nie chciała mieć z nimi nic wspólnego. Prowadziła wiele dyskusji z ludźmi o postawie pro-Apple, a każda z nich po prostu zepchnęła obcasy głębiej w ziemię. Potem ktoś kupił jej iPoda shuffle i w ten sposób jej uprzedzenia zniknęły. Nie sprawiało, że chciała kupować tylko produkty Apple, ale twarda, zakorzeniona postawa anty-Apple została zastąpiona bardziej zrównoważonym punktem widzenia. Było miejsce na kompromis, a ona w końcu powoli przechodziła na Apple.
Nie próbuj więc przekonywać wszystkich naraz: przyniesie to odwrotny skutek. Skup się na jednej drobiazgu, a reszta stanie się sama. Po prostu pozbądź się dwustronnej natury argumentu, aby ludzie mogli przechodzić krok po kroku, zamiast wszystkich naraz.
Konkretny punkt, na którym należy się skupić, zależy od twojej sytuacji, ale oto jeden pomysł: podział, który szkicujesz między bibliotekami a „prawdziwym kodem”, wydaje się bardzo nienaturalny. Moim zdaniem programista tworzący aplikację powinien poświęcić 80% swojego czasu na bibliotekę dla typu aplikacji, którą tworzy, a 20% na wykorzystanie tej biblioteki do zbudowania aplikacji. Cały kod, który warto przechowywać, należy traktować jako bibliotekę. Sugerowałbym przełożonym, aby uogólnili część kodu w bibliotece wewnętrznej (jeśli jeszcze tego nie zrobiłeś). Zgodnie z ich logiką powinni używać do tego ogólnych, a według powyższego szacunku 80% kodu może znaleźć się w bibliotece. Gdy wszyscy przyzwyczają się do używania leków generycznych z drugiej strony, powinni się do tego przyzwyczaić, a uprzedzenia powinny zniknąć.
źródło
Uwaga „zrozumiałe”. Jeśli recenzent kodu nie widzi korzyści z generics, wówczas wszystkie
<<<>>>
-tuff to po prostu niezrozumiały hałas, który jest niepotrzebny.Proponuję rzucić okiem na to, ile faktycznie obecnych błędów (otwartych lub ostatnio naprawionych), które zawiera baza błędów, których można by uniknąć, używając ogólnych. Poszukaj wyjątków ClassCast.
Zauważ też, że jeśli nie masz żadnych błędów, których można by uniknąć za pomocą ogólnych, wtedy twoi koledzy mają taki punkt, że nie potrzebujesz ich.
źródło
Zrobiłbym to łatwo. Kilka lat temu przeniosłem się z Java 1.4 do 1.6, a generics to prawdziwy wstrząs. Jest to proste i bardzo pomocne, jeśli próbujesz żonglować kilkoma kolekcjami, mapami i innymi strukturami. Jednak pisanie klas, które przyjmują dane ogólne jako parametry, manipuluje nimi i przekazuje je do innych klas, szybko staje się monumentalnie mylące. Czuję wielką satysfakcję z tego, że wszystko działa, ale zastanawiam się, czy warto poświęcić dodatkowy czas i wysiłek. Obawiam się również, że spora liczba programistów Java nigdy tak naprawdę nie zrozumie tego.
Jeszcze kilka przypadkowych myśli z mojej dotychczasowej podróży:
@SuppressWarnings(value="unchecked")
czasu do czasu ich używać . Skąd wiesz, że jesteś poza limitami leków generycznych, czy po prostu jesteś głupi i musisz się bardziej zastanowić?@SuppressWarnings(value="unchecked")
tylko do jednej linii.Generics wyczyścił mój kod zbyt wiele razy i ostrzegał mnie przed problemami, abym go odrzucił, ale widzę też dłuższy czas programowania, dodatkowy czas poświęcony na szkolenie, a programiści Java zmuszeni do pracy w C #, C i Visual Basic. ..lub Java 1.4. Skoncentruję się na pisaniu kodu, który Twoi współpracownicy mogą zrozumieć. Jeśli potrafisz podać jakieś zrozumiałe informacje ogólne, świetnie. Uważam, że generycy Java są szansą / problemem, który nie został jeszcze wyjaśniony.
źródło