Ang mga dependency ng code ay ang diyablo.

Ang iyong dependencies ay susunugin ka sa tuwing.
"Ang pagbabago ay ang tanging pare-pareho ..." - Heraclitus (Pilosopo)

Ang mga tool, aklatan, at mga frameworks na ginagamit namin upang maitaguyod ang aming mga aplikasyon sa web ngayon ay naiiba na naiiba sa mga ginamit namin ilang taon na ang nakalilipas.

Sa ilang maikling taon mula ngayon, ang karamihan sa mga teknolohiyang ito ay muling nagbago muli. Gayunpaman, marami sa atin ang gumagawa ng mga ito sa gitna, hindi maihahambing na bahagi ng aming mga app.

Nag-import kami, gumamit, at nagmana mula sa mga lasa-ng-buwan na mga frameworks na para bang lahat sila ay magiging paligid at hindi mababago magpakailanman. Well ... hindi sila. At problema yan.

Matapos ang 20+ taon ng pagbuo, pagdidisenyo, at pag-archive ng mga aplikasyon sa web, napahalagahan ko ang dalawang mahahalagang katotohanan:

  1. Ang mga panlabas na dependencies ay nagbibigay ng isang malaking banta sa pangmatagalang katatagan at kakayahang umangkop ng anumang aplikasyon.
  2. Ito ay lalong mahirap - kung hindi imposible - upang bumuo ng anumang uri ng di-walang kuwentang app nang walang pag-agaw sa mga panlabas na dependencies.

Ang artikulong ito ay tungkol sa pagkakasundo ng dalawang katotohanang ito upang ang aming mga app ay may pinakamalaking pagkakataon ng kaligtasan ng pangmatagalang.

Ang butas ng kuneho ay napakalalim talaga.

Kung nagsisimula kaming mag-isip ng lahat ng mga bagay na nakasalalay sa aming mga web app na madaling mag-isip ng isang dosenang o higit pa bago kami makarating sa code:

  • Kapangyarihan
  • Pagkakakonekta
  • Firewall
  • DNS
  • Hardware ng Server (CPU, Disk, Ram,…)
  • Palamig
  • Platform ng Virtualization
  • Lalagyan ng Platform
  • Operating System
  • Platform ng Web Server
  • Platform ng Server ng App
  • Web Browser

Bilang mga developer, mabuti na magkaroon ng kamalayan sa mga bagay na ito, ngunit madalas na hindi gaanong magagawa natin tungkol sa mga ito. Kaya, huwag nating pansinin ang mga ito para sa ngayon at pag-usapan lamang ang tungkol sa code.

Sa code, may tatlong uri ng dependencies:

1. Kinokontrol natin ang mga dependencies

Ito ang code na nakasulat at pag-aari ng amin o sa aming samahan.

2. Ang mga dependencies ay hindi natin kontrolado

Ito ang code na isinulat ng isang third party vendor o open-source software na komunidad.

3. Ang mga pag-asa sa sandaling tinanggal

Ito ang mga dependency ng code na nakasalalay sa mga dependency ng code ng third-party. (Sabihin na tatlong beses nang mabilis!)

Pag-uusapan natin ang tungkol sa mga dependencies na hindi namin kinokontrol.

Ang mga dependencies na kinokontrol natin at ang mga dependencies kapag tinanggal ay maaari pa ring magdulot ng pananakit ng ulo, ngunit sa kaso ng mga dependencies na kinokontrol natin, dapat nating direktang mamagitan at mabawasan ang anumang mga problema.

Sa kaso ng mga dependencies kapag tinanggal, maaari naming karaniwang umasa sa isang third-party upang alagaan ito para sa amin, dahil nakasalalay din sila sa mga ito.

Bakit ang mga dependency ng code ng third-party ay mabuti

Ang isang malaking bahagi ng iyong web application ay umiiral upang malutas ang mga karaniwang problema: pagpapatunay, pahintulot, pag-access ng data, paghawak ng error, nabigasyon, pag-log in, pag-encrypt, pagpapakita ng isang listahan ng mga item, pagpapatunay ng mga input ng form, at iba pa ...

Hindi alintana kung aling teknolohiya ang ginamit mo, mayroong isang magandang pagkakataon na umiiral ang mga karaniwang solusyon sa mga problemang ito, at magagamit bilang mga aklatan na madali mong makuha at mai-plug-in sa iyong codebase. Ang pagsulat ng anuman sa mga bagay na ito mula sa simula ay karaniwang pag-aaksaya ng oras.

