Zawsze staram się śledzić DRY zasadę ściśle w pracy; za każdym razem, gdy powtarzam kod z lenistwa, gryzie go później, kiedy muszę go utrzymywać w dwóch miejscach.
Ale często piszę małe metody (może 10-15 linii kodu), które trzeba ponownie wykorzystać w dwóch projektach, które nie mogą się nawzajem odnosić. Metoda może mieć coś wspólnego z siecią / łańcuchami / MVVM itp. I jest ogólnie użyteczną metodą, która nie jest specyficzna dla projektu, w którym pierwotnie się znajduje.
Standardowym sposobem ponownego wykorzystania tego kodu byłoby utworzenie niezależnego projektu dla kodu wielokrotnego użytku i odwołanie się do tego projektu, gdy będzie to potrzebne. Problem polega na tym, że kończymy w jednym z dwóch mniej niż idealnych scenariuszy:
- Skończyliśmy z dziesiątkami / setkami drobnych projektów - każdy z nich zawierał małe klasy / metody, których potrzebowaliśmy ponownie. Czy warto utworzyć zupełnie nowy
.DLL
kod, aby tylko odrobinę kodu? - W efekcie powstaje jeden projekt z rosnącą kolekcją niepowiązanych metod i klas. Takie podejście właśnie zrobiła firma, w której kiedyś pracowałem; mieli projekt o nazwie,
base.common
który zawierał foldery dla takich rzeczy, jak wspomniałem powyżej: sieci, manipulacji ciągami, MVVM itp. To było niezwykle przydatne, ale odwoływanie się do niego niepotrzebnie przeciągało za sobą cały niepotrzebny kod, którego nie potrzebowałeś.
Więc moje pytanie brzmi:
W jaki sposób zespół programistów najlepiej wykorzystuje ponowne wykorzystanie małych fragmentów kodu między projektami?
Interesuje mnie szczególnie to, czy ktoś pracował w firmie, która ma zasady w tym obszarze, lub osobiście spotkałem się z tym dylematem.
Uwaga: moje użycie słów „Projekt”, „Rozwiązanie” i „Dokumentacja” pochodzi z tła programowania .NET w Visual Studio. Ale jestem pewien, że ten problem jest niezależny od języka i platformy.
źródło
Odpowiedzi:
Jeśli naprawdę są to metody / klasy wielokrotnego użytku, możesz zapisać je w niewielkiej liczbie bibliotek „Swiss Army Knife”. Robimy to dość często w mojej firmie; nazywamy je bibliotekami szkieletowymi:
Framework.Data
- Narzędzia do pracy z zapytaniami do baz danych.Framework.ESB
- Standardowe metody interakcji z naszą magistralą usług dla przedsiębiorstwFramework.Logging
- Zunifikowany system rejestrowaniaFramework.Services
- Narzędzia do interakcji z usługami internetowymiFramework.Strings
- Narzędzia do zaawansowanej manipulacji ciągiem / wyszukiwania rozmytych ciągów znaków itp.W sumie istnieje około kilkunastu bibliotek. Możesz naprawdę rozprowadzać kod według własnego uznania, więc nie musisz kończyć setkami ani zrzucać wszystkiego do jednego gigantycznego zestawu. Uważam, że to podejście pasuje, ponieważ tylko niektóre z naszych projektów będą potrzebne,
Framework.Data
a tylko kilka będzie kiedykolwiek potrzebowaćFramework.Strings
, więc konsumenci mogą wybrać tylko te części ram, które są odpowiednie dla ich konkretnego projektu.Jeśli tak naprawdę są to tylko fragmenty, a nie rzeczywiste metody / klasy, które można łatwo ponownie wykorzystać, możesz spróbować rozpowszechnić je jako fragmenty kodu w IDE (np. Fragmenty kodu Visual Studio ). Zespoły, z którymi pracowałem w przeszłości, miały wspólną bibliotekę fragmentów, która ułatwiła wszystkim przestrzeganie naszych standardowych praktyk kodowania, także z kodem wewnętrznym.
źródło
IPAddressToString
, jest prawdopodobne, że konsumenci czynienia z protokołów sieciowych będzie musiał użyć, ale konsumenci który nie wiele błahy z ciągów nie troszczą się o adresy IP w ogóle. To prawdopodobnie skończyłoby się w pakiecie sieciowymFramework.Strings
.Framework.Logging.Gibraltar
Jest szczególnym dodatkiem do systemu rejestrowania.Nie zgadzam się z przyjętą odpowiedzią z wielu powodów.
Z mojego doświadczenia wynika, że gdy widzę „różne” biblioteki, takie jak zaakceptowana odpowiedź, są one pretekstem do ponownego wynalezienia koła (lub nie wymyślonego tutaj (NIH) ) - znacznie większego grzechu niż łamanie Dont Repeat Yourself (DRY) .
Czasami naruszenie DRY może być rozsądnym kompromisem, jest lepsze niż wprowadzenie ciasnego sprzężenia. Ponowne użycie jest kwestią drugorzędną w porównaniu z dobrym projektowaniem obiektowym. Nieco (mam na myśli małą ilość, zastosuj zasadę trzech ) powielania jest łatwiejsze do zrozumienia niż podstawa kodu spaghetti.
Podejście wielu bibliotek ogólnego przeznaczenia stanowi zły przykład. Prowadzi to do drobnej ziarnistości zestawu, a zbyt wiele zestawów jest złe. Niedawno zmniejszyłem wewnętrzny z 24 bibliotek do 6 bibliotek. Poprawił czas kompilacji z kilku minut do ~ 20 sekund. Visual Studio działa również wolniej i jest mniej responsywny dzięki większej liczbie zespołów. Posiadanie zbyt wielu bibliotek prowadzi również do zamieszania co do tego, gdzie powinien znajdować się kod; wolą mniej, prostsze zasady.
Dlaczego rzeczy w .NET Framework nie są wystarczająco dobre? Framework jest dość duży; wiele razy widziałem kod, który ponownie implementuje rzeczy, które już tam istnieją. Naprawdę upewnij się, że twoje frameworki wypełniają luki w frameworku .Net i nie istnieją tylko ze względów estetycznych (na przykład „Nie lubię frameworku .Net tutaj” lub być może przedwczesnej optymalizacji )
Wprowadzenie kolejnej warstwy do architektury wiąże się ze znacznymi kosztami złożoności. Dlaczego warstwa istnieje? Widziałem fałszywe ponowne użycie, to znaczy, że kod jest zbudowany na bazie wewnętrznego frameworka. Byłoby o wiele bardziej wydajne wdrożenie go bezpośrednio na standardowych bibliotekach.
Korzystanie ze znormalizowanych technologii (takich jak .Net Framework i popularne biblioteki stron trzecich / bibliotek open source) ma zalety, które często przewyższają porównywalne korzyści technologiczne wynikające z jego samodzielnego zbudowania. Łatwiej jest znaleźć talent, który zna te technologie, a Twoi obecni programiści zainwestują więcej w naukę tego.
Moje rekomendacje:
źródło
W przypadku małych fragmentów kodu - powiedzmy pojedynczej klasy bez zależności - zwykle kopiujemy i wklejamy kod do projektów. To brzmi jak naruszenie OSUSZANIA i muszę przyznać, że czasami tak jest. Ale w dłuższej perspektywie okazało się to znacznie lepsze niż posiadanie jakiegoś ogromnego, wielogłowego projektu wspólnego z kilku powodów.
Po pierwsze, łatwiej jest mieć pod ręką kod, szczególnie podczas budowania i debugowania.
Po drugie, niezmiennie będziesz chciał dokonać drobnych poprawek wspólnego kodu dla tego projektu. Jeśli masz lokalną kopię źródła, możesz po prostu wprowadzić poprawki i nazwać to dniem. Jeśli istnieje biblioteka współdzielona, możesz ją ulepszyć, a następnie upewnić się, że nie zepsujesz wszystkich innych aplikacji lub nie stworzysz koszmaru wersji.
Więc jeśli nie jest wystarczająco rozbudowany, by stworzyć własną przestrzeń nazw, zwykle popychamy go do odpowiednich części projektu i nazywamy to dniem.
źródło
Drugie rozwiązanie, które opisujesz, nie jest takie złe. W .NET odwołujesz się również do zestawu z GAC, nawet jeśli używasz tylko jednej jego klasy. „Przeciąganie nieistotnego kodu” nie jest problemem, jak mogłoby się wydawać. W takim przypadku konieczne jest przynajmniej uporządkowanie powiązanych metod i klas w różnych przestrzeniach nazw. Ponadto należy zastosować dobre praktyki projektowania interfejsu API, aby zapobiec bałaganowi w tym rozwiązaniu.
Jeśli chodzi o bardzo małe fragmenty kodu, myślę, że następujące podejście jest dobrym uzupełnieniem wspólnego projektu: Pozwól na ich powielanie w różnych rozwiązaniach. Postępuj z nimi jak najlepszymi praktykami: udokumentuj i przekaż je zespołowi.
źródło
Pracowałem tylko w środowiskach „korporacyjnych”, w których tego rodzaju problem był problemem i za każdym razem była to druga przyjęta opcja. W przeważającej części działa dobrze, ponieważ nie było żadnych ograniczeń dotyczących śladu aplikacji.
Jednak po ostatnim tygodniu spędzonym ze start-upem, który prowadzi własny serwer Nuget, jestem skłonny zaproponować to jako realną alternatywę. Oczywiście problemy, które się pojawią, będą dotyczyły zdolności odkrywania.
Jeśli projekty są odpowiednio szczegółowe, a przestrzenie nazw są sensowne, widzę, że staje się to popularnym podejściem w niektórych miejscach.
źródło
Niedawno o tym pomyślałem i przyszła mi do głowy duża biblioteka popularnych metod, o których wspomniano do tej pory, ale z pewnym zdziwieniem. Projekt biblioteki pozwoliłby ci skonfigurować w czasie kompilacji, które elementy są uwzględnione, podobnie jak projekt BusyBox . Dzięki takiemu podejściu możesz uzyskać repozytorium biblioteki w stylu zlewozmywaka kuchennego, ale chwytaj tylko narzędzia potrzebne podczas kompilacji.
źródło
GitHub ma bardzo przydatne narzędzie do zapisywania fragmentów kodu https://gist.github.com/
Przechowuje twoje fragmenty jako repozytoria git, które możesz zachować jako prywatne, lub użyć do udostępniania fragmentów innym osobom.
źródło
W zależności od wielkości zespołu / projektu / firmy będzie to raczej trudne do zrobienia skutecznie, chyba że jakoś jest już wbudowane w twoje środowisko, a każde znalezione rozwiązanie (jeśli je wdrożysz) będzie kosztować trochę pieniędzy. (Może cię to bardziej zabezpieczyć, ale nie będziesz w stanie łatwo zmierzyć). Musisz sprawdzić, czy jest wart swojej ceny. Należy również pamiętać, że rozwiązania wielokrotnego użytku stają się abstrakcyjne i często pasują do wielu sytuacji, ale nie są optymalne.
W każdym razie, jeśli chcesz to zrobić dla kodu wygenerowanego przez więcej niż jedną osobę, najpierw potrzebujesz świadomości wszystkich i współpracy. Dotyczy to programistów i menedżerów.
Następnie upewnij się, że znasz zakres, w którym chcesz to zrobić. Zespół? Projekt? Departament? Firma? W zależności od odpowiedzi, rodzaj kodu, który umieścisz w takich rozwiązaniach, będzie się różnił, podobnie jak szczegółowość, z jaką dostosujesz biblioteki DLL. Kiedy już zdecydujesz się na to, ktoś (najlepiej z entuzjazmem dla pomysłu - ty?) Powinien usiąść i zacząć nadawać temu strukturę.
Jednak samo utworzenie takich bibliotek DLL nie wystarczy, aby załatwić sprawę. Aby były użyteczne, musisz je zareklamować (użytkownikom i współpracownikom) i utrzymywać je jak każde inne oprogramowanie, co zwykle oznacza, że musisz powierzyć komuś odpowiedzialność za nie przez długi czas. Będziesz także potrzebować wiarygodnej dokumentacji, która również będzie wymagała konserwacji. Przy odrobinie szczęścia i współpracy możesz skończyć z najlepszymi praktykami, ale równie dobrze może ewoluować do własnego projektu, w zależności od wielkości i liczby zaangażowanych zespołów. Do tego nadal będziesz potrzebować wsparcia zarządzania.
źródło
często mam problemy, a moim preferowanym rozwiązaniem jest opublikowanie kodu w repozytorium obsługującym sieć github / pubic. rozwiązuje wiele problemów -
Jedną rzeczą polecam - bez względu na to, gdzie przechowujesz swoje fragmenty, zawsze korzystaj z google przed użyciem. rzeczy cały czas się zmieniają. zapisane fragmenty oszczędzają czas, ale także sprzyjają samozadowoleniu .
źródło
Mamy osobne „narzędzia” projektu, w których przechowujemy wszystkie te małe metody wraz z testami.
Gdy projekt potrzebuje jakiegoś narzędzia, po prostu dodaje plik źródłowy wymaganą metodą z „dodaj jako link”.
Oznacza to, że nie dodano żadnych zależności w czasie wykonywania (chyba że dołączony plik tego potrzebuje).
System działał dobrze, ale podobnie jak wszystkie inne, należy przewidzieć, co to jest narzędzie. Wymaganie wysokiego zakresu testów sprawdziło się u nas dobrze, a testy stanowią również dobrą dokumentację użytkowania. Odkrycie wciąż jest dla nas nierozwiązanym problemem.
Jedną z komplikacji związanych z projektem użyteczności jest wybór poziomu widoczności przedmiotów. Ogólna zasada jest taka, że metody powinny być wewnętrzne, a struktury danych - publiczne.
źródło
Moja firma korzysta z lokalnych usług intranetowych. Mamy kilka usług internetowych skonfigurowanych jako wspólne wewnętrzne usługi sieciowe, a gdy inny projekt potrzebuje dostępu do jednej z usług, wysyła żądanie HTTP ze zdefiniowanym interfejsem. Ponieważ znajduje się w intranecie, mieszczącym się w tej samej farmie serwerów, żądania te są bardzo szybkie.
Oczywiście działa to tylko z aplikacjami internetowymi (i działa tylko w milisekundach, gdy jest w tej samej sieci lokalnej), ale ma kilka naprawdę fajnych zalet.
źródło
Niedawno wymyśliłem tę usługę: Snip2Code ( http://www.snip2code.com ).
To interesujący sposób na udostępnianie tylko fragmentów kodu (nie tylko bibliotek) zespołowi. Przełamuje zwykły sens tworzenia wspólnych bibliotek, do których należy się odwoływać w innych projektach, i moim zdaniem jest to cenna wizja.
Ponadto istnieje wiele scenariuszy, w których użycie wspólnej biblioteki po prostu nie ma zastosowania: rozważmy na przykład niektóre wzorce projektowe, takie jak Singleton, strategia lub obserwator. Możesz tworzyć biblioteki do obsługi takich wzorców, ale wciąż nie ma 100% zasięgu.
Rzeczywistą potrzebą jest posiadanie narzędzia do dzielenia się powszechnymi praktykami w zespole. Próbowałem użyć Gistub, ale utknąłem w ich poszukiwaniu (naprawdę kiepskim) i w tym, że nie mogę dzielić się nimi tylko z moim zespołem, a nie z innymi ...
(Oświadczenie: Jestem jednym z założycieli Snip2Code i byłem razem z moimi współzałożycielami w tym samym nastawieniu jakiś czas temu: dlatego postanowiliśmy rozpocząć ten projekt !!)
źródło