Dynamisk navigering for høyere performance

redusere eller fjerne navigasjons koden fra GUI ved å legge avledet lenker og, på samme tid, forbedre ytelsen.
Modellering klassestrukturer tar litt tenkning, og når du er ferdig tenkning og tegningen, og etter at du starter opp ved hjelp av modellen, så vil du bruke forferdelig mye kode traversering lenker for å hente triviell info i et gitt objekt struktur. Navigere de samme somtimes komplisert link-banene om og om igjen tar CPU kraft, og det tar også mye overflødig kode og /eller uttrykk tilgang de samme navigeringsbanene om og om igjen. I Fet arkitektur vil du også plassere redundante abonnement fra mange forskjellige steder til samme mål som abonnerer på de samme banene, over en over igjen.
Men med Fet du kan ofte direkte adresse unødvendig navigasjon, redundant navigasjons kode /OCL-uttrykk og gevinst nedgang på CPU belastning ved å legge avledet foreninger i stedet gjør de få vedvarende linker mer nyttig og " intelligent ". Og dessuten å gjøre dette direkte i din modell modellen vil samtidig reflektere mer spesifikt hvilke deler av modellen faktisk brukes. Og hvordan.
Et eksempel kan vise en typisk situasjon der tilsette mange avledet linker, utvide modellen med mer nyttig info, vil resultere i mer effektiv, mindre overflødig og mer lesbar kode. Hvis vi snakket tradisjonelle håndverks du sannsynligvis ville ha trodd jeg spøkte, fordi vi vanligvis ikke redde oss fra flere problemer ved å legge til flere relasjoner mellom objekter ...! Men jeg er ikke fleiper - du faktisk vil oppnå alle de nevnte fordelene ved å legge noen enkle linjer til modellen ved hjelp Fet
eksempel
En lastebil vogntog kan tjene oss med et eksempel.. Eksempelet modellen vil bestå av kjøretøy enheter, noen Pakker og en tur objekt holde hele turen info og beregninger. Med disse tre grunnleggende kategoriene vil vi ende opp med å skrive nesten 50% av kode (eller uttrykk) i algoritmer navigere grunnstrukturen som har bare tre vedvarende linker ... Slik koding er trivielt, tar tid og legger ingenting av verdi til systemet.
Først en " RIL verden representasjon " av eksempelet før representerer den ved hjelp av et UML klassediagram (" RIL " er mine initialer):
Fig 1: Dette vogntoget inneholder av pakker, men bare foran mest VehicleUnit holder Trip info om avstander, arrangementer og økonomiske beregninger . største nettstedene Se bort fra kunst aspekter av illustrasjonen. Av flere grunner, ikke diskutert her, VehicleUnits vist ovenfor har alltid en tur gjenstand festet, men bare foran mest turen objekt representerer hele kombinasjonen. De andre tur gjenstander /kalkulatorer er " demobilisert " inntil trailer (muligens) er koblet fra lastebil, og deretter tilhengeren vil være et gyldig (" foran mest ") TripHolder på egen hånd
Tenk deg at du ser på en av de kjøretøy enheter eller en av de Parcels i. en UI og du vil nok gjerne vite mer om turen relatert info, kanskje avstander reist, adresser besøkte, på å besøke ordre, kostnader eller inntekter per km etc (alt administreres av turen objekt).
Det er bare tre relasjoner i denne modellen, men likevel måtte du tenke to ganger når du prøver å navigere riktig å prøve å finne den " kalkulator " (her representerer en " tur klassen ").
Det ville være enda verre hvis du ønsker å gjennomføre noen generiske logikk eller beregninger for de VehicleUnits fordi du vil alltid ha for å være sikker på at du navigere til " foran de fleste kjøretøyenheten " (kan kalle det det " Bergingsbil ") og derfra direkte til turen info (kalkulatoren).
I den virkelige søknaden det er så mye info som følger med denne grunnleggende struktur som de tre lenker vil bli akses /navigeres igjen og igjen så mange ganger at mange hundre linjer med kode (og /eller OCL uttrykk) ville være skrevet " her, der og overalt ". En av de dårlige tingene med dette er at hvis du eksplisitt traversere disse linkene hver gang du trenger tilgang til et objekt /attributt i den andre enden av strukturen, må du utføre denne logikken i CPU hver gang.
annen ille er at kjernevirksomheten logikk ville " drukne " i koden og uttrykkene som arbeider med dette trivielle navigasjon som " hvis da annet, for i: = " og tilordne sjekker. Det er der avledet koblinger kan hjelpe mange til å unngå en logisk rot (avledet attributter ville også, selvfølgelig).
Figur 2: En enkel klasse modell av illustrasjonen ovenfor kunne se omtrent slik ut:
Navigasjons problemet er mer opplagt i denne klassen modellen enn i " RIL verden illustrasjon ".
Hvis jeg valgte en pakke i en GUI liste og nødvendig info fra turen gjenstand jeg kunne ikke være sikker på nøyaktig navigasjon banen til " mobilisert " tur objekt som er den ene holder gyldig tur info. Eksempel:
Hvis pakken ble lastet på en trailer uttrykket 'vehicleUnit.trip' vil returnere en demobilisert tur objekt, men hvis pakken ble lastet på dumperen det vil returnere ønsket " mobilisert " tur objekt. Denne komplikasjonen er grunn nok til å legge en avledet lenke fikse problemet direkte i modellen slik at man aldri igjen vil måtte vurdere dette når du utformer algoritmer eller navigerer strukturen. Jeg vil definitivt legge en link som heter " EffectiveTrip " som følger:
Figur 3: En link som heter " EffectiveTrip " ble lagt inn i modellen. (Jeg prøver alltid å la blå farge representerer " vedvarende " (= " fryse ") og oransje representerer " avledet " for lenker).
Som jeg allerede kan forutse at denne koblingen skal åpnes for mange vogntog (i nett osv) ville jeg vanskelig kode avledning optimalisere logikken her for å finne " foran mest " kjøretøy og det betyr traversering trailer /hauler koblingen og stoppe når koblingen dumperen er null (= IsFrontMost). Derfra kan vi referere turen objektet direkte. Men jeg vet også at det å finne front mest kjøretøy (kombinasjonen dumperen) er veldig typisk, og vil skje enda oftere enn tilgang til turen objektet selv. Jeg vet allerede at koblingen EffectiveTrip også kan bruke en slik avledet link! Lar legge det med en gang gi den navnet "CombinationFirst '.
Jeg choosed navnet 'CombinationFirst' fordi da du umiddelbart realisere typisk i denne situasjonen. Det er en typisk liste håndtering problem. Du kan allerede forestille nytten av en annen avledet link som vi kan kalle "CombinationLast 'og enda en tredje link som heter' CombinationUnits '!
jeg kan forsikre at disse lenkene vil bli hyppig brukt, og dermed " kostnadene " evaluere dem vil være nedbetalt allerede andre gang du bruker noen av dem!
Figur 4: Har ikke også avledet lenker krever CPU for å bli vurdert ...? spør du kanskje. Svaret er, ja selvfølgelig - men bare en gang - hvis du abonnerer elementene endres ikke. Og dette er ikke veldig sannsynlig her, men veldig " hot spot " struktur her vil bli brukt i mange steder i logikken tilgang gjenstander krysse over svært ofte, og når du gjør det linkene allerede direkte referanser forekomster du vil ha tilgang til. Se på " rot " nedenfor ...! :
Denne høy ytelse løsning ved hjelp av modellen som et verktøy for optimalisering, og samtidig de ekstra koblingene er oppklarende /indikerer direkte i modellen den tiltenkte bruk av denne spesielle strukturen!
For de av dere som tror at jeg endelig fikk sint jeg kan fortelle at jeg ikke gjorde det. I stedet jeg økte hastigheten på beregningene og alle aktiviteter knyttet til denne strukturen i en virkelig verden program med mange tusen prosenter i forhold til eksplisitt å definere hele navigeringsbane hver gang kombinasjonen tur eller en bestemt kjøretøyenhet (eller attributt i noen av dem ) ble åpnet!
Alle typer data blir lagret i denne strukturen, og mer enn 30 avledet attributter for ulike beregningsmessig tilgang til struktur og tilbake hele tiden gi klienten brukeren med sanntid beregninger av inntekter /km avstand, avstand aksjer i total , andel av aksjene i ... etc, etc.
ting er å la en avledet lenken bruke andre lenker som ofte ass mulig, så selv behovet for omvurdere linkene når ting endres synker!
siste påstanden kan verifiseres veldig tydelig med et eget eksempel som viser hvor viktig det er å " gjenbruk " alt du utlede til alle høyere nivå (om hvilken del av strukturen er mer sannsynlig å endre og hvilken del som er mer " statisk "). Med " gjenbruk " Jeg mener " CPU arbeidet allerede gjort " ved utledning av koblingen. Mer om dette kan være gjenstand for en egen artikkel.
Nå ser på koden. Vi trenger å få tak i tur objekt (for noen reson), fra en Parcel, men vi vet ikke på hvilken VehicleUnit vi er lastet slik at vi begynner å lete etter den ved hjelp av koblingen " EffectiveTrip " som " huder " logikken bestemme hvilke tur objektet er " mobilisert " (dvs. " effektiv "):
funksjon TParcel.CalculateTrip_Something ...: Double; Var TripObj: TTrip; begynne TripObj: = vehicleUnit.effectiveTrip; //det er alt! ...
Easy, er dette klart kode. Detaljene om hvordan vi fikk tak i den riktige turen objektet må ikke blande opp forretningslogikken arbeider med tilgang eller beregninger i objektstrukturen.
I vår virkelige verden søknad både VehicleUnits og pakker har en felles superklasse (ikke vist her). Et kjøretøy kan lastes på en annen bil, akkurat som alle andre pakker så koden ovenfor selv simplier i mitt siste generisk modell der avledet koblingen er " virtuell overrided " i forskjellige underklasser. Min endelige koden går slik:
begynne TripObj: = effectiveTrip; //det er alt!
Parcel vil synes det er gyldig tur ved hjelp av denne kommandoen, uansett hvor komplisert banen kan være. Dette er vist i figur 5 hvor en ny felles superklasse faktisk eier den vedvarende og avledet lenke til turen klassen og EffectiveTrip-link er implementert først i TParcel og deretter overrided for VehicleUnit klassen som vist nedenfor.
Figur 5: Her endret jeg modellen til å bli mer generisk slik at alle " planable objekt " å gjennomføre en gruppe med andre planable gjenstander - og som modell går mer generell rollenavnene gjøre det også.
Reiseinfo gjelder direkte for en Parcel også (via AbstractPlanPortion) fordi et transportselskap kan planlegge en pakke som skal leveres med, for eksempel, et fly som tilsammen er vi ikke interessert i - men vi er fortsatt interessert i å holde styr på noen tur hendelser involvert i selve transporten, og dokumentasjon og transaksjoner knyttet til pakken selv etc. Men dette betyr også at når det er behov for tilgang til " effektiv " tur objekt vi trenger også å utføre svært kompliserte kontroller over hele strukturen prøver å finne ut i hvilken sammenheng den (riktig, " mobilisert ") tur objekt kan bli funnet ... Dette vil virkelig gjøre vår logikk litt komplisert for en slik enkle ting som rett og slett hente noen data fra strukturen. En ekte mareritt faktisk ...
Denne komplikasjonen av en enkel ting er ikke så veldig unikt. Hva er unikt er hvordan det kan håndteres ved bruk av Bold teknologi med sine avledet lenker.
Parcel kan være TripHolder selv, eller hvis Parcel er lastet på en bærer det vet ikke om det er lastet på transportøren som faktisk holder turen info. Vi ville virkelig trenger å gjøre noen navigatiion her. I en situasjon som dette kan du lett forestille seg hvor mye koding og hvor komplisert OCL uttrykk skulle få tilgang til informasjon i strukturen. Din kjernevirksomhet logikk ville " drukne " i navigasjon logikken når rett og slett hente trivielle ting fra strukturen og CPU vil bruke masse tid på å finne din vei (e) til målet objekter /data


