20 bibliotek do najprostszych zadań?

1

Moje zwyczajowe podejście: Jeśli mam coś do napisania, co wydaje się być proste, to piszę to samodzielnie, bo wychodzę z zalożenia, że szukanie i uczenie sie biblioteki, która robi to za mnie, zajmie więcej czasu. Natomiast jeśli zadanie wydaje sie być na tyle trudne bądź skomplikowane, ze nie sądze, bym był w stanie zrobić je samodzielnie w rozsądnym czasie, a przy tym zadanie wydaje się byc na tyle generyczne, że ktoś musiał je juz rozwiązać, wtedy szukam biblioteki. (Np. do świętej pamięci mona (może jeszcze zmartwychwstanie...), kiedy musiałem narysować graf, wtedy poszukałem biblioteki do tego - także uzyłem zewnętrznej biblioteki do serializacji/deserializacji JSONa - ale to jedyne zewnętrzne biblioteki, jakich użyłem. A przepraszam, jeszcze użyłem 3-ciej biblioteki, do parsowania zakresów IP, bo zrobienie tego samodzielnie wymagałoby wczytania się w RFCy, więc ten wymóg w mojej świadomości usprawiedliwił użycie biblioteki).

Psioczenie, jakie czytam na tym forum od czasu do czasu, że devowie JS nie umieją samodzielnie wykonać najprostszych zadań i do każdej pierdoły korzystają z biblioteki, przez co z NPMa robi się smietnik, utwierdził mnie w przekonaniu, że postępuję słusznie.

Moje (skromne jeszcze) doświadczenie, z którego wynika, że szefowie zazwyczaj dążą do minimalizacji ilości zewnęntrznych zależności też mnie utwierdził w przekonaniu, że postepuję słusznie.

Na przykładzie: Aplikacja ASP.NET ma pisać logi do pliku. OK, pisanie do pliku, zadanie trywialne, zrobie to samodzielnie. Napisałem wraz z kolegą prościutką biblioteczkę do pisania logów, zarówno do pliku jak i do eventLoga. Używamy jej.

Ale teraz pojawiają się problemy. Serwer ASP.NET raczej nie powinien blokować. Więc pisanie do pliku powinno użyc WriteLineAsync. Ale z drugiej strony nie wolno, by wiele wątków/procesów pisało do tego pliku wspóbieżnie. Rozwiązanie proste - lock. Ups, ale połączenie tych dwóch wymogów już nie jest proste - nie wolno awaitować w locku.

public static class Log 
{
    public static string LogFile {get; internal set;}
    public static string AppName {get; internal set;}

    public static async Task Log(string message)
    {
        LogToEv(message);
        await LogToFile(message);
    }

