paint-brush
Kā tikt galā ar programmatūras sistēmu projektēšanas sarežģītībuautors@fairday
64,370 lasījumi
64,370 lasījumi

Kā tikt galā ar programmatūras sistēmu projektēšanas sarežģītību

autors Aleksei23m2024/02/05
Read on Terminal Reader
Read this story w/o Javascript

Pārāk ilgi; Lasīt

Sarežģītība ir ienaidnieks! Mācīsimies ar to tikt galā!
featured image - Kā tikt galā ar programmatūras sistēmu projektēšanas sarežģītību
Aleksei HackerNoon profile picture

Par ko ir runa?

Ikdienā, ik mirkli savas inženiera karjeras laikā mēs saskaramies ar daudzām un dažādām dažādas sarežģītības problēmām un situācijām, kurās jāpieņem lēmums vai tas jāatliek datu trūkuma dēļ. Ikreiz, kad veidojam jaunus pakalpojumus, būvējam infrastruktūru vai pat veidojam attīstības procesus, mēs pieskaramies milzīgai dažādu izaicinājumu pasaulei.


Ir grūti un, iespējams, pat neiespējami uzskaitīt visas problēmas. Ar dažām no šīm problēmām jūs saskarsities tikai tad, ja strādājat noteiktā nišā. No otras puses, ir daudzas problēmas, kas mums visiem ir jāsaprot, kā tās atrisināt, jo tās ir ļoti svarīgas IT sistēmu veidošanā. Ar lielu varbūtību jūs ar tiem saskarsities visos projektos.


Šajā rakstā es dalīšos savā pieredzē par dažām problēmām, ar kurām esmu saskāries, veidojot programmatūras.

Kas ir transversālas bažas?

Ja ielūkosimies Vikipēdijā, mēs atradīsim šādu definīciju


Uz aspektiem orientētā programmatūras izstrādē transversālas problēmas ir programmas aspekti, kas ietekmē vairākus moduļus, bez iespējas tikt iekapsulēti nevienā no tiem. Šīs problēmas bieži vien nevar tīri izdalīt no pārējās sistēmas gan projektēšanas, gan ieviešanas laikā, un tās var izraisīt izkliedi (koda dublēšanos), sajaukšanos (būtiskas atkarības starp sistēmām) vai abus.


Tas lieliski apraksta, kas tas ir, bet es vēlos to nedaudz paplašināt un vienkāršot:

Transversāla problēma ir sistēmas/organizācijas jēdziens vai sastāvdaļa, kas ietekmē daudzas citas daļas.


Labākie šādu problēmu piemēri ir sistēmas arhitektūra, reģistrēšana, drošība, darījumu pārvaldība, telemetrija, datu bāzes dizains un daudzi citi. Daudzus no tiem mēs sīkāk aplūkosim vēlāk šajā rakstā.


Koda līmenī transversālās problēmas bieži tiek īstenotas, izmantojot tādas metodes kā aspektorientētā programmēšana (AOP) , kur šīs problēmas tiek modulētas atsevišķos komponentos, kurus var izmantot visā lietojumprogrammā. Tādējādi biznesa loģika tiek izolēta no šīm problēmām, padarot kodu lasāmāku un apkopējamāku.

Aspektu klasifikācija

Ir daudzi iespējamie veidi, kā klasificēt aspektus, segmentējot tos ar dažādām īpašībām, piemēram, darbības jomu, lielumu, funkcionalitāti, svarīgumu, mērķi un citiem, taču šajā rakstā es izmantošu vienkāršu tvēruma klasifikāciju. Ar to es domāju, kur šis konkrētais aspekts ir vērsts neatkarīgi no tā, vai tā ir visa organizācija, noteikta sistēma vai konkrēts šīs sistēmas elements.


Tāpēc es sadalīšu aspektus makro un mikro .