Nais mong mag-concentrate sa code na alinman ay malulutas ang isang hindi pangkaraniwang problema o malulutas ang isang karaniwang problema sa isang hindi karaniwang paraan. Iyon ang nagpapahalaga sa iyong aplikasyon: ang code na nagpapatupad ng mga patakaran sa negosyo na natatangi sa iyong app lamang - ang "lihim na sarsa."

Ang algorithm ng paghahanap at pag-ranggo ng Google, pag-filter ng timeline ng Facebook, "seksyong inirerekomenda para sa iyo" ng Netflix at mga algorithm ng compression ng data - ang code sa likod ng lahat ng mga tampok na ito ay "lihim na sarsa."

Ang third-party code - sa anyo ng mga aklatan - ay nagbibigay-daan sa iyo upang mabilis na maipatupad ang mga commoditized na tampok ng iyong app, upang maaari kang manatiling nakatuon sa iyong "lihim na sarsa."

Bakit ang mga dependencies ng third-party code ay masama

Tingnan ang anumang di-maliit na web-app na itinayo sa huling ilang taon at ganap kang mamangha sa pamamagitan ng dami ng code na talagang nagmula sa isang library ng third-party. Paano kung ang isa o higit pa sa mga aklatang third-party ay nagbago nang malaki, o nawala, o nabasag?

Kung open-source ito, marahil ay maaari mo itong ayusin ang iyong sarili. Ngunit gaano mo naiintindihan ang lahat ng mga code sa library na hindi mo pag-aari? Ang isang malaking kadahilanan kung bakit mo ginamit ang isang aklatan sa unang lugar ay upang makuha ang mga benepisyo ng code nang hindi kailangang mag-alala tungkol sa lahat ng mga detalye. Ngunit ngayon ay natigil ka. Ganap mong nakagapos ang iyong kapalaran sa mga dependencies na hindi mo pag-aari at hindi makontrol.

Huwag mag-alala, sa pagtatapos ng artikulong ito, makakahanap ka ng isang bagong pag-asa.

Marahil sa palagay mo ay pinalalaki ko, o nagsasalita mula sa isang purong pang-akademikong pananaw. Hayaan akong tiyakin ka - Mayroon akong dose-dosenang mga halimbawa ng mga kliyente na ganap na nag-snook sa kanilang sarili sa pamamagitan ng pag-emote ng third-party code na masyadong mahigpit sa kanilang app. Narito ang isang kamakailang halimbawa ...

Ang isang dating kliyente ng minahan ay nagtayo ng kanilang app gamit ang isang backend-as-a-Service provider na pag-aari ng Facebook, na tinatawag na Parse. Gumamit sila ng isang client client JavaScript na ibinigay ni Parse upang ubusin ang serbisyo ng Parse. Sa proseso, mahigpit nilang isinama ang lahat ng kanilang code - kasama ang code na "lihim na sarsa" - sa aklatang ito.

Tatlong buwan pagkatapos ng paunang paglunsad ng produkto ng aking kliyente - tulad ng sinimulan nila ang pagkuha ng ilang magagandang traksyon sa totoong, nagbabayad ng mga customer - inihayag ni Parse na isinara ito.

Ngayon sa halip na magtuon sa iterating sa kanilang produkto at lumalaki ang kanilang base ng customer, ang aking kliyente ay kailangang malaman kung paano lumipat sa alinman sa isang self-host, bukas na mapagkukunan na bersyon ng Parse, o palitan ang ganap na Parse.

Ang pagkagambala na sanhi nito para sa isang bata, tumatakbo na aplikasyon ay napakalaki na ang aking kliyente sa kalaunan ay na-scrap ang app nang buo.

Pagbalanse ng mabuti at masama

Ilang taon na ang nakalilipas, ang aking go-to solution para sa pagtagumpayan ng mga panganib habang pinapanatili ang mga benepisyo ng mga third-party-library ay ibalot ang mga ito gamit ang Adapter Pattern.

Mahalaga, balutin mo ang third party code sa isang adapter class o module na iyong isinulat. Ito ay gumagana upang ilantad ang mga pag-andar ng mga aklatan ng ikatlong partido sa isang paraan na kinokontrol mo.

Gamit ang pattern na ito, kung nagbabago ang isang library ng third-party o balangkas, o umalis, kailangan mo lamang ayusin ang kaunting adapter code. Ang natitirang bahagi ng iyong app ay mananatiling buo.

Diagram ng adaptor ng pattern mula sa Dofactory.com

