Dit bericht is voor het laatst bewerkt door Summer op 27-9-2017 om 15:32
Dit artikel is een kort verhaal dat Q&A imiteert, en de auteur gebruikt een humoristische stijl om kort het werk van architecten te analyseren: ik wil softwarearchitect worden. Dit is een uitstekende optie voor jonge softwareontwikkelaars. Ik wil het team leiden en belangrijke beslissingen nemen over databases en frameworks, webservers, enzovoort. Oh, dan wil je helemaal geen softwarearchitect zijn. Natuurlijk wilde ik de maker zijn van belangrijke beslissingen. Dat is prima, maar je neemt belangrijke beslissingen niet op je lijst, die irrelevante beslissingen zijn. Wat bedoel je? Zeg je dat databases geen belangrijke beslissingen zijn, weet je hoeveel we eraan uitgeven? Misschien kost het te veel. Databases zijn echter niet een van de belangrijke beslissingen. Hoe kun je dat zeggen? De database is de kern van het systeem, waar alle data wordt gesystematiseerd, geclassificeerd, geïndexeerd en geraadpleegd. Zonder een database zou er geen systeem zijn. De database is slechts een IO-apparaat dat toevallig enkele nuttige hulpmiddelen biedt voor classificatie, zoekopdrachten en informatierapportage, maar dit zijn slechts hulpfuncties van de systeemarchitectuur. Hulp? Dit is schandalig. Dat klopt, het is hulp. De bedrijfsregels van het systeem kunnen mogelijk gebruikmaken van sommige van deze tools, maar die tools zijn niet inherent aan de bijbehorende bedrijfsregels. Indien nodig kun je de bestaande vervangen door andere gereedschappen; En de bedrijfsregels zullen niet veranderen. Nou ja, maar het moest opnieuw gecodeerd worden, omdat deze tools in de oorspronkelijke database werden gebruikt. Dat is jouw probleem. Wat bedoel je? Je probleem is dat je denkt dat bedrijfsregels afhankelijk zijn van databasetools, maar dat is niet zo. Of in ieder geval, het zou niet zo moeten zijn totdat er een goede architectuur is geleverd. Het is gewoon gek. Hoe maak je bedrijfsregels die die tools niet gebruiken? Ik zeg niet dat ze geen databasetools gebruiken, maar ze zijn er niet van afhankelijk. Business rules hoeven niet te weten welke database je gebruikt. Dus hoe krijg je bedrijfsregels zonder te weten welke tools je moet gebruiken? Keer de afhankelijkheden om zodat de database afhankelijk is van bedrijfsregels. Zorg ervoor dat bedrijfsregels niet afhankelijk zijn van de database. Je praat onzin. Integendeel, ik gebruik de taal van softwarearchitectuur. Dit is het principe van afhankelijkheidsinversie: laag-niveau standaarden moeten vertrouwen op hoge niveau-standaarden. Onzin! Hoge criteria (ervan uitgaande dat we naar bedrijfsregels verwijzen) Laag-niveau criteria aanroepen (ervan uitgaande dat het naar databases verwijst). Daarom zal het high-level criterium vertrouwen op het low-level criterium volgens het principe dat de caller afhankelijk is van de callee. Iedereen weet dit! Dit geldt tijdens runtime. Maar bij compileren willen we afhankelijkheidsinversie hebben. De broncode van de high-level richtlijnen mag de broncode van de low-level richtlijnen niet vermelden. Kom nou! Hoe kun je een telefoontje plegen zonder het te noemen? Natuurlijk geen probleem. Dat is waar objectgeoriënteerd bij komt kijken. Objectoriëntatie draait om het creëren van een model in de echte wereld, waarbij data, functionaliteit en samenhangende objecten worden gecombineerd. Het gaat erom code te organiseren in een intuïtieve structuur. Dat zeggen ze? Zoals we allemaal weten, is dit de voor de hand liggende waarheid. Ja, dat is het wel, maar bij het gebruik van objectgeoriënteerde richtlijnen is het inderdaad mogelijk om het aan te roepen zonder het te vermelden. Hoe doe je dat? In objectgeoriënteerd ontwerp sturen objecten berichten naar elkaar. Dat klopt natuurlijk. Wanneer een afzender een bericht stuurt, weet hij niet welk type ontvanger het is. Het hangt af van de gebruikte taal. In Java kent de zender ten minste het basistype van de ontvanger. In Ruby weet de zender tenminste dat de ontvanger in staat is om de ontvangen berichten te verwerken. Dat klopt. Hoe dan ook, de afzender kent het specifieke type ontvanger niet. Dat klopt, nou, dat is het wel. Daarom kan een zender een ontvanger ontwerpen om een functie uit te voeren zonder het specifieke type ontvanger te vermelden. Dat klopt, dat klopt. Ik begrijp het. De afzender is echter nog steeds afhankelijk van de ontvanger. Dit geldt tijdens runtime. Het is echter anders wanneer het gecompileerd is. De broncode van de zender vermeldt niet of is afhankelijk van de broncode van de ontvanger. In feite hangt de broncode van de ontvanger af van de broncode van de zender. Echt niet! De afzender hangt nog steeds af van de klasse die hij stuurt. Misschien wordt het uit wat broncode duidelijker. De volgende alinea is geschreven in Java. Als eerste is er de afzender: pakketafzender; publieke klasse Sender { private Receiver receiver; publieke Sender (Ontvanger r) { ontvanger = r; } public void doSomething () { receiver.receiveThis (); } publieke interface Ontvanger { void receiveDit (); } }Hier is de ontvanger: pakketontvanger; Importafzender. Afzender; publieke klasse SpecificReceiver implementeert Sender.Receiver { public void receiveThis () { //do iets interessants. } }Opmerking: Ontvanger is afhankelijk van de zender, SpecificReceiver afhankelijk van de zender, en er is geen ontvangergerelateerde informatie in de zender. Ja, maar je liegt, je hebt de interface van de ontvanger in de sender-klasse geplaatst. Je begint het te begrijpen. Wat weet je ervan? Natuurlijk is het het principe van architectuur. De zender heeft de interface die de ontvanger moet implementeren. Als dat betekent dat ik geneste klassen moet gebruiken, dan ...... Geneste klassen zijn slechts een van de middelen om een doel te bereiken, er zijn ook andere manieren. Wacht even. Wat heeft dit met databases te maken? We begonnen te praten over databases. Laten we de code nog wat beter bekijken. De eerste is een eenvoudige zakelijke regel: package businessRules; importentiteiten. Iets; publieke klasse BusinessRule { private BusinessRuleGateway gateway; publieke BusinessRule (BusinessRuleGateway gateway) { this.gateway = gateway; } public void execute (String id) { gateway.startTransaction (); Something thing = gateway.getSomething (id); thing.makeChanges (); gateway.saveSomething (ding); gateway.endTransaction (); } }Bedrijfsregels hebben weinig gewicht. Dit is slechts één voorbeeld. Er zouden meer van zulke klassen kunnen zijn die veel verschillende bedrijfsregels implementeren. Oké, wat is Gateway precies? Het biedt alle data-toegangsmethoden via bedrijfsregels. Voer het als volgt uit: package businessRules; importentiteiten. Iets; publieke interface BusinessRuleGateway { Something getSomething (String id); void startTransaction (); void saveSomething (Something thing); void endTransaction (); }Opmerking: Dit staat in businessRules. Oké, wat is de Iets-klasse? Het vertegenwoordigt een eenvoudig bedrijfsobject. Ik zet het in entiteiten. pakketentiteiten; publieke klasse Iets { publieke void makeChanges () { //... } }Uiteindelijk kent de implementatie van BusinessRuleGateway, deze klas de echte database: pakketdatabase; importeer businessRules.BusinessRuleGateway; importentiteiten. Iets; publieke klasse MySqlBusinessRuleGateway implementeert BusinessRuleGateway { public Something getSomething (String id) { // gebruik MySQL om een ding te krijgen. } public void startTransaction () { // start MySql transactie } public void saveSomething (Something thing) { // save thing in MySql } public void endTransaction () { // end MySQL-transactie } }Daarnaast moet opgemerkt worden dat de bedrijfsregels de database tijdens runtime aanroepen; Echter, tijdens het compileren omvat en is de database afhankelijk van businessRules. Nou, ik denk dat ik het snap. Je gebruikt gewoon polymorfisme om te verbergen dat de database is geïmplementeerd vanuit business rules. Toch is er nog steeds een interface nodig om alle databasetools aan de bedrijfsregels te koppelen. Nee, helemaal niet. We hebben niet geprobeerd databasetools aan te bieden voor bedrijfsregels. In plaats daarvan gebruiken ze business rules om interfaces te creëren voor wat ze nodig hebben. Door deze interfaces te implementeren, kun je de juiste tools aanroepen. Ja, maar als je elke tool voor alle bedrijfsregels moet gebruiken, plaats dan gewoon de tool in de gateway-interface. Ah, ik denk niet dat je het nog begrijpt. Wat begrijpen? Dit is al duidelijk. Elke businessregel definieert slechts één interface voor de data-toegangstools die het nodig heeft. Wacht even, wat zeg je ervan? Dit is het Interface Segregation Principle. Elke business rule class gebruikt alleen bepaalde faciliteiten van de database. Daarom kunnen de interfaces die door elke business rule worden aangeboden alleen toegang krijgen tot de bijbehorende faciliteiten. Dit betekent echter dat er veel interfaces en veel kleine implementatieklassen zijn die andere databaseklassen aanroepen. Geweldig, je begint het te begrijpen. Maar het is te rommelig en tijdverspilling. Waarom doe je dit? Dit is georganiseerd en bespaart tijd. Kom op, haal veel code om de code zelf. Integendeel, irrelevante beslissingen kunnen worden uitgesteld door belangrijke architectonische beslissingen. Wat moet dat betekenen? Ik herinner me dat je in het begin zei dat je softwarearchitect wilde worden, toch? Je wilt alle beslissingen nemen die echt belangrijk zijn. Ja, dat dacht ik al. Je wilt beslissingen nemen over databases, webservers en frameworks, toch? Ja, je zegt dat dat allemaal niet uitmaakt. Gewoon irrelevante inhoud. Dat klopt. Dat is het. De belangrijke beslissingen die softwarearchitecten nemen, zijn die welke je in staat stellen beslissingen te nemen over databases, webservers en frameworks. Maar je moet eerst beslissen welke het is! Nee, het werkt niet. In feite kunnen deze later in de ontwikkelingscyclus worden beslist, wanneer de informatie ruimer is. Het is een ramp als architecten frameworks van tevoren identificeren, om vervolgens te ontdekken dat ze niet de vereiste prestaties leveren of onaanvaardbare beperkingen introduceren. Pas wanneer de architect besluit de beslissing uit te stellen, zal hij een beslissing nemen wanneer de informatie voldoende is; Teams die geen trage en resource-intensieve IO-apparaten en frameworks gebruiken, kunnen snelle, lichtgewicht testomgevingen creëren naar eigen inzicht van architecten. Alleen de architecten geven om wat echt belangrijk is en vertragen degenen die dat niet doen, en zo'n team is de gelukkige. Onzin, ik begrijp helemaal niet wat je bedoelt. Kijk goed naar dit artikel, anders moet je nog tien jaar wachten om het uit te zoeken.
|