Ar makro aspektu es galvenokārt domāju apsvērumus, kurus mēs ievērojam visai sistēmai, piemēram, izvēlētā sistēmas arhitektūra un tās dizains (monolīts, mikropakalpojumi, uz pakalpojumiem orientēta arhitektūra), tehnoloģiju kopums, organizācijas struktūra utt. Makro aspekti galvenokārt ir saistīti ar stratēģiskiem un augsta līmeņa aspektiem. lēmumus.


Tikmēr Micro aspekts ir daudz tuvāks koda līmenim un attīstībai. Piemēram, kurš ietvars tiek izmantots mijiedarbībai ar datu bāzi, mapju un klašu projekta struktūra vai pat konkrēti objektu dizaina modeļi.


Lai gan šī klasifikācija nav ideāla, tā palīdz strukturēt izpratni par iespējamām problēmām un to risinājumu nozīmi un ietekmi, ko tām piemērojam.


Šajā rakstā mana galvenā uzmanība tiks pievērsta makro aspektiem.

Makro aspekti

Organizācijas struktūra

Kad es tikko sāku mācīties par programmatūras arhitektūru, es izlasīju daudz interesantu rakstu par Konveja likumu un tā ietekmi uz organizācijas struktūru. Īpaši šis . Tātad šis likums to nosaka


Jebkura organizācija, kas izstrādā sistēmu (definēta plaši), izstrādās dizainu, kura struktūra ir organizācijas komunikācijas struktūras kopija.


Es vienmēr esmu uzskatījis, ka šis jēdziens patiešām ir ļoti universāls un atspoguļo Zelta likumu.


Pēc tam es sāku apgūt Ērika Evansa (Domain-Driven Design — DDD) pieeju modelēšanas sistēmām. Ēriks Evanss uzsver Bounded Context identifikācijas nozīmi. Šī koncepcija ietver sarežģīta domēna modeļa sadalīšanu mazākās, vieglāk pārvaldāmās sadaļās, katrai no kurām ir ierobežots zināšanu kopums. Šī pieeja palīdz efektīvai komandas komunikācijai, jo samazina nepieciešamību pēc plašām zināšanām par visu domēnu un samazina konteksta maiņu, tādējādi padarot sarunas efektīvākas. Konteksta maiņa ir visu laiku vissliktākā un resursus patērējošākā lieta. Pat datori ar to cīnās. Lai gan ir maz ticams, ka tiks panākta pilnīga konteksta maiņas neesamība, es uzskatu, ka tas ir tas, uz ko mums jātiecas.


Fantasy about keeping in mind a lot of bounded contexts

Atgriežoties pie Konveja likuma, ar to esmu atradis vairākas problēmas.


Pirmā problēma, ar kuru es saskāros ar Konveja likumu, kas liecina, ka sistēmas dizains atspoguļo organizācijas struktūru, ir iespēja veidot sarežģītus un visaptverošus ierobežotus kontekstus. Šī sarežģītība rodas, ja organizatoriskā struktūra nav saskaņota ar domēna robežām, kas noved pie ierobežotiem kontekstiem, kas ir ļoti savstarpēji atkarīgi un ir pieslogoti ar informāciju. Tas izraisa biežu konteksta maiņu izstrādes komandai.


Vēl viena problēma ir tā, ka organizācijas terminoloģija nonāk koda līmenī. Kad mainās organizatoriskās struktūras, ir nepieciešamas koda bāzes modifikācijas, kas patērē vērtīgus resursus.


Tādējādi Inverse Conway manevra ievērošana palīdz izveidot sistēmu un organizāciju, kas veicina vēlamo programmatūras arhitektūru. Tomēr jāatzīmē, ka šī pieeja nedarbosies īpaši labi jau izveidotajā arhitektūrā un struktūrās, jo izmaiņas šajā posmā ir ieilgušas, taču tā ir izcili efektīva starta uzņēmumos, jo tie ātri ievieš jebkādas izmaiņas.

Lielā dubļu bumba

Šis modelis jeb “pretraksts” veicina sistēmas izveidi bez arhitektūras. Nav noteikumu, nav robežu un stratēģijas, kā kontrolēt neizbēgami pieaugošo sarežģītību. Sarežģītība ir visbriesmīgākais ienaidnieks programmatūras sistēmu izveides ceļojumā.