    private static async Task LogToFile(string message)
    {
        lock(LogFile)
        {
            using(var writer = new StreamWriter(LogFile, append: true)
            {
                await writer.WriteLineAsync($"[{DateTime.Now:g}]: [{AppName}]: {message}"); // Zakazane!
            }
        }
    }
}

Pewnie da sie to prosto rozwiązać jakimiś mutexami, ale to musi być częsty problem - co mi szkodzi - zapytam się kogoś, jak to się robi, może być tak że tu jest jakiś "gotcha" w który wpadnę, jeśli spróbuję zrobić to samodzielnie w najprostszy sposób, jaki mi przychodzi do głowy.

Pytam sie na C# Discordzie. Dyskusja przebiega mniej więcej tak:

Ja: pytam sie o powyższe

Odpowiedź: Czemu nie używasz biblioteki, takiej tak Serilog, która to robi?

Ja: Przecież pisanie do pliku to trywialne zadanie, czy potrzebuję do tego bibliotki?

Odpowiedź: Ty nie chcesz tylko pisać do pliku, ty chcesz robić to w sposób nieblokujący, a Serilog to robi i rozwiązuje problemy, na które teraz wpadasz.

Ja: Zaraz, chyba jestem głupi. Tu w ogóle nie potrzebny jest async. Async słuzy do tego, by nie blokować, by umożliwić jednoczesne przetwarzanie requestu przez wiele procesów. Ale przecież dokładnie tego musimy zakazać, gdy piszemy do pliku. Rozwiazanie proste - tutaj blokowanie jest konieczne, zostawić lock, wyrzucić async.

Odpowiedź: Czemu nie uzywasz biblioteki, takiej jak Serilog, która to robi i rozwiązuje problemy, na które teraz wpadasz?

Ech. W ten sposób niewiele się nauczyłem.

Oprócz jednego. Czy moje podejście unikania używania dziesięciu zewnętrznych bibliotek do zadań, które wydają się być proste, rzeczywiście jest słuszne? Może powinienem jednak przeprosić sie z długą listą zewnętrznych zależnosci i poświęcic czas na czytanie dokumentacji wszystkich tych bibliotek? (Zamiast przeznaczyć czas na poznanie mniejszej ilości narzędzi, za to bardziej dogłebnie, czyli w szczególności dobrze poznać C#?)

Albo właśnie przeciwnie, ta "dyskusja" udowodniła słusznośc mojego podejścia? Po prostu ludzie, którzy nic nie umieli powiedzieć ponad "użyj Seriloga" to sa owi programiści, którzy samodzielnie nie potrafią wykonać najprostszych zadań i dlatego do każdego kiwnięcia lewym palcem u prawej nogi potrzebuja zewnętrznej biblioteki? Nic nie mogli powiedzieć, bo nic nie wiedzą, w szczególności pojęcia nie mają, jak w C# działa async?

2

W czasie pracy w jednej z firm miałem okazję pisać swoje rzeczy kiedy nie musiałem. Nauczyłem się przy tym trochę i to było fajne. Tyle, że zazwyczaj nie ma sensu wynajdywać koła na nowo jeśli ktoś już napisał bibliotekę wykonującą dokładnie to czego oczekujesz, do tego prawdopodobnie bardziej rozbudowaną i co najważniejsze - mocno przetestowaną przez tysiące innych użytkowników.

Użycie znanej biblioteki ułatwia też pracę innym osobom, które prawdopodobnie spotkały się już z nią w czasie pracy gdzie indziej albo mogą zajrzeć do dostępnej online dokumentacji, poprzeglądać issues na githubie albo znaleźć odpowiedzi na jakieś inne pytania np na stacku. Przy twojej własnej implementacji pewnie tego nie ma.
Przy zadaniach trywialnych może nie ma to wielkiego znaczenia ale przy rzeczach krytycznych (jak np. szyfrowanie) może się to skończyć mniejszą lub większą katastrofą.

Async słuzy do tego, by nie blokować, by umożliwić jednoczesne przetwarzanie requestu przez wiele procesów

no nie do końca

Moim zdaniem nie robisz do końca słusznie ale jest to zależne od osoby która ci za to płaci. Jeśli ona się na to zgadza (albo są też takie wymogi to ok). Ja jednak płacąc programiście oczekiwałbym, że on będzie on skupiony na rozwiązywaniu problemów mojej firmy a nie pisaniem którejś z kolei biblioteki do logowania, którą i tak pewnie ktoś wymieni na Serilog czy NLog

0

Aż z ciekawości popatrzyłem na kod źródłowy Seriloga i nie wygląda, żeby pisał do pliku asynchronicznie - ale może patrzyłem w złym miejscu :P Bo mają chyba jakieś extensiony do asynców

7

Czy moje podejście unikania używania dziesięciu zewnętrznych bibliotek do zadań, które wydają się być proste, rzeczywiście jest słuszne?

TLDR: NIE JEST.

Już ze 3 razy widziałem w karierze jak programista robił prościuteńką biblioteczkę do wczytywania CSVki i potem było z tego łatanie 100 bugów przez 3 miesiące.

Ja do tego podchodzę tak, jak bierzesz "wygrzaną" bibliotekę to cała gama osób spędziła już nad nią pewnie z 2 lub 3 osobolata. Biblioteka ta była używana w najprzeróżniejszych konfiguracjach oraz z najróżniejszymi stackami technologicznymi. Biblioteka ma dokumentację oraz całą masę odpowiedzi na SO na najczęstsze problemy. Prawie wszystkie bugi które mogły się w niej znajdować zostały już znalezione i naprawione. Na koniec ponieważ biblioteka była (o ile jest wystarczająco popularna) używana w aplikacjach które dbają o wydajność to z pewnością jest też doszlifowana od tej strony (czyli w przypadku logowania używa się np. bufora in-memory + osobnego wątku który loguje zdarzenia do pliku + shutdown hooki żeby przy gwałtownym zamknięciu aplikacji niczego nie stracić).

Jeżeli chcesz pisać nowy kod od zera to polecam skoncentrować się na rzeczach do które jeszcze nie_ma bibliotek. Ewentualnie niech twój młody duch dołączy do społeczności open source i zamiast przepisywać zacznij kontrybuować!

3

Ja bym zaczął leczyć syndrom not invented here, zazwyczaj te niby lepsze alternatywy do szeroko stosowanych bibliotek to wbrew zapewnieniom twórców ulepy bez ładu i składu, a biblioteki OS weryfikuje społeczność i słabe rzeczy mają mało gwiazdek na GH.

3
kmph napisał(a):

Hmm, to jak pisałem kiedyś cos w JS to też powinienem był użyć jquery + react (czy która tam obecnie jest w modzie) + 10 innych? Wyszedłem z założenia, że aby napisać coś w JS i tak musze nauczyć się JS, a jeśli dołożę do tego 10 najpopularniejszych frameworków to będę miał 10x więcej nauki = nigdy nie zacznę pisać

Ale wiesz, że żadna z tych rzeczy nie wymaga uczenia się przed rozpoczęciem pisania? Bo Ty chcesz robić taki waterfall w nauce - nauczyć się wszystkiego, dopiero wtedy zacząć. I może z tego wynika, że od użycia Seriloga (mniej niż 10 minut) przechodzisz do rozumienia codebase biblioteki.

0
Saalin napisał(a):

Ja bym zaczął leczyć syndrom not invented here, zazwyczaj te niby lepsze alternatywy do szeroko stosowanych bibliotek to wbrew zapewnieniom twórców ulepy bez ładu i składu, a biblioteki OS weryfikuje społeczność i słabe rzeczy mają mało gwiazdek na GH.

Zaczynam wierzyć, że zanim zacznę pisać w jakimkolwiek języku, to powinieme przejrzeć 20 najpopularniejszych bibliotek do tego języka. I przestawić mentalność z: Mam problemy? Szukam biblioteki! Na: Jest biblioteka? Jeśli nie, to piszę sam -- no ale do tego trzeba po pierwsze orientować się w 50 bibliotekach, bo jeśli ich nie znam (bo szkoda mi czasu na naukę) to nawet nie wpadnie mi do głowy, że w ogóle powinienem do tego szukac biblioteki.

Np. JQuery - DOM manipulation w JS. Przecież JS ma własne narzędzia do DOM manipulation: appendChild, getElementByXPath, itp. Stąd, gdybym z góry nie wiedział, że istnieje coś takiego jak jQuery, to w ogóle nie wpadłoby mi do głowy, że nalezy czegokolwiek szukać dla celów DOM manipulation.

Tak samo logowanie - wydaje się być równie trywialne, jak pisanie do pliku. A przecież są w C# narzędzia do pisania do pliku. Dlatego byłem zdziwiony, ze w ogóle należy szukać biblioteki do czegoś, co zdaje się na oko, ze język wspiera out of the box.

3

Spłycasz problemy i wydaje Ci się, że rzeczy są proste i trywialne, a nie są. Przykład: ostatnio poprawiałem buga w kodzie, który wyglądał mniej więcej tak

Task Login(string username, string password) {
    var loginJson = $"{ \"username\": \"{username}\", \"password\": \"{password}\" }";
...
}

Bo są ludzie, którzy uważają, że taki JSON to banał i po co używać Newtonsofta (który zazwyczaj i tak w projekcie jest), a później się okazuje, że ktoś w password ustawił sobie ". Wystarczyło wrzucić w anonymous object, zserializowac i nikt o escape'owaniu nigdy by nie pomyślał.
Gorzej, że są ludzie którzy w takiej sytuacji dalej by brnęli to to bagno i zaczęli escape'ować z ręki.

0

zadanie trywialne, zrobie to samodzielnie.
(...)
zadań, które wydają się być proste

zadanie trywialne, zadania, ktore wydają się proste to są tylko hipotezy, które należałoby sprawdzić robiąc eksperyment / PoC. Pytanie, ile taki eksperyment by trwał. Czasem lepiej takie rzeczy rozwojowe robić we własnym czasie. Robiąc coś dla siebie możesz się bawić tygodniami robiąc coś, "co wydaje się być proste" (i jeśli faktycznie okaże się proste, to będziesz miał podstawy, żeby używać tego w pracy), natomiast niestety nie zawsze będzie na to czas na produkcji.

Tylko, że tak samo można powiedzieć o bibliotekach. Jak ktoś instaluje randomową bibliotekę z NPMa, której nigdy nie używał, to nie ma pewności, że będzie to dobra biblioteka, więc jest to eksperyment. Zainstalowanie gotowej biblioteki nie gwarantuje niczego (szczególnie jeśli to biblioteka mało popularna, zabugowana i nie utrzymywana od lat, a takich pełno na NPMie).

Dlatego często mniejszym ryzykiem jest napisanie czegoś z palca (jak się wie, jak napisać) niż użycie podejrzanej paczki z NPMa.

także uzyłem zewnętrznej biblioteki do serializacji/deserializacji JSONa

I prawidłowo. Ogólnie do parsowania takich rzeczy jak JSON czy innych formatów lepiej używać albo tego, co jest w języku albo gotowej biblioteki, która jest sprawdzona, przetestowana i ma pofiksowane bugi. Bo nie chodzi o to, że nie można by tego zrobić samemu, tylko o edge case'y. Ew. można polecieć partyzantem jak niektórzy i użyć paru regexpów, ale wtedy bugi będą lać się strumieniami.

Pytanie więc, jakie problemy chcesz rozwiązywać. Jak robisz wszystko od zera, to twoją robotą będzie robienie biblioteki, a nie aplikacji (co nie musi być złe, niektórzy mają nawet płacone za robienie bibliotek).

1

W ogóle to jest rozwiązanie na te problemy, wybierz sobie stosunkowo nowy język, a nie taki rozwijany 20 lat i będziesz musiał implementować biblioteki od zera. Tylko wg mnie to jest argument za nieuzywaniem danego języka.

0

O, ciekawe znalezisko: https://www.nuget.org/packages/automapper/

Kolejna rzecz, na którą NIGDY bym nie wpadł, że należy do tego szukac biblioteki. Może i zacznę używać, ale musiałem skądinąd się dowiedzieć, że istnieje do tego biblioteka...

2

Jak nie kojarzysz Automappera to może serio sobie ogarnij z czego się korzysta w .NET, bo może być więcej takich zaskoczeń. I to mimo że akurat nie przepadam, za tą biblioteką.

3

"Czy warto pisać samemu libki (na proda)"

Według mnie:

Punkty na nie:

  • Możesz nie mieć wystarczającej wiedzy w danej tematyce aby napisać coś sensownego

  • Zajmie Ci to prawdopodobnie jakąś znaczną ilość czasu aby napisać coś prod-ready zamiast 15min z nugeta+przeczytanie doca

  • Jeżeli napisałeś już samemu libkę, to pewnie warto by ją używać w innych projektach, bo przecież nie będziesz w każdym kopiował klasy od nowa, więc trzeba wrzucić na firmowego nugeta (a co jeżeli go nie ma) lub o (o boże) referencje do projektu dokładać (i liczyć że libka będzie działać w starych i nowych .NETach)

  • Musisz napisać dokumentacje

  • Musisz to utrzymać, bo edge casy prawie na pewno się pojawią

  • Bierzesz odpowiedzialność za ten kod i gdy będą problemy to ludzie będą do ciebie walić (pewnie nawet gdy błąd będzie nie u ciebie :D)

  • Utrudniasz nowym pracownikom wejście w projekt, bo muszą poznać wewnętrzne narzędzia zamiast tzw. "industry standards"

Punkty na tak:

  • Jeżeli jest to corowy komponent systemu, to lepiej byłoby mieć pełną kontrolę nad nim jeżeli was na to stać.

  • Oczywiście jeżeli istniejące popularne libki nie spełniają waszych wymagań / mają błędy.

  • Jeżeli jesteście w stanie ocenić czy jesteście w stanie na tym coś zyskać (zarobić, czas, zyskać elastyczność)

  • Jest to bardzo rozwijające.

  • Jeżeli nie ufasz (lub twoja firma / kontrakty DoD itd.) np. pod względem bezpieczeństwa tym 3rd party.

Raczej odradzam próbowanie pisać bibliotek do obsługi pdfów, csv, jsonów, xmli, exceli, http wrapperów i dużo więcej jeżeli już wcześniej tego nie robiłeś.

A co do twojego loggera - jeżeli jest to aplikacja 1 wątkowa, nierobiąca zbyt dużo to może być, ale w aplikacji webowej ja osobiście bym nie pisał loggera z ręki, bo pewnie zabiłbym wydajność :D na pewno wolałbym wziąć to jako jakiś side-project, samemu się pobawić i zobaczyć czy moje rezultaty są chociaż porównywalne z tymi "industry standards"

Może powinienem jednak przeprosić sie z długą listą zewnętrznych zależnosci

Czy naprawdę taką długą? tak z 80% zewnętrznych bibliotek (nie microsoftowe itd.) jakie używam, to po prostu obsługa: loggera, csv, json, pdf, excel, http.
I one prawie zawsze wyskakują pod wynikami zapytania do Googla C# <problem> library

którzy samodzielnie nie potrafią wykonać najprostszych zadań i dlatego do każdego kiwnięcia lewym palcem u prawej nogi potrzebuja zewnętrznej biblioteki? Nic nie mogli powiedzieć, bo nic nie wiedzą, w szczególności pojęcia nie mają, jak w C# działa async?

Czym innym jest rozwijać sobie na boku libkę do czegoś fajnego, a czym innym jest wrzucanie tego na proda do jednego lub wielu projektów i branie za to odpowiedzialności - generalnie chcemy minimalizować ryzyko.

Cytując klasyka:

"Można zaoszczędzić 15min czytania dokumentacji libki N godzinami developmentu", pytanie czy warto?

2
public static class Log 
{
    public static string LogFile {get; internal set;}
    public static string AppName {get; internal set;}

    public static async Task Log(string message)
    {
        LogToEv(message);
        await LogToFile(message);
    }

    private static async Task LogToFile(string message)
    {
        lock(LogFile)
        {
            using(var writer = new StreamWriter(LogFile, append: true)
            {
                await writer.WriteLineAsync($"[{DateTime.Now:g}]: [{AppName}]: {message}"); // Zakazane!
            }
        }
    }
}

W ogóle dlaczego ten twój logger nie wyrzuca na konsole? chciałbym sobie podczas developmentu patrzeć co tam leci

aaa i jeszcze jakby kolorki były, bo jak dużo rzeczy leci na konsole to chciałbym błędy widzieć na czerwono

a co z usuwaniem starych logów? przecież gupio będzie jak się uzbiera z 500MB logów, te stare trzeba byłoby pewnie wywalić...

a mógłbyś to rozbijać na pliki z nazwą YYYY-MM-DD.txt i np. te starsze niż 14 dni usuwać?

albo może nie, dajmy inny format nazwy bo klient chce aby mu te logi mailem wysyłać i chce aby to się nazywało XD_APP_YYYY_MM_DD_HH_mm.log

więc w sumie może jakiś plik konfiguracyjny? np. manago pewnie lubią xmla, albo ten, no - niech się z kodu też da skonfigurować

a czemu klasa statyczna? niektórzy lubią wstrzykiwanie przez DI

a jakbym chciał aby np. na prodzie zapisywał się tylko Error i Warning, a Information tylko na developie?


w sumie, to te wszystkie rzeczy już ma Serilog - no może poza kolorkami na konsole, ale tutaj faktycznie możesz sobie napisać swój 10 linijkowy wrapper, a Serilogowi pozwolić działać na plikach.

0

W ogóle dlaczego ten twój logger nie wyrzuca na konsole? chciałbym sobie podczas developmentu patrzeć co tam leci

Lepiej, wyrzuca się na GUI

aaa i jeszcze jakby kolorki były, bo jak dużo rzeczy leci na konsole to chciałbym błędy widzieć na czerwono

Sysadmin wysyła errory na czerwono na maile, jak on to zrobił że w thunderbirdzie tematy maili sa na czerwono pojęcia nie mam

a co z usuwaniem starych logów? przecież gupio będzie jak się uzbiera z 500MB logów, te stare trzeba byłoby pewnie wywalić...

Jest jako todo...

a mógłbyś to rozbijać na pliki z nazwą YYYY-MM-DD.txt i np. te starsze niż 14 dni usuwać?

Punkt pierwszy zrobiony, punkt drugi nie

albo może nie, dajmy inny format nazwy bo klient chce aby mu te logi mailem wysyłać i chce aby to się nazywało XD_APP_YYYY_MM_DD_HH_mm.log

no tak, nie ma

więc w sumie może jakiś plik konfiguracyjny? np. manago pewnie lubią xmla, albo ten, no - niech się z kodu też da skonfigurować

nie używamy app.config bo tak szef zadecydował. więc i tak mamy własny plik konfiguracyjny

a czemu klasa statyczna? niektórzy lubią wstrzykiwanie przez DI

(a) jestem skazany na ASP.NET zamiast Core - kompatybilnośc z konieczną biblioteką zewnętrzną - a w asp.net czystym chyba się to robi odrobinkę mniej trywialnie (b) ludzi konfudować nie chcę - chyba jako jedyny słyszałem tam o DI (c) sam musiałbym nauczyc sie jak to się robi w asp.net a nie core a tym razem nie chcę powtórzyć błedu z poprzedniej pracy więc chcę skupić się przede wszystkim na tym żeby zrobić jak najszybciej co się ode mnie wymaga (natomiast na dalszy plan odkładam zgodnośc mojego kodu z dogmatami)

ale kiedy zewnętrzna biblioteka przejdzie wreszcie na core'a (mają to niby zrobić) to chyba się zrobi DI i także zacznie wykorzystywać konfigurację która jest out of the box w core

a jakbym chciał aby np. na prodzie zapisywał się tylko Error i Warning, a Information tylko na developie?

zrobione w tym sensie, że poziom komunikatów jest w pliku konf.

0

@kmph

Nie chodziło o to, abyś się tłumaczył :P

Chodziło o to, ze z tak prostej rzeczy nagle robi się wiele różnych casów / scenariuszy gdy chcesz ją zastosować w wielu projektach lub przez różnych ludzi mających różne wymagania/oczekiwania - o tym pisałem wcześniej, raczej nie po to stworzysz własną implementacje loggera aby teraz ją tylko użyć w 1 projekcie

1

Ja w ogóle nie rozumiem podejścia, że trzeba przejrzeć i poznać 20 najpopularniejszych bibliotek. Mam problem i go rozwiązuje. W tym czasie zastanawiam się czy ktoś już go nie rozwiązał chociaż częściowo, czy potrzebuję czegoś np z zakresu infrastruktury (co już w sumie powinno istnieć) i skupiam się tylko na tym.
Nie mówię że wiedza jest niepotrzebna bo jest potrzebna. Tylko że dobrze napisano - robienie waterfalla w nauce nie ma najmniejszego sensu bo jak się uprzesz to nigdy nie podejdziesz do próby rozwiązania problemu ze względu na to, że jeszcze nie znasz języka zbyt dobrze. Narzędzie dobrze poznaje się przy pracy z nim.

1
var napisał(a):

Ja w ogóle nie rozumiem podejścia, że trzeba przejrzeć i poznać 20 najpopularniejszych bibliotek.

C# nie znam, ale dla Javy nie umiałbym wymienić 20 najpopularniejszych bibliotek. Niby o większości z tego artykuły słyszałem, ale połowy nie używałem. W dodatku wiele z punktów jest dla mnie sporne (co innego jest najpopularniejsze, a co innego uważam za najlepsze)

3

No ja tu widzę dwie możliwości:

  • albo firma jest tak bogata, ze stać ją aby pisać wszystko po swojemu;
  • albo za pisanie kodu płacą tam mniej niż gdzie indziej za programowanie.
    I chyba nawet się domyślam się, jaka jest odpowiedź. ;)

W mojej opinii programista .NET z takich często używanych bibliotek powinien znać:
Obsługa bazy danych: Entity Framework, NHibernate, Dapper
Unit testy: xUnit, NUnit, Moq, NSubsittute, FluentAssertions
Logowanie: NLog, Serilog
IoC: Autofac, Ninject, Simple Injector, to śmieszne gównienko od Microsoftu
Różne: AutoMapper, Newtonsoft, Swashbuckle, Polly, MediatR, FluentValidation
A reszta, to już w zależności od zadania, jak trzeba eksportować do PDF, czytać z CSV czy używać S3 albo czegokolwiek innego w jakiejś chmurze, to się szuka do tego libki.

Czy to dużo? Nie sądzę, bo te biblioteki w ramach swoich grup są dość podobne, a przynajmniej operują na podobnych konceptach.

Poza tym, że używając gotowej biblioteki w dłuższej perspektywie oszczędzamy czas pracy i zyskujemy na stabilności rozwiązania, to ułatwiamy sobie przyszłość. Zazwyczaj inne firmy nie są tak bogate, żeby pisać wszystko po swojemu i używają gotowych bibliotek. Jeśli się ich nie zna, to może być ciężko zmienić pracę.

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