Czy ramy nakładają zbyt wiele abstrakcji? [Zamknięte]


24

Programuję od nieco ponad roku i mam doświadczenie w pisaniu aplikacji systemowych, aplikacji internetowych i skryptów dla firm / organizacji. Jednak jedna rzecz, której nigdy tak naprawdę nie zrobiłem, to praca z frameworkiem takim jak Django, Rails lub Zend.

Patrząc na środowisko Django, jestem trochę sfrustrowany tym, jak bardzo jest on abstrakcyjny w ramach. Rozumiem podstawowe cele DRY i minimalnego kodu, ale wydaje się, że niektóre z tego nadmiernego polegania na różnych modułach i dużej abstrakcji podstawowych funkcji:

  1. Sprawia, że ​​programy są naprawdę szybko datowane z powodu ciągle zmieniającej się natury modułów / ram,

  2. Utrudnia zrozumienie kodu z powodu mnogości dostępnych frameworków i modułów oraz wszystkich ich osobliwości,

  3. Uczynia kod mniej logicznym, chyba że przeczytasz całą dokumentację; tzn. potrafię odczytać niektóre wyliczenia i logikę warunkową oraz dowiedzieć się, co robi program, ale kiedy zobaczysz funkcje wymagające przekazywania dowolnych ciągów znaków i słowników, sprawy stają się trochę trudne do zrozumienia, chyba że jesteś już guru dany moduł; i:

  4. Utrudnia i uciążliwe jest przełączanie między ramami. Przełączanie języków jest już wyzwaniem, ale jest możliwe do opanowania, jeśli dobrze rozumiesz ich podstawową funkcjonalność / filozofię. Przełączanie między ramami wydaje się być bardziej kwestią zapamiętywania na pamięć, co w pewien sposób wydaje się sprzyjać bardzo nieefektywności, którą te ramy mają wyeliminować.

Czy naprawdę musimy nakładać około 50 warstw abstrakcji na coś tak prostego jak zapytanie MySQL? Dlaczego nie użyć czegoś takiego jak interfejs PDO PHP, w którym obsługiwane są przygotowane instrukcje / testowanie danych wejściowych, ale powszechnie zrozumiałe zapytanie SQL jest nadal częścią funkcji?

Czy te abstrakcje są naprawdę przydatne? Czy funkcja nie jest nadęta, czyniąc je bezużytecznymi, czyniąc aplikacje trudniejszymi niż podobne aplikacje napisane bez użycia frameworka?


22
Słowa kluczowe: as a relatively inexperienced programmer- im dłużej tworzysz oprogramowanie, tym bardziej docenisz spędzanie mniej czasu na odkrywaniu kierownicy i więcej czasu w domu, robiąc rzeczy, które kochasz.
sergserg

13
Do we really need to put like 50 layers of abstraction on top of something as simple as a MySQL query?- Po pierwsze, dobry framework to jedna warstwa abstrakcji (może 2 lub 3 wewnętrznie), a po drugie „coś tak prostego jak zapytanie MySQL” w rzeczywistości wymaga kilkudziesięciu abstrakcji. Nawet po tym, jak zapytanie wykonane z interpretowanego języka dotarło do serwera bazy danych, nadal masz zapytania dotyczące baz danych nad silnikami, nad systemami plików, nad pamięcią fizyczną. Krótko mówiąc: tak, potrzebujemy abstrakcji, ponieważ powstrzymują nasze głowy przed wybuchem.
back2dos

7
FWIW, tak, czasami wyprzedzamy hydraulikę. Liczba przypadków, w których używam ram do wykonania pracy, jest mniejsza niż początkowo myślałem; czasem pisanie własnego kodu skutkuje prostszym projektem, ściślejszym dopasowaniem do dziedziny problemów i lepszą wydajnością, bez problemów związanych z licencjonowaniem.
Robert Harvey

2
Istnieje wiele mikrocząsteczek. Są to lekkie ramy, które dla niektórych osób są bardziej atrakcyjne. Na przykład: flask.pocoo.org . Nigdy tego nie użyłem.
ipaul