Entertaining illustration made by ChatGPT

Lai izvairītos no šāda veida sistēmas izveidošanas, mums ir jāievēro īpaši noteikumi un ierobežojumi.

Sistēmas arhitektūra

Programmatūras arhitektūrai ir neskaitāmas definīcijas. Man patīk daudzi no tiem, jo tie aptver dažādus tā aspektus. Tomēr, lai varētu spriest par arhitektūru, mums, protams, daži no tiem ir jāveido savā prātā. Un ir vērts teikt, ka šī definīcija var attīstīties. Tāpēc vismaz pagaidām man ir šāds apraksts.


Programmatūras arhitektūra ir saistīta ar lēmumiem un izvēlēm, ko veicat katru dienu un kas ietekmē izveidoto sistēmu.


Lai pieņemtu lēmumus, jums ir jābūt principiem un modeļiem radušos problēmu risināšanai, ir svarīgi arī norādīt, ka prasību izpratne ir būtiska, lai izveidotu uzņēmumam nepieciešamo. Tomēr dažkārt prasības nav caurskatāmas vai pat nav definētas, šajā gadījumā labāk nogaidīt, lai iegūtu plašāku skaidrojumu vai paļauties uz savu pieredzi un uzticēties savai intuīcijai. Bet jebkurā gadījumā jūs nevarat pieņemt pareizus lēmumus, ja jums nav principu un modeļu, uz kuriem paļauties. Šeit es nonāku pie programmatūras arhitektūras stila definīcijas.


Programmatūras arhitektūras stils ir principu un modeļu kopums, kas nosaka, kā izveidot programmatūru.


Ir ļoti daudz dažādu arhitektūras stilu, kas vērsti uz dažādām plānotās arhitektūras pusēm, un vairāku to izmantošana vienlaikus ir normāla situācija.


Piemēram, piemēram:

  1. Monolītā arhitektūra

  2. Uz domēnu orientēts dizains

  3. Uz komponentiem balstīta

  4. Mikropakalpojumi

  5. Caurule un filtri

  6. Notikumu vadīts

  7. Mikrokodolu

  8. Uz servisu orientēts


un tā tālāk…


Protams, tiem ir savas priekšrocības un trūkumi, bet vissvarīgākais, ko esmu iemācījies, ir tas, ka arhitektūra attīstās pakāpeniski, atkarībā no faktiskajām problēmām. Sākot ar monolītu arhitektūru, tā ir lieliska izvēle, lai samazinātu darbības sarežģītību. Ļoti iespējams, ka šī arhitektūra atbilst jūsu vajadzībām pat pēc produkta izveides produkta tirgus atbilstības (PMI) posma sasniegšanas. Mērogā varat apsvērt iespēju pāriet uz notikumiem balstītu pieeju un mikropakalpojumiem, lai panāktu neatkarīgu izvietošanu, neviendabīgu tehnoloģiju skursteņa vidi un mazāk saistītu arhitektūru (un tikmēr mazāk pārredzamu notikumu virzītas un pub-sub pieejas rakstura dēļ, ja tie ir pieņemti). Vienkāršība un efektivitāte ir tuvas, un tām ir liela ietekme viena uz otru. Parasti sarežģītas arhitektūras ietekmē jaunu līdzekļu izstrādes ātrumu, atbalstot un uzturot esošās, kā arī izaicinot sistēmas dabisko attīstību.


Tomēr sarežģītām sistēmām bieži ir nepieciešama sarežģīta un visaptveroša arhitektūra, kas ir neizbēgami.