slutt:. Tre (3) persistente lenker holde strukturen alle sammen endte opp i ytterligere fem (5) svært nyttige avledet lenker! Resultatet er at den endelige søknaden går mye raskere og forretningslogikk holdes mer bortsett fra trivielle navigasjon uendelige krysser objektstrukturer.
Før notering den mest effektive koden for de optimaliserte hardkodede avledninger av linkene, ønsker jeg å konkludere med at med disse linkene kan du, fra hvor som helst i strukturen, gå hvor som helst - direkte - ved å referere leddeler med navn fullt avklare hva du har tenkt å få tilgang, og dette vil bli gjort på den mest effektive måten du kan komme opp med å bruke den vanlige Bold arkitektur.
Med " effektiv " Jeg mener " alltid direkte tilgang til det ønskede målet objektet eksempel " (med unntak av den første evalueringen wich i mitt tilfelle skjer bare én gang i hundrevis av aksesser ...).
Dette er bare en del av konseptene vi brukt bevisst for å muliggjøre hva som ikke var mulig før: bruker vanlig, men " ren design ", modellert og strukturerte objektorientert virksomhet klasser utføre høy ytelse sanntid (re) beregninger av svært avanserte tur beregninger (ikke omtalt her). På en enkelt CPU (applikasjonsserver) for flere klienter.



