Tento příspěvek naposledy upravila Summer dne 27. 9. 2017 v 15:32
Tento článek je povídkou, která napodobuje otázky a odpovědi, a autor používá humorný styl k stručné analýze práce architektů: Chci být softwarovým architektem. To je skvělá volba pro mladé softwarové vývojáře. Chci vést tým a dělat důležitá rozhodnutí ohledně databází a frameworků, webserverů atd. Aha, takže vůbec nechceš být softwarovým architektem. Samozřejmě jsem chtěl být tím, kdo rozhoduje důležitě. To je v pořádku, ale do seznamu nezahrnujete důležitá rozhodnutí, která jsou irelevantní. Jak to myslíš? Říkáte, že databáze nejsou důležitá rozhodnutí, víte, kolik na ně utrácíme? Možná to stojí moc. Databáze však nejsou jedním z důležitých rozhodnutí. Jak to můžeš říct? Databáze je jádrem systému, kde jsou všechna data systematizována, klasifikována, indexována a přístupná. Bez databáze by systém neexistoval. Databáze je pouze IO zařízení, které náhodou poskytuje užitečné nástroje pro klasifikaci, dotazování a reportování informací, ale to jsou pouze pomocné funkce architektury systému. Pomoc? To je pobuřující. Přesně tak, je to pomocné. Obchodní pravidla systému mohou některé z těchto nástrojů využívat, ale tyto nástroje nejsou součástí příslušných obchodních pravidel. Pokud je potřeba, můžete stávající nahradit jinými nástroji; A obchodní pravidla se nezmění. Ano, ale muselo to být přeprogramováno, protože tyto nástroje byly použity v původní databázi. To je tvůj problém. Jak to myslíš? Váš problém je, že si myslíte, že obchodní pravidla závisí na databázových nástrojích, ale nejsou. Nebo alespoň by to tak nemělo být, dokud nebude zajištěna dobrá architektura. Je to prostě šílené. Jak vytvořit obchodní pravidla, která tyto nástroje nevyužívají? Neříkám, že nepoužívají databázové nástroje, ale nejsou na nich závislí. Obchodní pravidla nemusí vědět, kterou databázi používáte. Jak tedy získat obchodní pravidla, aniž byste věděli, jaké nástroje použít? Invertujte závislosti tak, aby databáze závisela na obchodních pravidlech. Ujistěte se, že obchodní pravidla nejsou závislá na databázi. Mluvíš nesmysly. Naopak, používám jazyk softwarové architektury. Toto je princip inverze závislosti: nízkoúrovňové standardy by měly spoléhat na vysoké úrovně. Nesmysl! Kritéria vysoké úrovně (za předpokladu, že se vztahují k obchodním pravidlům) Volání nízkoúrovňových kritérií (předpokládá se odkaz na databáze). Proto se kritérium vysoké úrovně bude opírat o kritérium nízké úrovně podle principu, že volající závisí na volaném. To ví každý! To platí za běhu. Ale při kompilaci chceme inverzi závislosti. Zdrojový kód pokynů na vysoké úrovni by neměl zmiňovat zdrojový kód těchto pokynů. No tak! Jak můžete zavolat, aniž byste to zmínili? Samozřejmě, že není problém. To je to, co objektově orientované znamená. Objektová orientace se týká tvorby reálných modelů, kombinování dat, funkcionality a soudržných objektů. Jde o organizaci kódu do intuitivní struktury. To se říká? Jak všichni víme, je to zřejmá pravda. Ano, je to však možné při použití objektově orientovaných pokynů skutečně vyvolat bez zmínky. Jak to udělat? V objektově orientovaném návrhu si objekty navzájem posílají zprávy. To je samozřejmě pravda. Když odesílatel odesílá zprávu, nezná typ příjemce. Záleží na použitém jazyku. V Javě odesílatel zná alespoň základní typ příjemce. V Ruby alespoň odesílatel ví, že příjemce je schopen zpracovávat přijaté zprávy. Přesně tak. V každém případě však odesílatel nezná konkrétní typ příjemce. Přesně tak, no, je. Proto může odesílatel navrhnout přijímač tak, aby vykonával určitou funkci, aniž by zmínil konkrétní typ přijímače. Přesně tak, přesně tak. Rozumím. Přesto odesílatel stále závisí na příjemci. To platí za běhu. Nicméně je jiná při kompilaci. Zdrojový kód odesílatele nezmiňuje ani nezávisí na zdrojovém kódu příjemce. Ve skutečnosti zdrojový kód příjemce závisí na zdrojovém kódu odesílatele. V žádném případě! Odesílatel stále závisí na třídě, kterou odešle. Možná z nějakého zdrojového kódu to bude jasnější. Následující odstavec je napsán v Javě. Nejprve je tu odesílatel: odesílatel balíku; veřejná třída Sender { soukromý příjemce Receiver; veřejný odesílatel (příjemce r) { příjemce = r; } public void doNěco () { receiver.receiveThis (); } veřejné rozhraní Receiver { void receiveThis (); } }Tady je přijímač: přijímač balíčků; Importovat odesílatele. Odesílatel; public class SpecificReceiver implementuje Sender.Receiver { public void receiveThis () { //do something interesting. } }Poznámka: Příjemce závisí na odesílateli, SpecificReceiver na odesílateli a v odesílateli nejsou žádné informace týkající se příjemce. Ano, ale lžeš, přidal jsi rozhraní příjemce do třídy odesílatele. Začínáš chápat. Co ty víš? Samozřejmě, že je to princip architektury. Odesílatel má rozhraní, které musí příjemce implementovat. Pokud to znamená, že musím používat vnořené třídy, pak ...... Vnořené třídy jsou jen jedním z prostředků k cíli, existují i jiné způsoby. Počkej chvilku. Co to má společného s databázemi? Začali jsme mluvit o databázích. Podívejme se na kód trochu víc. První je jednoduché obchodní pravidlo: balíčkové businessRules; importovat entity. Něco; veřejná třída BusinessRule { private BusinessRuleGateway brána; public BusinessRule (brána BusinessRuleGateway) { this.gateway = brána; } public void execute (String ID) { gateway.startTransaction (); Something thing = gateway.getSomething (id); thing.makeChanges (); gateway.saveSomething (věc); gateway.endTransaction (); } }Obchodní pravidla nemají velkou váhu. To je jen jeden příklad. Mohlo by existovat více takových tříd, které implementují různé obchodní pravidla. Dobře, co přesně je Gateway? Poskytuje všechny metody přístupu k datům prostřednictvím obchodních pravidel. Implementujte to následovně: balíčkové businessRules; importovat entity. Něco; veřejné rozhraní BusinessRuleGateway { Something getSomething (String ID); void startTransaction (); void saveSomething (Něco věc); void endTransaction (); }Poznámka: Toto je v businessRules. Dobře, co je to třída Něco? Představuje jednoduchý obchodní objekt. Dávám to do entit. balících entit; public class Something { public void makeChanges () { //... } }Nakonec implementace BusinessRuleGateway, tato třída zná skutečnou databázi: databázi balíčků; importovat businessRules.BusinessRuleGateway; importovat entity. Něco; public class MySqlBusinessRuleGateway implementuje BusinessRuleGateway { public Something getSomething (String ID) { // use MySQL to get a thing. } public void startTransaction () { // start MySql transaction } public void saveSomething (Something thing) { // save thing in MySQL } public void endTransaction () { // end MySql transaction } }Dále je třeba poznamenat, že obchodní pravidla volají databázi za běhu; Nicméně při kompilaci databáze zahrnuje a závisí na businessRules. No, myslím, že to chápu. Polymorfismus jen používáš k tomu, abys skryl fakt, že databáze je implementována z obchodních pravidel. Nicméně je stále potřeba rozhraní, které poskytne všechny databázové nástroje pro obchodní pravidla. Ne, vůbec ne. Nepokusili jsme se poskytovat databázové nástroje pro obchodní pravidla. Místo toho používají obchodní pravidla k vytváření rozhraní pro to, co potřebují. Implementace těchto rozhraní vám umožní volat správné nástroje. Ano, ale pokud potřebujete používat všechny nástroje pro všechna obchodní pravidla, prostě je vložte do rozhraní brány. Ah, myslím, že to pořád nechápeš. Rozumět čemu? To je už jasné. Každé obchodní pravidlo definuje pouze jedno rozhraní pro nástroje pro přístup k datům, které potřebuje. Počkej chvíli, co říkáš? To je princip segregace rozhraní. Každá třída obchodních pravidel používá pouze určité funkce databáze. Proto rozhraní poskytovaná každým obchodním pravidlem mohou přistupovat pouze k příslušným zařízením. To však znamená, že existuje mnoho rozhraní a mnoho malých implementačních tříd, které volají jiné databázové třídy. Skvělé, začínáš chápat. Ale je to příliš chaotické a ztráta času. Proč to dělat? Je to organizované a šetří čas. No tak, sežeň hodně kódu jen pro samotný kód. Naopak, irelevantní rozhodnutí mohou být zpožděna důležitými architektonickými rozhodnutími. Co to znamená? Pamatuji si, že na začátku jsi říkal, že chceš být softwarovým architektem, že? Chcete dělat všechna rozhodnutí, která opravdu mají význam. Ano, to jsem si myslel. Chcete rozhodovat o databázích, webových serverech a frameworkech, že? Ano, říkáš, že na tom nezáleží. Prostě nesouvisející obsah. Přesně tak. To je vše. Důležitá rozhodnutí, která činí softwaroví architekti, jsou ta, která vám umožní rozhodovat o databázích, webových serverech a frameworkech. Ale musíte se nejdřív rozhodnout, které z nich! Ne, nefunguje to. Ve skutečnosti lze tyto hodnoty rozhodnout později ve vývojovém cyklu, kdy je informací více. Je katastrofa, pokud architekti předem identifikují rámce, jen aby zjistili, že neposkytují požadovaný výkon nebo zavádějí nesnesitelná omezení. Teprve když se architekt rozhodne rozhodnutí odložit, učiní rozhodnutí, až bude dostatek informací; Týmy, které nepoužívají pomalá a zdrojově náročná IO zařízení a frameworky, mohou vytvářet rychlá, lehká testovací prostředí podle uvážení architektů. Pouze jeho architekti se zajímají o to, na čem opravdu záleží, a zdržují ty, kteří ne, a takový tým je ten šťastný. Nesmysl, vůbec nechápu, co tím myslíš. No, dobře si přečtěte tento článek, jinak budete muset čekat dalších 10 let, než na to přijdete.
|