Patiesi sakot, šī ir ļoti ļoti plaša tēma, un ir daudz lielisku ideju par to, kā strukturēt un veidot sistēmas dabiskai evolūcijai. Pamatojoties uz savu pieredzi, esmu izstrādājis šādu pieeju:

  1. Gandrīz vienmēr sākas ar monolītās arhitektūras stilu, jo tas novērš lielāko daļu problēmu, kas rodas sadalīto sistēmu rakstura dēļ. Ir arī lietderīgi sekot moduļu monolītam, lai koncentrētos uz ēkas sastāvdaļām ar skaidrām robežām. Uz komponentiem balstītas pieejas izmantošana varētu palīdzēt viņiem sazināties vienam ar otru, izmantojot notikumus, taču tiešie zvani (pazīstams arī kā RPC) lietas sākumā vienkāršo. Tomēr ir svarīgi izsekot atkarībām starp komponentiem, jo, ja komponents A zina daudz par komponentu B, iespējams, ir lietderīgi tos apvienot vienā.
  2. Kad esat tuvāk situācijai, kad nepieciešams mērogot savu attīstību un sistēmu, varat apsvērt iespēju sekot Stangler modelim, lai pakāpeniski iegūtu komponentus, kas jāizvieto neatkarīgi vai pat jāmēro atbilstoši īpašām prasībām.
  3. Tagad, ja jums ir skaidra nākotnes vīzija, kas ir mazliet neticami veiksme, jūs varētu izlemt par vēlamo arhitektūru. Šobrīd jūs varētu izlemt par pāreju uz mikropakalpojumu arhitektūru, izmantojot arī orķestrēšanas un horeogrāfijas pieejas, iekļaujot CQRS modeli neatkarīgām mēroga rakstīšanas un lasīšanas darbībām vai pat izlemjot palikt pie monolītās arhitektūras, ja tā atbilst jūsu vajadzībām.


Ir svarīgi arī izprast skaitļus un metriku, piemēram, DAU (dienas aktīvie lietotāji), MAU (ikmēneša aktīvie lietotāji), RPC (pieprasījums sekundē) un TPC (darījums sekundē), jo tas var palīdzēt jums izdarīt izvēli, jo arhitektūra 100 aktīvie lietotāji un 100 miljoni aktīvo lietotāju atšķiras.


Noslēgumā es vēlos teikt, ka arhitektūra būtiski ietekmē produkta panākumus. Mērogošanas procesā ir nepieciešama slikti izstrādāta produktu arhitektūra, kas, ļoti iespējams, novedīs pie neveiksmes, jo klienti negaidīs, kamēr jūs mērogojat sistēmu, viņi izvēlēsies konkurentu, tāpēc mums ir jāapsteidz iespējamā mērogošana. Lai gan es pieļauju, ka dažreiz tā nevarētu būt vienkārša pieeja, ideja ir par mērogojamu, bet ne jau mērogotu sistēmu. No otras puses, ja jums ir ļoti sarežģīta un jau mērogota sistēma bez klientiem vai plāniem iegūt daudzus no tiem, jūsu uzņēmumam būs jāmaksā par velti.

Tehnoloģiju kaudzes izvēle

Tehnoloģiju kopas izvēle ir arī makrolīmeņa lēmums, jo tas ietekmē pieņemšanu darbā, sistēmas dabiskās attīstības perspektīvas, mērogojamību un sistēmas veiktspēju.