Ito ay mahusay na tunog sa papel. Kung mayroon kang mga dependencies sa sarili na nagbibigay lamang ng ilang mga pag-andar, gagawin nito ang lansihin. Ngunit ang mga bagay ay maaaring makakuha ng pangit mabilis.

Naisip mo bang balutin ang buong library ng React (kasama ang JSX) bago gamitin ang alinman dito? Paano ang tungkol sa pambalot na jQuery, o Angular, o ang balangkas ng Spring sa Java? Mabilis itong nagiging isang bangungot.

Sa mga araw na ito inirerekumenda ko ang isang higit pang nuanced diskarte ...

Para sa bawat dependency na nais mong idagdag sa iyong codebase, suriin ang antas ng panganib na ipakikilala sa pamamagitan ng pagdaragdag ng dalawang mga kadahilanan:

  1. Ang posibilidad na ang dependency ay magbabago sa isang materyal na paraan.
  2. Ang halaga ng pinsala ng isang pagbabago sa materyal sa dependant ay gagawin sa iyong aplikasyon.

Ang isang library ng third-party o balangkas ay mas malamang na magbago kapag ang ilan o lahat ng mga sumusunod na bagay ay totoo:

  • Ito ay sa paligid ng maraming mga taon at nagkaroon ng maraming mga pangunahing release.
  • Malawakang ginagamit ito ng maraming mga komersyal na aplikasyon.
  • Mayroon itong aktibong suporta ng isang malaking samahan - mas mabuti ang isang kumpanya ng pangalan ng sambahayan o institusyon.

Ang isang library ng third-party o balangkas ay hindi gaanong masira sa iyong aplikasyon kapag ang ilan o ang lahat ng mga sumusunod na bagay ay totoo:

  • Ginagamit lamang ito ng isang maliit na bahagi ng iyong aplikasyon, sa halip na ginagamit sa buong.
  • Ang code na nakasalalay dito ay hindi bahagi ng "lihim na sarsa" na napag-usapan ko kanina.
  • Ang pag-alis nito ay nangangailangan ng kaunting mga pagbabago sa iyong codebase.
  • Ang iyong buong aplikasyon ay napakaliit at maaaring maisulat nang mabilis. (Mag-ingat sa isang ito - bihirang totoo ito sa napakatagal.)

Ang riskier ng isang bagay ay, mas malamang na dapat mong balutin ito o maiwasan ito nang buo.

Pagdating sa code na talagang nasa sentro ng halaga ng panukala ng iyong aplikasyon - ang iyong "lihim na sarsa" - kailangan mong maging sobrang proteksyon nito. Gawing independiyenteng posible ang code na iyon. Kung talagang kailangan mong gumamit ng isang dependency, isaalang-alang ang pag-iniksyon nito sa halip na direktang tumutukoy dito. Kahit na, mag-ingat.

Minsan nangangahulugan ito ng pagsasabi ng "hindi" sa isang library ng third-party na sa palagay mo ay talagang cool, o talagang gusto mong gamitin para sa isang kadahilanan o sa iba pa. Magpakatatag ka. Tiwala sa akin, babayaran ito. Tanungin lamang ang lahat ng mga taong namuhunan nang labis sa pinakaunang paglabas ng Angular, o ang aking dating kliyente na gumagamit ng Parse kahit saan. Hindi masaya. Maniwala ka sa akin.

Nagsasalita ng masaya, tingnan ito ...

Depende ng graph para sa explorer ng TinyTag

Ang imahe sa itaas ay ang dependency graph para sa isang application na tinatawag na TinyTag Explorer.

Ang pagbuo ng isang dependency graph para sa iyong umiiral na mga app ay isang mahusay na paraan upang maunawaan ang antas ng peligro na ipinakilala ng iyong mga dependencies. Pinagsama ko ang isang listahan ng mga libreng tool para sa pagbuo ng mga graph na katulad ng sa itaas sa iba't ibang wika kabilang ang JavaScript, C #, Java, PHP, at Python. Maaari mo itong makuha dito.

Tulungan mo akong tulungan ang iba

Nais kong makatulong sa maraming mga developer hangga't maaari sa pamamagitan ng pagbabahagi ng aking kaalaman at karanasan sa kanila. Mangyaring tulungan ako sa pamamagitan ng pag-click sa pindutan ng inirerekumenda ng ❤ (berdeng puso) sa ibaba.

Sa wakas, huwag kalimutang sunggaban ang iyong listahan ng mga libreng mga dependency ng graprower dito.