To pytanie przywraca bolesne wspomnienia starej szkoły WCF i LINQ do SQL. Dwa frameworki, które spędziłem dużo czasu walcząc. Ramy, które wystarczająco streszczają, są łatwe do zrozumienia i łatwe do dostosowania to naprawdę rzadki ptak. Ale istnieją.
Phil

Odpowiedzi:


21

Ramy mogą być naprawdę trudne. Problemy mogą łatwo powstać, gdy framework jest zbyt „opiniotwórczy”, tj. Kiedy naprawdę woli jeden konkretny styl aplikacji, a wszystkie części są ukierunkowane na wspieranie tego konkretnego stylu.

Na przykład, jeśli środowisko całkowicie abstrakuje proces uwierzytelniania użytkownika, umożliwiając dodanie tylko jednego komponentu, dodanie gdzieś szablonu logowania i voila, uwierzytelnienie użytkownika jest bezpłatne. Pozwoliło to zaoszczędzić wiele powtarzalnej pracy związanej z martwieniem się o pliki cookie, przechowywanie sesji, mieszanie haseł i tak dalej.

Problemy zaczynają się, gdy zdajesz sobie sprawę, że domyślne zachowanie kodu uwierzytelniającego frameworka nie jest tym, czego potrzebujesz. Może nie przestrzega najnowszych najlepszych praktyk bezpieczeństwa. Być może potrzebujesz niestandardowego haka, aby uruchomić jakieś działanie, ale framework go nie oferuje. Być może musisz zmienić szczegóły ustawianego pliku cookie, ale środowisko nie oferuje możliwości dostosowania tego.

Abstrakcja udostępniona przez platformę pozwoliła na dodanie ważnej funkcji do witryny w ciągu kilku minut zamiast dni, ale w końcu być może będziesz musiał walczyć z ramą, aby zrobić to, czego potrzebujesz, w przeciwnym razie i tak musisz od nowa opracować funkcjonalność od nowa, aby dopasować ją do swoich potrzeb.

Nie oznacza to, że abstrakcje ramowe są złe, pamiętajcie. Trzeba powiedzieć, że jest to zawsze możliwość, o której należy pamiętać. Niektóre frameworki są wyraźnie ukierunkowane na to, oferują sposób na szybkie uzyskanie czegoś jako prototypu lub nawet frameworka produkcyjnego dla bardzo specyficznego, ograniczonego rodzaju aplikacji. Inne frameworki przypominają raczej luźne kolekcje komponentów, których można użyć, ale które nadal pozwalają na dużą elastyczność, aby zmienić je później.

Korzystając z abstrakcji, powinieneś zawsze rozumieć przynajmniej z grubsza, co to jest abstrakcji. Jeśli nie rozumiesz plików cookie i systemów uwierzytelniania, rozpoczęcie od abstrakcji nie jest dobrym pomysłem. Jeśli rozumiesz, co próbujesz zrobić, i potrzebujesz kodu, który już to robi, zamiast żmudnego pisania własnego tekstu, abstrakcje to świetna oszczędność czasu. Źle napisane abstrakcje mogą jednak wpędzić cię w kłopoty, więc jest to miecz obosieczny.


Należy również rozróżnić abstrakcje techniczne od abstrakcji „reguł biznesowych” . Programowanie w języku wyższego poziomu to abstrakcja, której prawdopodobnie nie chcesz przegapić (Python, PHP, C # vs. C vs. Assembler; Less vs. CSS), podczas gdy „abstrakcje reguł biznesowych” mogą być trudne, jeśli nie dokładnie spełniają Twoje potrzeby (uwierzytelnianie jednym kliknięciem vs. ręczne kodowanie plików cookie).

Wynika to z faktu, że abstrakcje techniczne rzadko „wyciekają”, tzn. Nie będziesz musiał debugować kodu maszynowego podczas pisania aplikacji w Pythonie. Abstrakcje reguł biznesowych działają jednak na tym samym poziomie technicznym i są tak naprawdę „pakietami kodów”. Prawdopodobnie będziesz musiał debugować ustawiony plik cookie lub skrót hasłowy, który zostanie utworzony w pewnym momencie, co oznacza, że ​​będziesz nurkować przez wiele kodu firm trzecich.


„Jeśli nie rozumiesz plików cookie i systemów uwierzytelniania, rozpoczęcie od abstrakcji nie jest dobrym pomysłem.” Tak, ale prawdopodobnie nadal jest lepsze niż samodzielne tworzenie od podstaw.
sick

@svick Faster? Tak. Lepszy? To jest dyskusyjne.
lunchmeat317

@ lunchmeat317 Chodzi mi o to, że jeśli ktoś nie wie, co robi i używa frameworka, prawdopodobnie popełni błąd. Ale jeśli sam napisze cały kod, prawie na pewno popełni błąd.
svick

2
Zgodzić się. „Używasz bibliotek, ale frameworki cię używają” to dobry cytat. Potrzebujemy bibliotek wielokrotnego użytku i znacznie mniej frameworków all-in-one.
gbjbaanb

1
@gbjbaanb Bardzo się zgadzam. Zwłaszcza, że ​​frameworki do zlewów kuchennych rzadko mają najwyższą jakość kodu. Najlepsze w swojej klasie biblioteki są często znacznie lepsze niż ogólne wdrożenie frameworka.
deceze

29

Wydaje mi się, że źle rozumiesz abstrakcje i ponownie używasz kodu.

Cały przemysł programistyczny opiera się na abstrakcjach. Tylko dlatego, że nieużywanie ich, tj. Unikanie korzystania z frameworków, bibliotek i ogólnie kodu, który nie jest pisany wewnętrznie, zwiększyłoby koszt produkcji oprogramowania o sto tysięcy, a może nawet więcej.

Podobnie jak nie tworzysz odrzutowca od podstaw, bez korzystania z wiedzy inżynierskiej wypracowanej przez lata przy budowie innych samolotów, nie piszesz oprogramowania biznesowego od zera.

Uzyskujesz to, używając przede wszystkim PHP lub Ruby, masz już wiele abstrakcji, prawda? Najbardziej oczywiste:

  1. System operacyjny, język programowania i kompilator zapewniają ogromną abstrakcję w stosunku do asemblera i sprzętu,

  2. Serwer WWW zapewnia abstrakcję gniazd, przełączania awaryjnego, protokołu HTTP itp.,

  3. SQL zapewnia abstrakcję, w jaki sposób dane są przechowywane w stałej pamięci masowej i przechowywane w pamięci w celu szybszego dostępu, zapewnia ACID, dublowanie itp.

Zawsze możesz spróbować utworzyć aplikację internetową bez użycia systemu operacyjnego, serwera WWW, bazy danych lub języka programowania wysokiego poziomu. Będziesz szybko okaże się, że spędził lata wyważania otwartych drzwi, czyli odtworzenie swój język programowania, swój serwer WWW i swoją bazę danych, biorąc pod uwagę, że ich jakość będzie daleko od jakości produktów, które faktycznie korzystają.

Ramy nie różnią się od tego. Możesz robić to, co oni. Wystarczy, że zmarnujesz czas na przerabianie tej samej funkcjonalności, z tą różnicą, że frameworki zrobią to lepiej i bardzo często ich kod będzie testowany i dokumentowany lepiej niż twój.

Weź przykład wózka dla witryny e-commerce. Możesz wymyślić swój własny i poświęcić kilka tygodni na jego opracowanie, lub możesz wziąć ten, który został opracowany przez lata przez grupę ludzi w ramach. Oczekuje się, że zostaną przetestowane, nie licząc faktu, że w ciągu kilku lat ci programiści odkryli i załatali kilka błędów, których nie wyobrażasz sobie podczas opracowywania własnego koszyka.

Możesz odpowiedzieć, że ich jest bardziej skomplikowana, ponieważ ma więcej przypadków użytkowników. Na przykład ich powinny dotyczyć rabatów, podczas gdy nie masz rabatów na swojej stronie i nie potrzebujesz tej funkcji w koszyku. Cóż, nie jesteś zmuszony do korzystania z tej funkcji i nie jest tak, że wpłynie to negatywnie na wydajność Twojej aplikacji internetowej.

Możesz mieć bardzo podstawowy scenariusz, w którym naprawdę łatwiej jest opracować własny koszyk niż korzystać z istniejącego. Podobnie, jeśli jedyną rzeczą, której potrzebuje Twoja aplikacja, jest przechowywanie listy liczb, nic więcej, nie potrzebujesz bazy danych: wystarczy zwykłe wypełnienie tekstu. W takich przypadkach nie przerabiaj zbytnio swojej aplikacji: proste scenariusze wymagają prostych rozwiązań.

Kolejnym czynnikiem jest czytelność twojego kodu. Wyobraź sobie, że masz witrynę e-commerce. Później opuściłeś projekt i inny programista powinien go utrzymać.

  • Jeśli używałeś wózka dostarczonego przez platformę, twój kolega poczułby ulgę: musiałby zachować mały fragment kodu, który opiera się na niezawodnej, mocno udokumentowanej ramie. Jeszcze lepiej: ten programista mógł zostać wykorzystany do pracy z tym frameworkiem i jest mu znany. Jeśli nie, może zadawać pytania na temat przepełnienia stosu: na pewno ktoś już używał frameworka.

  • Gdybyś miał własny koszyk, wówczas twój kolega musiałby zachować niestandardowy kod, być może nawet nieudokumentowany, bez możliwości uzyskania pomocy w dowolnym miejscu.

Korzystając z frameworka, korzystasz z kodu, który jest:

  • Napisane przez doświadczonych programistów,

  • Często sprawdzane parami,

  • Testowane jednostkowo,

  • Szeroko udokumentowane,

  • Używany od lat przez tysiące programistów,

  • Często obsługiwany, więc możesz zgłosić błąd i zobaczyć, jak został naprawiony,

  • Znany przez wielu programistów, którzy znają możliwe zastrzeżenia i problemy i mogą pomóc w witrynach takich jak Przepełnienie stosu.

  • Dostępne dla ciebie teraz, za darmo.


3
Przepraszam, ale to nie odpowiada na pytanie. Sposób, w jaki to interpretowałem, dotyczy tego, kiedy abstrakcja jest zbyt duża i powoduje problemy, a nie tego, czy abstrakcja i ramy mogą być pomocne. OP wydaje się już rozumieć, że mogą być przydatne. Jednak złe abstrakcje mogą być tak samo bolesne i ograniczające, jak dobre abstrakcje mogą być pomocne i wyzwalające.

3
@MattFenwick - dla mnie OP mówi, że jeśli w ogóle używasz tych ram, abstrakcja posunęła się za daleko i powoduje więcej problemów, niż są warte. Z pewnością pytanie nie brzmi, czy złe abstrakcje są złe?
JeffO,

3

Zgadzam się - większość ram staje się rozdętymi dyktatorami. Obiecują wolność, ale wy jesteście w niewoli. więc spójrz na strukturę przypominającą narzędzie - najlepszym narzędziem jest to, które nie przeszkadza. Jeśli w PHP sugerowałbym sprawdzenie frameworka Codeigniter, ponieważ jest to elegancka równowaga między konwencjami a wolnością i ma wspaniałą społeczność. I do plakatu, który posłużył się przykładem koszyka e-commerce - chciałbym się z tobą zgodzić. ale po zapoznaniu się z kodeksem wielu rozwiązań e-commerce - i zaprojektowaniu kilku - z szacunkiem nie zgadzam się z twoim przykładem.


2

Hmmm Jednym z aspektów LedgerSMB, nad którym dużo pracowaliśmy, było nasze podejście do frameworka. Istnieją jednak dwa podstawowe problemy związane z tego rodzaju abstrakcją. To są:

  1. Wybuch zależności, oraz

  2. Zła abstrakcja

Pierwszy jest w rzeczywistości lepszy niż alternatywa polegająca na ponownym wynalezieniu koła. Drugi jest trudny do opisania, ponieważ może pochodzić ze źle zdefiniowanego przypadku problemu lub, częściej, od osób używających czegoś poza przeznaczeniem.

Spójrzmy na przykład na ORM. Unikam używania ORM, ponieważ bardzo często zdarza się, że db kończy się na modelu obiektowym aplikacji, ponieważ w najlepszym wypadku są to nieszczelne warstwy abstrakcji. Niekoniecznie tak jest. Spotkałem programistów, którym udało się zachować dobry projekt DB i dobrą aplikację podczas korzystania z ORM, ale uciekają się do wielu rzeczy, które według hype orm nie powinny być wymagane, takich jak hermetyzacja relacyjnego API db za aktualizowanymi widokami.

Głównym problemem jest oczywiście to, że im bardziej zautomatyzowany kod, szczególnie gdy jest on również nieprzezroczysty, tym trudniej jest zobaczyć, co się dzieje. Jest to punkt dotyczący ORM, które @jhewlett wysuwa powyżej (patrz /software//a/190807/63722 ).

Dobrym odpowiednikiem może być zaawansowana awionika jako ramy do pilotowania samolotu. Zostały one wysoce zaprojektowane pod kątem niezawodności i są czynnikiem zwiększającym bezpieczeństwo lotu. Jednak, jak zauważa wiele artykułów w IEEE Spectrum, wiąże się to z kosztem możliwości odzyskania na podstawie błędów wykraczających poza to, co jest uważane za dopuszczalne z punktu widzenia automatyzacji. To samo dotyczy debugowania. Debugowanie kodu SQL w programie to jedna rzecz. Debugowanie części programu, która zapisuje kod SQL do użycia przez program, jest czymś zupełnie innym.

Framework LedgerSMB napisaliśmy od zera, ponieważ w chwili, gdy zaczynaliśmy, nie było naprawdę dobrych ram, które działałyby tak, jak byśmy chcieli. W rzeczywistości jest to jedna rzecz, z której jestem całkiem zadowolony, a według nowszego programisty projektu, dostosowanie aplikacji jest bardzo proste. (W rzeczywistości ograniczamy generowanie kodu SQL do minimum i zamiast tego skupiamy się na ręcznie pisanych funkcjach zdefiniowanych przez użytkownika, co oznacza, że ​​części do pisania SQL są bardzo cienkie. Tak, zapewnia dużo abstrakcji w niektórych miejscach, bardziej niż niektórzy programiści czują się swobodnie (w szczególności „odwzorowanie właściwości obiektu na argumenty w tej procedurze przechowywanej” od czasu do czasu nas odsuwa). Staramy się jednak, aby wszystko było proste i spójne, aby łatwo było ustalić, co poszło nie tak. To działa całkiem dobrze.

W końcu „zbyt wiele” jest nieco subiektywne, ale na poziomie obiektywnym zależy również od tego, co robisz. Jeśli robisz dokładnie to, co zostało zaprojektowane dla frameworka, dobrze zaprojektowane frameworki zapewnią idealną ilość abstrakcji. Jeśli robisz coś, co jest nieco mniej pasujące, abstrakcja stanie się zarówno zbyt duża, jak i zbyt nieszczelna.


2

Tak, są przydatne. Zapewniają one korzyść wielu innym doświadczonym programistom pracującym nad rozwiązaniem problemu, który należy rozwiązać, z dodatkowymi korzyściami z przetestowania go, naprawienia wielu błędów i dostarczenia rozwiązań trudnych problemów, o które nie musisz się martwić samemu, korzystając z frameworka.

Czy mogą być nadmiernie rozdęci? Pewnie. Wszystko zależy od tego, czego potrzebujesz, i od tego, co oferuje środowisko. Jeśli masz prostą aplikację internetową, być może Rails to dla ciebie przesada, i powinieneś rozważyć coś prostszego, jak Sinatra jako rozwiązanie.

Zdecydowanie istnieje krzywa uczenia się dla wszystkich frameworków i jest bardziej stroma, im więcej pracy dla ciebie zaoszczędzi. Jednak nauka frameworka oznacza, że ​​oszczędzasz czas i możesz wykorzystać całą tę wiedzę w następnym projekcie, zamiast przepisywania aplikacji od zera, po raz drugi.

Ale, powiadasz, po prostu skopiuję mój kod ze starego projektu i mogę go wykorzystać jako punkt wyjścia dla mojego nowego projektu! Po prostu zmienię to, co jest inne, i może sprawię, że niektóre moje obiekty / funkcje będą bardziej ogólne, i wymyślę lepszy sposób na rozwiązanie tego trudnego fragmentu kodu! Gratulacje, właśnie stworzyłeś ramę. Zrób to jeszcze kilka tysięcy razy, a masz coś takiego jak Django, Rails lub Zend.


1

Ramy zwykle skutkują większą produktywnością (być może po lekkiej krzywej uczenia się), ale często wiąże się to z kompromisem. W niektórych przypadkach, na przykład, zyskujesz wydajność programisty kosztem obniżenia wydajności.

Zastanów się nad mapowaniem obiektowo-relacyjnym (ORM). Są świetne, ponieważ dbają o wiele żmudnego kodu mapowania. Mogą nawet tworzyć dla ciebie twoje obiekty. Jednak przy wyodrębnianiu kodu SQL znacznie trudniej jest uzasadnić wydajność i zoptymalizować wąskie gardła.

Jeśli budujesz aplikację, która nie będzie miała dużo danych lub złożonych zapytań, wydajność może nie stanowić problemu. Rzeczywiście, czas programisty jest wąskim gardłem w wielu projektach, a frameworki, biblioteki i języki wysokiego poziomu pomagają to złagodzić.


1

Zgadzam się, że „korzystasz z bibliotek, ale frameworki z ciebie”. To bardzo zgrabny sposób. Nie zgadzam się, że jak tylko zaczniesz ponownie używać kodu, zaczynasz budować framework, ponieważ zwykle nie musisz robić nic więcej niż szybkie kopiowanie i wklejanie, aby ponownie użyć kodu - to biblioteka, którą budujesz; nie musisz się dziwić, jak wprowadzasz kod do swojej witryny lub aplikacji.

Dla mnie najważniejsze jest to, że muszę czerpać więcej z zasobów, niż wymaga to ode mnie inwestycji. Lub, z innej strony, powiedziałbym, że gdy tylko potrzeby ram są większe niż dostępna nagroda (nagrody), wszystkie korzyści są nieobecne. Więc to „Tak! Proszę! I dziękuję!' dla wszystkich, którzy tworzą zasoby, które spadną prosto i będą działać zgodnie z potrzebami w moim własnym html / CSS / PHP i SQL.

Niezrozumiałe jest dla mnie to, że ramy ułatwiają konserwację? Jeśli złożona siatka współpracujących części nie działa zgodnie z przeznaczeniem, lepiej poznaj wszystko, co należy wiedzieć o danym frameworku. Lub bądź przygotowany na ogromny wkład nowej składni.


0

Niektórzy twierdzą, że jest to hollywoodzka zasada ram: „Nie dzwoń do nas, my zadzwonimy”. Natomiast za każdym razem, gdy korzystasz z biblioteki, twój kod wywołuje bibliotekę , a nie na odwrót.

Jak widać, ważną kwestią jest to, kto ma kontrolę - a mianowicie kontrolę nad przepływem kontroli. Kto decyduje, które polecenie jest uruchamiane po którym?

Istnieją argumenty przemawiające za i przeciw, i ilekroć widzę takie niekończące się dyskusje, wydaje mi się, że musi to być kwestia gustu, a nie obiektywnie rozstrzygalnego pytania. W przeciwnym razie decyzja byłaby już podjęta.

Moim zdaniem to, czy wolisz używać frameworków czy bibliotek, mówi coś o tym, jakim jesteś programistą, a nie czy jedno z obu podejść jest lepsze i ostatecznie zwycięży.

Jeśli wolisz frameworki, wolisz wymieniać wolność na bezpieczeństwo: prawdopodobnie jesteś bardziej pragmatyczny i zwykle ufasz innym, że wykonają swoją pracę poprawnie. Jeśli wolisz biblioteki, wolisz wymieniać bezpieczeństwo na wolność: prawdopodobnie jesteś bardziej idealistą i kwestionujesz pomysły i roszczenia innych.

Nie sądzę, że rozsądnie byłoby zdecydować, że lepiej być jak ten pierwszy lub drugi.

Odpowiadając na twoje pytanie: Czy ramy nakładają zbyt wiele abstrakcji? Zależy to od tego, kim jesteś, a zwłaszcza od odległości od pierwszych zasad, z którymi czujesz się komfortowo.

...

A dokładniej, jeśli nie lubisz frameworków takich jak Django, poszukaj „microframeworks” takich jak Flask :)

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.