Šis ir saraksts ar galvenajiem apsvērumiem, izvēloties tehnoloģiju kopu:

  • Projekta prasības un sarežģītība. Piemēram, vienkāršu tīmekļa lietojumprogrammu var izveidot ar Blazor ietvaru, ja jūsu izstrādātājiem ir pieredze ar to, taču WebAssembly nepietiekama brieduma dēļ varētu būt labāks lēmums izvēlēties React un Typescript ilgtermiņa panākumiem.
  • Mērogojamības un veiktspējas vajadzības. Ja plānojat saņemt lielu trafika apjomu, ASP.NET Core izvēle, nevis Django, varētu būt saprātīga izvēle, jo tas nodrošina izcilu veiktspēju vienlaicīgu pieprasījumu apstrādē. Tomēr šis lēmums ir atkarīgs no jūsu sagaidāmās trafika mēroga. Ja jums ir jāpārvalda potenciāli miljardi pieprasījumu ar zemu latentumu, atkritumu savākšanas klātbūtne varētu būt izaicinājums.
  • Noma, izstrādes laiks un izmaksas. Vairumā gadījumu šie ir faktori, par kuriem mums ir jārūpējas. Laiks līdz tirgum, uzturēšanas izmaksas un darbā pieņemšanas stabilitāte nodrošina jūsu biznesa vajadzības bez šķēršļiem.
  • Komandas zināšanas un resursi. Jūsu attīstības komandas prasmju kopums ir būtisks faktors. Parasti efektīvāk ir izmantot tehnoloģijas, kuras jūsu komandai jau ir pazīstamas, ja vien nav pamatota iemesla ieguldīt jaunas skursteņa apguvē.
  • Briedums. Spēcīga kopiena un bagātīga bibliotēku un rīku ekosistēma var ievērojami atvieglot izstrādes procesu. Populārām tehnoloģijām bieži ir labāks kopienas atbalsts, kas var būt nenovērtējams problēmu risināšanā un resursu atrašanā. Tādējādi jūs varētu ietaupīt resursus un koncentrēties galvenokārt uz produktu.
  • Ilgtermiņa apkope un atbalsts. Apsveriet tehnoloģijas ilgtermiņa dzīvotspēju. Plaši pieņemtajām un atbalstītajām tehnoloģijām ir mazāka iespēja novecot, un tās parasti saņem regulārus atjauninājumus un uzlabojumus.


Kā vairāku tehnoloģiju kaudzes var ietekmēt biznesa izaugsmi?

No vienas perspektīvas, ieviešot vēl vienu komplektu, jūsu darbā pieņemšanas apjoms varētu palielināties, bet, no otras puses, tas rada papildu uzturēšanas izmaksas, jo jums ir jāatbalsta abas grupas. Tātad, kā jau teicu iepriekš, manuprāt, tikai papildu nepieciešamībai vajadzētu būt argumentam, lai iekļautu vairāk tehnoloģiju skursteņu.


Bet kā ir ar principu izvēlēties labāko rīku konkrētai problēmai?

Dažreiz jums nav citas izvēles, kā vien piedāvāt jaunus rīkus, lai atrisinātu konkrētu problēmu, pamatojoties uz tiem pašiem iepriekšminētajiem apsvērumiem, šādos gadījumos ir lietderīgi izvēlēties labāko risinājumu.


Sistēmu izveide bez augsta savienojuma ar konkrētu tehnoloģiju varētu būt izaicinājums. Tomēr ir lietderīgi censties panākt stāvokli, kurā sistēma nav cieši saistīta ar tehnoloģiju un tā nemirs, ja rīt kāds konkrēts ietvars vai rīks kļūs neaizsargāts vai pat novecojis.


Vēl viens svarīgs apsvērums ir saistīts ar atvērtā pirmkoda un patentētas programmatūras atkarībām. Patentēta programmatūra nodrošina mazāk elastības un iespēju tikt pielāgotai. Tomēr visbīstamākais faktors ir pārdevēja bloķēšana, kad jūs kļūstat atkarīgs no pārdevēja produktiem, cenām, noteikumiem un ceļveža. Tas var būt riskanti, ja pārdevējs maina virzienu, paaugstina cenas vai pārtrauc produkta ražošanu. Atvērtā pirmkoda programmatūra samazina šo risku, jo viena vienība to nekontrolē. Viena atteices punkta novēršana visos līmeņos ir galvenais faktors, lai izveidotu uzticamas sistēmas izaugsmei.

Single Point of Failure (SPOF)

Viens atteices punkts (SPOF) attiecas uz jebkuru sistēmas daļu, kuras atteices gadījumā visa sistēma pārtrauks darboties. SPOF likvidēšana visos līmeņos ir ļoti svarīga jebkurai sistēmai, kurai nepieciešama augsta pieejamība. Viss, tostarp zināšanas, personāls, sistēmas komponenti, mākoņpakalpojumu sniedzēji un interneta kabeļi, var neizdoties.