Derivation kode, med kommentarer
I koden nedenfor jeg understreket all den interne referanse av de utledede lenker (" effektiv gjenbruk av allerede evaluert resultatene ") .
Jeg brukte også lokale variabler og dermed unngår den interne " ser opp " av Fet medlemmer mer enn én gang (= > du unngår gjentatt aktivering av interne dristige arrangementer osv).
effektiviteten av hele konseptet diskutert og detaljert koding nedenfor er bekreftet ved hjelp ProDelphi profiler (svært høy nøyaktighet (+ -3%) på måling kode ytelse). product: {TParcel} prosedyre TParcel._EffectiveTrip_DeriveAndSubscribe (...); //Hvis lastet bærere (effektive) tur er returnert, //annet den lokale turen (hvis noen) .var CarrierObj: TVehicleUnit; ResultValue: TTrip; begynne M_batchHolder.DefaultSubscribe (Subscriber, breResubscribe); CarrierObj: = batchHolder; hvis Assigned (CarrierObj) da begynne CarrierObj.M_EffectiveTrip.DefaultSubscribe (Subscriber, breResubscribe); ResultValue: = CarrierObj.EffectiveTrip; ende annet begynne M_trip.DefaultSubscribe (Subscriber, breResubscribe); ResultValue: = turen; ende; M_EffectiveTrip.BoldObject: = ResultValue; end {TVehicleUnit} prosedyre TVehicleUnit._EffectiveTrip_DeriveAndSubscribe (...); Var HaulerObj: TVehicleUnit; ResultValue, TripObj: TTrip; begynne ResultValue: = null; M_CombinationFirst.DefaultSubscribe (Subscriber, breResubscribe); HaulerObj: = CombinationFirst; //Den traversering er allerede gjort her hvis Assigned (HaulerObj) da begynne HaulerObj.M_Trip.DefaultSubscribe (Subscriber, breResubscribe); TripObj: = HaulerObj.trip; hvis Assigned (TripObj) da begynne TripObj.M_IsMobilized.DefaultSubscribe (Subscriber); hvis TripObj.IsMobilized deretter ResultValue: = TripObj; ende; ende; M_EffectiveTrip.BoldObject: = ResultValue; ende; prosedyre TVehicleUnit._CombinationFirst_DeriveAndSubscribe (...); //Denne linken vil være den raske " kort cut " brukes av mange mange //funksjoner i dette omfang og andre koblinger og attributter, og dermed //betyr optimalisering, ikke " ekstra " eller " godteri " i model.var LoopObj: TVehicleUnit; begynne LoopObj: = Selv; //Traverse fremover LoopObj.M_hauler.DefaultSubscribe (Subscriber, breResubscribe); mens Assigned (LoopObj.Hauler) gjør begynne LoopObj: = LoopObj.Hauler; LoopObj.M_hauler.DefaultSubscribe (Subscriber, breResubscribe); ende; M_CombinationFirst.BoldObject: = LoopObj; ende; prosedyre TVehicleUnit._CombinationLast_DeriveAndSubscribe (DerivedObject: TObject; Subscriber: TBoldSubscriber); Var LoopObj: TVehicleUnit; begynne LoopObj: = Selv; LoopObj.M_trailer.DefaultSubscribe (Subscriber, breResubscribe); mens Assigned (LoopObj.trailer) gjør begynne LoopObj: = LoopObj.trailer; LoopObj.M_trailer.DefaultSubscribe (Subscriber, breResubscribe); ende; M_CombinationLast.BoldObject: = LoopObj; ende; prosedyre TVehicleUnit.CombinationUnits_DeriveAndSubscribe (...); Var LoopObj: TVehicleUnit; Resultatlisten: TBoldObjectList; begynne M_CombinationUnits.Clear; Resultatlisten: = TBoldObjectList.Create; prøv M_CombinationFirst.DefaultSubscribe (Subscriber, breResubscribe); LoopObj: = CombinationFirst; gjenta ResultList.Add (LoopObj); LoopObj.M_trailer.DefaultSubscribe (Subscriber, breResubscribe); LoopObj: = LoopObj.trailer; inntil LoopObj = nil endelig M_CombinationUnits.AddList (resultatlisten); FreeAndNil (resultatlisten); end, end, prosedyre TVehicleUnit._CombinationLoadItems_DeriveAndSubscribe (DerivedObject: TObject; Subscriber: TBoldSubscriber); //En liste samle alle (batch) objekter lastet på enhver enhet i //vogntoget. Implementert for bekvemmelighet og //clearification.var UnitCnt, jeg: Integer; UnitObj: TVehicleUnit; begynne M_CombinationLoadItems.Clear; CombinationUnits.DefaultSubscribe (Subscriber, breResubscribe); UnitCnt: = CombinationUnits.Count; hvis UnitCnt > 0 da begynne for i: = 0 til UnitCnt-en ikke begynne UnitObj: = CombinationUnits [i]; UnitObj.loadedItems.EnsureObjects; UnitObj.loadedItems.DefaultSubscribe (Subscriber); //Samle alle hvis UnitObj.loadedItems.Count > 0 da M_CombinationLoadItems.AddList (UnitObj.loadedItems); ende; end, end,
//Rolf Lampa plakater (Current postadresse: rolf-dot-lampa-at-rilnet-dot-com)



Previous:
Next Page: