Czy podzielenie potencjalnie monolitycznej aplikacji na kilka mniejszych pomaga zapobiegać błędom? [Zamknięte]

48

Innym sposobem zadawania tego pytania jest; dlaczego programy wydają się być monolityczne?

Mam na myśli coś takiego jak pakiet animacji, taki jak Maya, który ludzie używają do różnych przepływów pracy.

Gdyby możliwości animacji i modelowania zostały podzielone na osobne aplikacje i opracowane osobno, a pliki były przesyłane między nimi, czy nie byłoby łatwiejsze do utrzymania?

dnv
źródło
9
If the animation and modelling capabilities were split into their own separate application and developed separately, with files being passed between them, would they not be easier to maintain?Nie mieszaj łatwiejsze do rozszerzenia z łatwiejszym do utrzymania modułem - jeśli nie jest wolny od komplikacji lub wątpliwych projektów. Maya może być piekłem na ziemi, a jej wtyczki nie. Lub odwrotnie.
Laiv
37
Dodam, że jeden monolityczny programu wydaje się być łatwiej sprzedać i łatwiejsze dla większości ludzi do korzystania .
DarthFennec
2
@DarthFennec Najlepsze aplikacje wyglądają dla użytkownika jak jedna aplikacja, ale wykorzystują wszystko, co jest konieczne pod maską. Ile mikrousług zasila różne odwiedzane witryny? Prawie żaden z nich nie jest już monolitem!
corsiKa
23
@corsiKa Zazwyczaj nie ma nic do zyskania, pisząc aplikację komputerową jako wiele programów komunikujących się pod maską, czego nie uzyskuje się po prostu pisząc wiele modułów / bibliotek i łącząc je ze sobą w monolityczny plik binarny. Mikrousługi służą całkowicie innemu celowi, ponieważ umożliwiają uruchamianie jednej aplikacji na wielu serwerach fizycznych, umożliwiając skalowanie wydajności wraz z obciążeniem.
DarthFennec
5
@corsiKa - zgaduję, że przytłaczająca liczba stron, z których korzystam, to wciąż monolity. W końcu większość Internetu działa na Wordpress.
Davor Ždralo

Odpowiedzi:

94

Tak. Zasadniczo dwie mniejsze, mniej złożone aplikacje są o wiele łatwiejsze w utrzymaniu niż jedna duża.

Pojawia się jednak nowy rodzaj błędu, gdy wszystkie aplikacje współpracują ze sobą, aby osiągnąć cel. Aby zmusić ich do współpracy, muszą wymieniać wiadomości, a ta aranżacja może pójść nie tak na różne sposoby, nawet jeśli każda aplikacja może działać idealnie. Posiadanie miliona małych aplikacji ma swoje własne problemy.

Aplikacja monolityczna jest tak naprawdę domyślną opcją, z jaką się kończysz, gdy dodajesz coraz więcej funkcji do jednej aplikacji. Jest to najłatwiejsze podejście, jeśli weźmiesz pod uwagę każdą funkcję osobno. Dopiero gdy urosną, możesz spojrzeć na całość i powiedzieć: „wiesz co, lepiej by było, gdybyśmy wyodrębnili X i Y”.

Ewan
źródło
6
Tak, istnieją również względy wydajnościowe, np. Koszt przekazywania wskaźnika w porównaniu do serializacji danych.
JimmyJames
65
„Zasadniczo 2 mniejsze, mniej złożone aplikacje są o wiele łatwiejsze w utrzymaniu niż jedna duża”. - to prawda, z wyjątkiem sytuacji, gdy tak nie jest. Zależy w dużej mierze od tego, gdzie i jak te dwie aplikacje muszą się ze sobą łączyć.
Doc Brown
10
„Zasadniczo 2 mniejsze, mniej złożone aplikacje są o wiele łatwiejsze w utrzymaniu niż jedna duża.”. Myślę, że potrzebuję więcej wyjaśnień na ten temat. Dlaczego właśnie proces generowania dwóch zamiast jednego pliku wykonywalnego z bazy kodu magicznie ułatwiłby kod? To, co decyduje o łatwości rozumowania kodu, to jego ścisłe powiązanie i podobne rzeczy. Ale to jest logiczna separacja i nie ma nic wspólnego z fizyczną .
Voo
11
@Ew Fizyczna separacja nie wymusza logicznej separacji, to jest problem. Mogę z łatwością zaprojektować system, w którym dwie osobne aplikacje są ze sobą ściśle powiązane. Na pewno wiąże się to z pewną korelacją , ponieważ ludzie, którzy spędzają czas na oddzieleniu aplikacji, są najprawdopodobniej wystarczająco kompetentni, aby rozważyć te rzeczy, ale nie ma powodu, aby zakładać jakąkolwiek przyczynę . Zgodnie z tą samą logiką mogę twierdzić, że korzystanie z najnowszej wersji C # znacznie ułatwia utrzymanie kodu, ponieważ zespół, który aktualizuje swoje narzędzia, prawdopodobnie będzie również martwił się o utrzymanie kodu.
Voo
9
Myślę, że dyskusję tutaj można podsumować za pomocą 2 stwierdzeń: 1) Samo dzielenie aplikacji nie czyni aplikacji łatwiejszą do utrzymania - wręcz przeciwnie, zapewnia kolejny możliwy błąd 2) Dzielenie aplikacji zmusza do myślenia o tym, gdzie podzielić co daje przewagę w porównaniu z monolitem, w którym nigdy tego nie zrobiono.
R. Schmitz
51

Czy podział potencjalnie monolitycznej aplikacji na kilka mniejszych pomaga zapobiegać błędom

Rzeczy w rzeczywistości rzadko są tak proste.

Podział zdecydowanie nie pomaga przede wszystkim w zapobieganiu tym błędom. Czasami może pomóc w szybszym znajdowaniu błędów. Aplikacja, która składa się z małych, izolowanych komponentów, może pozwolić na bardziej indywidualne testy (tych „jednostek” -) dla tych komponentów, co może czasem ułatwić wykrycie pierwotnej przyczyny niektórych błędów, a tym samym umożliwić ich szybsze usunięcie.

Jednak,

  • nawet aplikacja, która wydaje się monolityczna z zewnątrz, może składać się z wielu elementów możliwych do przetestowania w jednostce, więc testowanie jednostkowe niekoniecznie jest trudniejsze dla aplikacji monolitycznej

  • jak już wspomniano Ewan, interakcja kilku składników wprowadza dodatkowe ryzyko i błędy. Debugowanie systemu aplikacji ze złożoną komunikacją międzyprocesową może być znacznie trudniejsze niż debugowanie aplikacji jednoprocesowej

Zależy to również w dużej mierze od tego, jak dobrze większa aplikacja może podzielić się na komponenty, jak szerokie są interfejsy między komponentami i jak te interfejsy są używane.

Krótko mówiąc, często jest to kompromis i nic, w przypadku gdy odpowiedź „tak” lub „nie” jest ogólnie poprawna.

dlaczego programy są zwykle monolityczne

Czy oni? Rozejrzyj się wokół, są tysiące aplikacji internetowych na świecie, które nie wyglądają dla mnie zbyt monolitycznie, wręcz przeciwnie. Istnieje również wiele programów, które zapewniają model wtyczki (AFAIK nawet oprogramowanie Maya, o którym wspomniałeś, robi).

czy nie byłyby łatwiejsze w utrzymaniu

„Łatwiejsza konserwacja” często wynika z faktu, że różne części aplikacji mogą być łatwiej opracowywane przez różne zespoły, dzięki czemu lepiej rozłożone obciążenie, wyspecjalizowane zespoły z wyraźniejszym nastawieniem i dalej.

Doktor Brown
źródło
4
W ostatnim zdaniu, prawo Conwaya mówi, że struktura systemu ma tendencję do naśladowania org. struktura: deweloperzy / zespoły są bardziej zaznajomieni z niektórymi częściami niż inne, więc chociaż poprawki / ulepszenia powinny nastąpić w najbardziej odpowiedniej części, deweloper może łatwiej włamać się do „swoich” części, niż (a) dowiedzieć się, jak to zrobić inna część działa lub (b) współpracuje z kimś bardziej zaznajomionym z tą częścią. Jest to związane ze wzmiankami o „szwach” @TKK oraz o tym, jak trudne może być znalezienie i wymuszenie „poprawnych” / prostych.
Warbo
38

Będę musiał się nie zgodzić z większością w tej sprawie. Podział aplikacji na dwie osobne nie sprawia, że ​​kod jest łatwiejszy do utrzymania lub uzasadnienia.

Rozdzielenie kodu na dwa pliki wykonywalne po prostu zmienia fizyczną strukturę kodu, ale to nie jest ważne. O tym, jak złożona jest aplikacja, decyduje to, jak ściśle powiązane są ze sobą różne części, które ją tworzą. To nie jest własność fizyczna, ale logiczna .

Możesz mieć monolityczną aplikację, która ma wyraźne oddzielenie różnych problemów i prostych interfejsów. Możesz mieć architekturę mikrousług, która opiera się na szczegółach implementacji innych mikrousług i jest ściśle powiązana ze wszystkimi innymi.

Prawdą jest, że proces dzielenia jednej dużej aplikacji na mniejsze jest bardzo pomocny przy próbie ustalenia jasnych interfejsów i wymagań dla każdej części. W DDD mów, że wymyślisz swoje ograniczone konteksty. Ale to, czy następnie utworzysz wiele małych aplikacji, czy jedną dużą, która ma tę samą logiczną strukturę, jest bardziej decyzją techniczną.

Voo
źródło
Ale co, jeśli weźmiesz aplikację komputerową z wieloma trybami edycji i zamiast tego stworzysz tylko jedną aplikację komputerową dla każdego trybu, którą użytkownik otworzyłby indywidualnie, zamiast mieć interfejs. Czy nie wyeliminowałoby to niebagatelnej ilości kodu poświęconego tworzeniu „funkcji”, że „użytkownik może przełączać tryby edycji”?
The Great Duck
3
@TheGreatDuck To brzmi tak, jakby wyeliminowałoby to również trywialną liczbę użytkowników, którzy nie lubią przełączać się między różnymi aplikacjami. ;) Ale tak, eliminacja funkcji ogólnie prowadzi do uproszczenia kodu. Wyeliminuj sprawdzanie pisowni, a usuniesz możliwość występowania błędów sprawdzania pisowni. Jest to rzadko wykonywane, ponieważ funkcja została dodana, ponieważ ktoś jej chciał.
Odalrick
1
@TheGreatDuck Z pewnością projekt UX powinien poprzedzać wszelkie decyzje architektoniczne. Nie ma sensu mieć najlepiej zaprojektowanej architektury, jeśli nikt nie używa Twojego programu. Najpierw zdecyduj, co chcesz zbudować i na podstawie decyzji o szczegółach technicznych. Jeśli preferowane są dwie oddzielne aplikacje, wybierz tę opcję. Nadal możesz jednak udostępniać dużo kodu za pośrednictwem bibliotek współdzielonych.
Voo
Czy naprawdę prawdą jest stwierdzenie, że złożoność systemu wynika z ciasnego połączenia części? Chciałbym powiedzieć, że całkowita złożoność wzrasta, jeśli partycjonujesz system podczas wprowadzania pośrednictwa i komunikacji, chociaż złożoność poszczególnych poszczególnych składników jest izolowana w stanie ograniczonym o bardziej ograniczonej złożoności.
Alex
1
@TheGreatDuck Podstawowym założeniem tutaj było to, że systemy mają coś wspólnego i faktycznie muszą się ze sobą komunikować w taki czy inny sposób. Nie sądzę, by OP pytał o to, czy dwie zupełnie różne aplikacje, które są spakowane razem z jakiegoś dziwnego powodu, byłyby łatwiejsze do utrzymania, gdyby były oddzielone. Wydaje się to dziwnym przypadkiem, który rzadko pojawia się w praktyce (chociaż jestem pewien, że ktoś gdzieś to zrobił).
Voo
15

Łatwiejsze w utrzymaniu, gdy skończysz je dzielić, tak. Ale podział ich nie zawsze jest łatwy. Próba podzielenia fragmentu programu na bibliotekę wielokrotnego użytku ujawnia, gdzie pierwotni programiści nie zastanawiali się, gdzie powinny znajdować się szwy . Jeśli jedna część aplikacji sięga głęboko w inną część aplikacji, naprawa może być trudna. Zgrywanie szwy wymusza zdefiniowanie wewnętrznych API jaśniej, i to jest to, co ostatecznie sprawia, że baza kod łatwiejszy w utrzymaniu. Wielokrotnego użytku i konserwacji są produkty dobrze określonych szwów.

Nie ty
źródło
wspaniały post. Myślę, że klasycznym / kanonicznym przykładem tego, o czym mówisz, jest aplikacja GUI. wiele razy aplikacja GUI jest jednym programem, a backend / frontend są ściśle powiązane. w miarę upływu czasu pojawiają się problemy ... jak ktoś inny musi korzystać z backendu, ale nie może, ponieważ jest on powiązany z frontendem. lub przetwarzanie backendu trwa zbyt długo i torfuje frontend. często jedna duża aplikacja GUI jest podzielona na dwa programy: jeden jest graficznym interfejsem użytkownika, a drugi jest zapleczem.
Trevor Boyd Smith
13

Ważne jest, aby pamiętać, że korelacja nie jest przyczyną.

Zbudowanie dużego monolitu, a następnie podzielenie go na kilka małych części może, ale nie musi, prowadzić do dobrego projektu. ( Może poprawić projekt, ale nie ma takiej gwarancji.)

Ale dobry projekt często prowadzi do zbudowania systemu jako kilku małych części zamiast dużego monolitu. (Monolit może być najlepszym projektem, jest o wiele mniej prawdopodobne).

Dlaczego małe części są lepsze? Ponieważ łatwiej je zrozumieć. A jeśli łatwo jest uzasadnić poprawność, istnieje większe prawdopodobieństwo, że uzyskasz poprawny wynik.

Cytując CAR Hoare:

Istnieją dwa sposoby konstruowania projektu oprogramowania: Jednym ze sposobów jest uczynienie go tak prostym, aby oczywiście brakowało braków, a drugim sposobem jest uczynienie go tak skomplikowanym, aby nie było oczywistych braków.

Jeśli tak, to dlaczego ktoś miałby budować niepotrzebnie skomplikowane lub monolityczne rozwiązanie? Hoare udziela odpowiedzi w następnym zdaniu:

Pierwsza metoda jest znacznie trudniejsza.

A później w tym samym źródle (wykład Turinga z 1980 r.):

Cena niezawodności to dążenie do jak największej prostoty. Jest to cena, którą bardzo bogaci najtrudniej zapłacić.

Daniel Pryden
źródło
6

To nie jest pytanie z odpowiedzią tak lub nie. Pytanie to nie tylko łatwość konserwacji, ale także pytanie o efektywne wykorzystanie umiejętności.

Ogólnie dobrze napisana aplikacja monolityczna jest wydajna. Komunikacja między procesami i między urządzeniami nie jest tania. Przerwanie jednego procesu zmniejsza wydajność. Jednak wykonanie wszystkiego na jednym procesorze może przeciążyć procesor i obniżyć wydajność. Jest to podstawowy problem ze skalowalnością. Gdy sieć wchodzi w obraz, problem staje się bardziej skomplikowany.

Dobrze napisana aplikacja monolityczna, która może działać skutecznie jako pojedynczy proces na jednym serwerze, może być łatwa w utrzymaniu i wolna od wad, ale nadal nie może być efektywnym wykorzystaniem umiejętności kodowania i architektury. Pierwszym krokiem jest rozbicie procesu na biblioteki, które nadal działają jako ten sam proces, ale są kodowane niezależnie, zgodnie z dyscypliną spójności i luźnego łączenia. Dobra praca na tym poziomie poprawia łatwość konserwacji i rzadko wpływa na wydajność.

Następnym etapem jest podzielenie monolitu na osobne procesy. Jest to trudniejsze, ponieważ wchodzisz na trudne terytorium. Łatwo jest wprowadzić błędy warunków wyścigu. Zwiększają się koszty komunikacji i należy uważać na „gadatliwe interfejsy”. Nagrody są świetne, ponieważ przełamujesz barierę skalowalności, ale zwiększa się również potencjał wad. Aplikacje wieloprocesowe są łatwiejsze w utrzymaniu na poziomie modułu, ale cały system jest bardziej skomplikowany i trudniejszy do rozwiązania. Naprawy mogą być diabelnie skomplikowane.

Gdy procesy są dystrybuowane do oddzielnych serwerów lub do implementacji w chmurze, problemy stają się coraz trudniejsze, a nagrody większe. Skalowalność szybuje. (Jeśli zastanawiasz się nad implementacją chmury, która nie daje skalowalności, zastanów się.) Jednak problemy, które pojawiają się na tym etapie, mogą być niezwykle trudne do zidentyfikowania i przemyślenia.

Cud
źródło
4

Nie . nie ułatwia to utrzymania. Jeśli cokolwiek, zapraszamy na więcej problemów.

Dlaczego?

  • Programy nie są ortogonalne, muszą zachowywać się nawzajem w zakresie, w jakim jest to uzasadnione, co wymaga wspólnego zrozumienia.
  • Wiele kodów obu programów jest identycznych. Czy prowadzisz wspólną bibliotekę współdzieloną, czy dwie osobne kopie?
  • Masz teraz dwa zespoły programistyczne. Jak się komunikują?
  • Masz teraz dwa produkty, które potrzebują:

    • wspólny styl interfejsu użytkownika, mechanizmy interakcji itp. Więc masz teraz problemy projektowe. (Jak zespoły programistów komunikują się ponownie?)
    • kompatybilność wsteczna (czy modeler v1 można zaimportować do animatora v3?)
    • integracja z chmurą / siecią (jeśli jest to funkcja) musi być teraz aktualizowana w dwukrotnie większej liczbie produktów.
  • Masz teraz trzy rynki konsumenckie: modelarzy, animatorów i animatorów modellerów

    • Będą mieć sprzeczne priorytety
    • Będą mieć sprzeczne potrzeby w zakresie wsparcia
    • Będą mieć sprzeczne style użytkowania
  • Czy Modeller Animators musi otworzyć dwie osobne aplikacje do pracy na tym samym pliku? Czy istnieje trzecia aplikacja z obiema funkcjami, czy jedna aplikacja ładuje funkcje drugiej?
  • itp...

Biorąc pod uwagę, że mniejsze bazy kodu są łatwiejsze do utrzymania na poziomie aplikacji, po prostu nie dostaniesz darmowego lunchu. Jest to ten sam problem w sercu architektury Micro-Service / Any-Modular-Architecture. To nie jest panaceum, trudności konserwacyjne na poziomie aplikacji są wymieniane za trudności konserwacyjne na poziomie aranżacji. Te problemy są nadal problemami, po prostu nie znajdują się już w bazie kodu, należy ich uniknąć lub rozwiązać.

Jeśli rozwiązanie problemu na poziomie aranżacji jest prostsze niż rozwiązywanie go na każdym poziomie aplikacji, wówczas sensowne jest podzielenie go na dwie bazy kodu i zajęcie się problemami z aranżacją.

W przeciwnym razie nie, po prostu nie rób tego, lepiej byś był obsługiwany przez poprawę wewnętrznej modułowości samej aplikacji. Wypchnij sekcje kodu do spójnych i łatwiejszych w utrzymaniu bibliotek, do których aplikacja działa jak wtyczka. W końcu monolit jest tylko warstwą aranżacyjną krajobrazu bibliotecznego.

Kain0_0
źródło
3

Było wiele dobrych odpowiedzi, ale ponieważ jest prawie martwy podział, wrzucę też kapelusz na ring.

Z mojego doświadczenia jako inżyniera oprogramowania odkryłem, że nie jest to prosty problem. To zależy od wielkości , skali i celu zastosowania. Starsze zastosowania ze względu na bezwładność wymaganą do ich zmiany są generalnie monolityczne, ponieważ była to powszechna praktyka przez długi czas (Maya kwalifikowała się w tej kategorii). Zakładam, że ogólnie mówisz o nowszych aplikacjach.

W wystarczająco małych aplikacjach, które są mniej więcej pojedynczymi problemami, narzut wymagany do utrzymania wielu oddzielnych części ogólnie przewyższa użyteczność oddzielenia. Jeśli może go utrzymywać jedna osoba, prawdopodobnie może być monolityczny, nie powodując zbyt wielu problemów. Wyjątkiem od tej reguły jest sytuacja, gdy masz wiele różnych części (frontend, backend, być może niektóre warstwy danych pomiędzy nimi), które są dogodnie oddzielone (logicznie).

W bardzo dużych nawet pojedynczych aplikacjach dzielenie go ma sens z mojego doświadczenia. Zaletą jest zmniejszenie części możliwych błędów w zamian za inne (czasem łatwiejsze do rozwiązania) błędy. Ogólnie rzecz biorąc, możesz również mieć zespoły ludzi pracujących w izolacji, co poprawia wydajność. Wiele aplikacji jest jednak obecnie bardzo dobrze podzielonych, czasem na własną szkodę. Byłem też w zespołach, w których aplikacja została niepotrzebnie podzielona na tak wiele mikrousług, że spowodowało to duże obciążenie, gdy sprawy przestały ze sobą rozmawiać. Ponadto konieczność posiadania całej wiedzy na temat tego, jak każda część rozmawia z innymi częściami, staje się znacznie trudniejsza z każdym kolejnym podziałem. Istnieje równowaga i jak można stwierdzić po odpowiedziach tutaj, sposób na zrobienie tego nie jest bardzo jasny,

CL40
źródło
2
Moja pierwsza praca jako programisty była jako programista od tysiącleci. Oprogramowanie, nad którym pracowałem, zostało podzielone na setki małych programów, z których wszystkie miały niewielki udział, połączone z plikami wsadowymi i wykorzystujące pliki do komunikowania stanu. To był wielki bałagan, wymyślony w czasach, gdy komputery były wolne, miały mało pamięci, a pamięć masowa była droga. Kiedy z nim pracowałem, kod miał już 10-15 lat. Gdy skończyliśmy, poprosili mnie o radę, a moją radą było przekonwertować wszystko do nowego monolitycznego zastosowania. Tak zrobili, a rok później dostałem wielkie podziękowania.
Pieter B
@PieterB Miałem podobne doświadczenie. „Najnowocześniejsza” technologia to niestety bardzo duży kult ładunków na wiele sposobów. Zamiast wybierać najlepszą metodę pracy, wiele firm po prostu podąży za tym, co robi FAANG w danym czasie, bez żadnych pytań.
CL40
a także: to, co po kompilacji może wyjść jako aplikacja monolityczna, może być aplikacją bardzo modułową, jeśli chodzi o kod.
Pieter B
1

W przypadku aplikacji interfejsu użytkownika jest mało prawdopodobne, aby zmniejszyć ogólną liczbę błędów, ale zmieni bilans mieszania błędów w kierunku problemów spowodowanych komunikacją.

Mówiąc o aplikacjach / witrynach z interfejsem użytkownika - użytkownicy są wyjątkowo niecierpliwi i wymagają krótkiego czasu reakcji. Powoduje to, że wszelkie opóźnienia w komunikacji stają się błędami. W rezultacie wymienimy potencjalne zmniejszenie liczby błędów z powodu zmniejszonej złożoności pojedynczego komponentu z bardzo trudnymi błędami i wymogiem czasowym komunikacji między procesami / między maszynami.

Jeśli jednostki danych, którymi zajmuje się program, są duże (tzn. Obrazy), wszelkie opóźnienia między procesami byłyby dłuższe i trudniejsze do wyeliminowania - coś w rodzaju „zastosuj transformację do obrazu 10 MB” natychmiast zyska dodatkowo + 20 MB dysku I / dysku IO do 2 konwersji z formatu w pamięci na format serializacji iz powrotem. Naprawdę niewiele można zrobić, aby ukryć czas potrzebny użytkownikowi.

Ponadto wszelka komunikacja, a zwłaszcza dyskowe operacje wejścia / wyjścia, podlegają kontroli antywirusowej / zapory ogniowej - to nieuchronnie dodaje kolejną warstwę trudnych do odtworzenia błędów i jeszcze więcej opóźnień.

Podział monolitycznego „programu” świeci tam, gdzie opóźnienia komunikacyjne nie są krytyczne lub są już nieuniknione

  • równoległe przetwarzanie zbiorcze informacji, w którym można handlować małymi dodatkowymi opóźnieniami w celu znacznej poprawy poszczególnych kroków (czasami eliminując potrzebę niestandardowych komponentów przez jednorazowe użycie gotowych produktów). Mały indywidualny krok może pozwolić na użycie wielu tańszych maszyn zamiast na przykład jednej drogiej.
  • podział usług monolitycznych na mikroprzełączniki mniej sprzężone - wywoływanie kilku usług równolegle zamiast jednej najprawdopodobniej nie spowoduje dodatkowych opóźnień (może nawet skrócić całkowity czas, jeśli każda z nich jest szybsza i nie ma zależności)
  • przenoszenie operacji, których użytkownicy oczekują długo - renderowanie skomplikowanej sceny / filmu 3D, obliczanie złożonych danych o danych, ...
  • wszelkiego rodzaju „autouzupełnianie”, „sprawdzanie pisowni” i inne opcjonalne pomoce mogą i często stają się zewnętrzne - najbardziej oczywistym przykładem są automatyczne sugestie adresu URL przeglądarki, w których dane wejściowe są wysyłane do usług zewnętrznych (wyszukiwarka) przez cały czas .