Ir vairākas pamata metodes, ko mēs varētu izmantot, lai novērstu atsevišķus kļūmes punktus:

  1. Atlaišana. Ieviesiet kritisko komponentu dublēšanu. Tas nozīmē, ka ir rezerves komponenti, kas var pārņemt, ja primārais komponents neizdodas. Redundanci var izmantot dažādos sistēmas slāņos, tostarp aparatūrā (serveros, diskos), tīklos (saites, slēdži) un programmatūrā (datubāzēs, lietojumprogrammu serveros). Ja visu mitināt vienā mākoņa pakalpojumu sniedzējā un tur pat ir dublējumkopijas, apsveriet iespēju izveidot regulāru papildu dublējumu citā, lai samazinātu zaudētās izmaksas katastrofas gadījumā.
  2. Datu centri. Izplatiet savu sistēmu vairākās fiziskās vietās, piemēram, datu centros vai mākoņu reģionos. Šī pieeja aizsargā jūsu sistēmu pret atrašanās vietai raksturīgām kļūmēm, piemēram, strāvas padeves pārtraukumiem vai dabas katastrofām.
  3. Kļūmjpārlēce. Lietojiet kļūmjpārlēces pieeju visiem saviem komponentiem (DNS, CDN, slodzes līdzsvarotājiem, Kubernetes, API vārtejas un datu bāzēm). Tā kā problēmas var rasties negaidīti, ir ļoti svarīgi izveidot rezerves plānu, lai pēc vajadzības ātri aizstātu jebkuru komponentu ar tā klonu.
  4. Augstas pieejamības pakalpojumi. Nodrošiniet, lai jūsu pakalpojumi būtu horizontāli mērogojami un būtu ļoti pieejami jau no paša sākuma, ievērojot šādus principus:
    • Praktizējiet pakalpojumu bezpavalstniecību un izvairieties no lietotāju sesiju glabāšanas atmiņas kešatmiņā. Tā vietā izmantojiet izplatītu kešatmiņas sistēmu, piemēram, Redis.
    • Izstrādājot loģiku, izvairieties no paļaušanās uz ziņojumu patēriņa hronoloģisko secību.
    • Samaziniet bojājošās izmaiņas, lai novērstu API patērētāju traucējumus. Ja iespējams, izvēlieties ar atpakaļejošu spēku saderīgas izmaiņas. Ņemiet vērā arī izmaksas, jo dažkārt laužu izmaiņu ieviešana var būt rentablāka.
    • Iekļaujiet migrācijas izpildi izvietošanas konveijerā.
    • Izveidojiet stratēģiju vienlaicīgu pieprasījumu apstrādei.
    • Ieviesiet pakalpojumu atklāšanu, uzraudzību un reģistrēšanu, lai uzlabotu uzticamību un novērojamību.
    • Attīstiet biznesa loģiku, lai tā būtu idempotena, atzīstot, ka tīkla kļūmes ir neizbēgamas.
  5. Atkarības apskats. Regulāri pārskatiet un samaziniet ārējās atkarības. Katra ārējā atkarība var radīt potenciālus SPOF, tāpēc ir svarīgi izprast un mazināt šos riskus.
  6. Regulāra zināšanu apmaiņa. Nekad neaizmirstiet, cik svarīgi ir izplatīt zināšanas savā organizācijā. Cilvēki var būt neparedzami, un paļauties uz vienu cilvēku ir riskanti. Mudiniet komandas locekļus digitalizēt savas zināšanas, izmantojot dokumentāciju. Tomēr pievērsiet uzmanību pārmērīgai dokumentēšanai. Izmantojiet dažādus AI rīkus, lai vienkāršotu šo procesu.

Secinājums

Šajā rakstā mēs apskatījām vairākus galvenos makro aspektus un to, kā mēs varam tikt galā ar to sarežģītību.


Paldies, ka izlasījāt! Uz tikšanos nākamreiz!