Należy pamiętać, że dotyczy to zarówno aplikacji komputerowych, jak i stron internetowych - część programu skierowana do użytkownika jest zazwyczaj „monolityczna” - cały kod interakcji użytkownika związany z pojedynczą częścią danych jest zwykle uruchamiany w jednym procesie (podział nie jest niczym niezwykłym przetwarza na podstawie danych, takich jak strona HTML lub obraz, ale jest to ortogonalne dla tego pytania). Nawet w przypadku najbardziej podstawowej witryny z danymi wprowadzonymi przez użytkownika zobaczysz logikę sprawdzania poprawności uruchomioną po stronie klienta, nawet jeśli uczynienie jej po stronie serwera będzie bardziej modułowe i zmniejszy złożoność / duplikację kodu.

Aleksiej Lewenkow
źródło
0

Czy [it] pomaga zapobiegać błędom?

Zapobiec? Nie, nie bardzo.

  • Pomaga wykrywać błędy .
    Mianowicie wszystkie błędy, o których nawet nie wiedziałeś, że odkryłeś je, kiedy próbowałeś podzielić cały ten bałagan na mniejsze części. W pewien sposób zapobiegło to pojawieniu się tych błędów w produkcji - ale błędy już tam były.
  • Pomaga zmniejszyć wpływ błędów .
    Błędy w aplikacjach monolitycznych mogą doprowadzić do awarii całego systemu i uniemożliwić użytkownikowi interakcję z aplikacją. Jeśli podzielisz tę aplikację na komponenty, większość błędów - zgodnie z projektem - wpłynie tylko na jeden z komponentów.
  • Tworzy scenariusz dla nowych błędów .
    Jeśli chcesz zachować niezmienione wrażenia użytkownika, musisz wprowadzić nową logikę dla wszystkich tych komponentów do komunikacji (za pośrednictwem usług REST, za pośrednictwem wywołań systemu operacyjnego, co masz), aby mogły bezproblemowo współdziałać z POV użytkownika.
    Jako prosty przykład: Twoja monolityczna aplikacja pozwala użytkownikom stworzyć model i animować go bez opuszczania aplikacji. Aplikacja została podzielona na dwa komponenty: modelowanie i animację. Teraz użytkownicy muszą wyeksportować model aplikacji do modelowania do pliku, a następnie znaleźć plik, a następnie otworzyć go za pomocą aplikacji do animacji ... Spójrzmy prawdzie w oczy, niektórym użytkownikom się to nie spodoba, więc musisz uwzględnić nową logikę dla aplikacja do modelowania w celu wyeksportowania pliku iautomatycznie uruchom aplikację do animacji i otwórz plik. I ta nowa logika, choć może być prosta, może zawierać szereg błędów dotyczących serializacji danych, dostępu do plików i uprawnień, użytkowników zmieniających ścieżkę instalacyjną aplikacji itp.
  • Jest to idealna wymówka do zastosowania bardzo potrzebnego refaktoryzacji .
    Decydując się na podzielenie monolitycznej aplikacji na mniejsze komponenty, (miejmy nadzieję) robisz to z dużo większą wiedzą i doświadczeniem na temat systemu niż w momencie jego pierwszego zaprojektowania, a dzięki temu możesz zastosować wiele refaktorów do stworzenia kodu czystsze, prostsze, wydajniejsze, bardziej elastyczne, bezpieczniejsze. A to refaktoryzacja może w pewien sposób pomóc w zapobieganiu błędom. Oczywiście możesz również zastosować to samo refaktoryzowanie do monolitycznej aplikacji, aby zapobiec tym samym błędom, ale nie robisz tego, ponieważ jest tak monolityczny, że boisz się dotknąć czegoś w interfejsie użytkownika i złamać logikę biznesową ¯ \ _ (ツ) _ / ¯

Nie powiedziałbym więc, że zapobiegasz błędom, dzieląc monolityczną aplikację na mniejsze komponenty, ale w rzeczywistości ułatwiasz osiągnięcie punktu, w którym można łatwiej zapobiec błędom.

Walen
źródło