Programmering

Utvikle konfigurerbare programvare med letthet

Å utvikle lett konfigurerbar programvare er av største betydning i dagens forretningsmiljø. Programvareapplikasjoner vurderes ikke lenger bare etter mengden forretningslogikk som de innkapsler; de blir også bedømt etter hvor enkle de er å vedlikeholde. Evnen til å endre programvareadferd via konfigurasjon utgjør et viktig aspekt av denne vedlikeholdssyklusen.

Mens Java-språket gir en rekke funksjoner, for eksempel eiendomsfiler og ressurspakker, for å hjelpe konfigurasjonen, mangler disse funksjonene som kreves for dagens dynamiske forretningsmiljøer. Mange Java-standarder, verktøy og containere bruker allerede mer avanserte og tilpassede XML-konfigurasjonsformater.

Obix Framework er et open source-rammeverk som gir vanlige midler og formater for lagring av konfigurasjonsdata i XML, og for tilgang til disse dataene via enkle Java-objekter. Det muliggjør modulering av konfigurasjonsdata ved å la konfigurasjonsfiler importeres og inkluderes i hverandre, og ved å organisere konfigurasjonsinformasjon i "moduler".

I tillegg støtter den "hete" konfigurasjonsendringer - gjennom automatisk gjenkjenning og automatisk innlasting av endringer i konfigurasjonsdata - og gir også støtte for Java Naming and Directory Interface API (JNDI). Videre kan den integreres i Java-applikasjoner på flere måter, blant annet gjennom Java Management Extensions (JMX) og Java Platform, Enterprise Edition-lyttere som ikke krever koding, samt vanlige Java-klasser som kan påberopes direkte. Til slutt gir rammeverket et brukervennlig plugin-API som lar utviklere utvide det til å utføre initialiseringsrelaterte oppgaver. Denne API-en har blitt brukt av Obix-teamet til å tilby initialiseringsverktøy for andre open source-rammer som Apache's log4j, Hibernate og Commons DBCP (databaseforbindelsesbassenger).

I denne veiledningen beskriver jeg et hypotetisk scenario som krever konfigurerbar programvare og som vi lager skjelettapplikasjoner for ved hjelp av Obix. Det første eksemplet gir det nærmeste til et "Hello World" -konseptbevis, mens det andre og tredje utvider denne applikasjonen for å vise mindre trivielle aspekter ved konfigurasjon.

Vær oppmerksom på at alle kodeeksemplene i denne artikkelen er pakket som et arkiv, som kan lastes ned via lenken i Resources.

Problem scenario

Verdsettelse av finansielle eiendeler som aksjer eller opsjoner innebærer noen ganger å simulere prisen på eiendelen tusenvis av ganger, og ta gjennomsnittet av disse verdiene - i troen på at gjennomsnittet gir en best gjetning om eiendelens "sanne" fremtidige verdi. Slike simuleringer krever vanligvis statistisk innspill i form av gjeldende pris på eiendelen (e), gjennomsnittsprisen over et gitt tidsrom, samt avvik fra gjennomsnittet.

La oss anta at vi lager en applikasjon for å verdsette slike instrumenter. Som sådan må denne applikasjonen laste ned de statistiske inngangene via en webtjeneste, og detaljene - for eksempel URL og autentiseringsinformasjon - for å koble til denne tjenesten lagres i et konfigurasjonsdokument. Det er nok å si at antall simuleringer som skal utføres for en gitt verdivurderingsforespørsel, også skal være fleksible og som sådan spesifiseres via konfigurasjon.

Eksempel 1: En grunnleggende konfigurasjonsfil

I dette eksemplet lager vi en grunnleggende konfigurasjonsfil, example1-config.xml, for applikasjonen vår, som inneholder detaljene for tilkobling til webtjenesten som gir de statistiske inngangene til verdsettelsesprosessen. Denne konfigurasjonsfilen vil også lagre antall simuleringer som skal utføres for enhver verdsettelsesforespørsel. Denne filen (i tillegg til konfigurasjonsfilene for de andre eksemplene) er i konfigurasjonsmappen til det nedlastbare arkivet som er tilknyttet denne opplæringen. Innholdet i konfigurasjonsfilen er listet opp som følger:

//www.some-exchange.com/marketdata

trading_app_dbo

nopassword

10000

Hvis vi undersøker filen mer detaljert, legg merke til at den starter med rotnoden ; dette markerer begynnelsen på et Obix-konfigurasjonsdokument. Det er fire noder, som hver inneholder en konfigurasjonsoppføring. De tre første inneholder URL, bruker-ID og passord for tilkobling til inngangstjenesten; den endelige oppføringen inneholder antall simuleringer som skal utføres for hver verdsettelsesforespørsel. Legg merke til at hver oppføring har en unik nøkkel, som spesifisert av entryKey attributt, og at verdien i hver oppføring er innkapslet av en node.

Deretter lager vi skjelettet til vår verdsettelsesapplikasjon, og, enda viktigere, vi demonstrerer hvordan konfigurasjonsdokumentet leses i løpetid. Klassen av interesse kalles Eksempel 1. java og kan bli funnet i src-mappen til det nedlastbare arkivet som er tilknyttet denne opplæringen. Klassedefinisjonen er som følger:

importer org.obix.configuration.Configuration; importer org.obix.configuration.ConfigurationAdapter; importer org.obix.configuration.ConfigurationAdapterFactory;

public class Eksempel1 {public static void main (String [] args) {ConfigurationAdapterFactory adapterFactory = ConfigurationAdapterFactory.newAdapterFactory ();

ConfigurationAdapter adapter = adapterFactory.create (null);

adapter.adaptConfiguration (Configuration.getConfiguration (), "config / example1-config.xml"); printMarketDataInfo (); }

privat statisk tomrom printMarketDataInfo () {Configuration globalConfig = Configuration.getConfiguration ();

System.out.println ("URL for datatjeneste: \ t \ t" + globalConfig.getValue ("market.data.service.url"));

System.out.println ("Bruker-ID for datatjeneste: \ t \ t" + globalConfig.getValue ("market.data.service.uid"));

System.out.println ("Passord for datatjeneste: \ t \ t" + globalConfig.getValue ("market.data.service.password"));

System.out.println ("Antall simuleringer: \ t \ t" + globalConfig.getValue ("number.of.valuation.simulations")); }}

For å kjøre dette og påfølgende eksempler må du laste ned Obix Framework-binærfiler til et sted som er tilgjengelig via klassestien din. Klassestien din må referere til Obix-biblioteket, obix-framework.jar, som du finner i lib-mappen i rammeverkets rotkatalog. Du trenger også følgende open source-biblioteker fra tredjeparter: dom.jar, jaxen-full.jar, sax.jar, saxpath.jar, og xercesImpl.jar, som du finner i lib / thirdParty-mappen i rammeverkets rotkatalog.

Å gjennomføre denne klassen skal gi følgende resultat:

URL for datatjeneste: //www.some-exchange.com/marketdata Data Service Bruker-ID: trading_app_dbo Datatjenestepassord: nopassword Simuleringsantall: 10000 

For å dissekere denne klassen starter vi med hovedmetoden. Den første linjen i denne metoden oppretter en forekomst av klassen org.obix.configuration.ConfigurationAdapterFactory, som er ansvarlig for å lage en konfigurasjonsadapter (en forekomst av klasse org.obix.configuration.ConfigurationAdapter). Adapteren er i sin tur ansvarlig for å faktisk lese et konfigurasjonsdokument fra et gitt sted (spesifisert som en filbane eller URL).

Følgende kodeutdrag leser innholdet i konfigurasjonsfilen vår i den globale / statiske konfigurasjonsinstansen ved å påkalle adaptermetoden adaptConfiguration (), og ved å sende en referanse til den globale forekomsten — som hentet fra samtalen Configuration.getConfiguration ()—Og stien til konfigurasjonsfilen config / example1-config.xml:

adapter.adaptConfiguration (Configuration.getConfiguration (), "config / example1-config.xml"); 

Merk at det er mulig å opprette en ny konfigurasjonsforekomst for å lagre konfigurasjonsdataene våre, i stedet for å bruke den statiske (globale) forekomsten, men for enkelhets skyld (og kortfattethet) bruker vi den statiske forekomsten for dette eksemplet.

Deretter undersøker vi metoden kort printMarketDataInfo (), som ganske enkelt leser konfigurasjonsoppføringene (dvs. XML-noder) og skriver ut verdiene (dvs. deres barneknuter). Legg merke til at verdien for hver oppføring oppnås ved å ringe metoden getValue (...) på tilhørende Konfigurasjon eksempel, ved å sende inn navnet / nøkkelen til oppføringen - som spesifisert for oppføringsnoden entryKey Egenskap. Merk deg at en oppføring kan ha flere verdier, noe som vil bli demonstrert senere i denne opplæringen.

Eksempel 2: Modularisering av konfigurasjonsdata

Søknader av denne typen vil vanligvis generere en rapport som viser resultatene av en forespørsel i et slags format. Vår hypotetiske anvendelse er ikke annerledes; den er i stand til å produsere verdsettelsesrapporter i en rekke formater. I tillegg er rapporteringsformatene som brukes i en gitt applikasjonskjøring diktert av en konfigurasjonsoppføring, og alle genererte rapporter sendes per e-post til en liste over mottakere i organisasjonen vår - der mottakerne også er spesifisert i konfigurasjonssettet.

Logisk sett er rapportering en tydelig funksjonalitet - sammenlignet med verdsettelse - selv om begge er relatert; så det ville være ganske rimelig å kapsle inn våre "rapporterings" konfigurasjonsdata. Dette gir ikke bare en renere separasjon av konfigurasjonsdataene, men gjør det også enklere for en nybegynner å visualisere avgrensningen av funksjonalitet i applikasjonen.

Vi innkapsler rapporteringskonfigurasjonen for dette eksemplet ved å opprette en konfigurasjonsmodul for rapportering, som er en underordnet del av rotmodulen vår. Vi endrer konfigurasjonsfilen fra det siste eksemplet ved å legge til noden vist nedenfor i listen over noder; den resulterende filen heter example2-config.xml og kan bli funnet i konfigurasjonsmappen i kildearkivet.

.................... .................... .......... ......... [email protected]

regneark tekstfil pdf

To ting skiller seg umiddelbart ut i denne konfigurasjonsfilen: den første er selvfølgelig vår moduldefinisjon , etterfulgt av modulens andre oppføringsnode . Vi begynner med moduldefinisjonen. Et Obix-konfigurasjonsdokument kan inneholde et hvilket som helst antall submoduler. Hvis du sperrer to elementer - ikke diskutert i denne opplæringen - støtter moduler det samme nodesettet som rotmodulen. Med andre ord, moduler har oppføringer og kan inneholde andre moduler; Derfor kan moduler effektivt brukes til å replikere en trestruktur.

Husk at i det siste eksemplet nevnte jeg at en konfigurasjonsoppføring kan ha flere verdier. Denne funksjonaliteten demonstreres av konfigurasjonsoppføringen for å holde rapporteringsformater, dvs. . Som du kan se, skiller dette seg fra andre oppføringer ved at den har tre verdier - spesifiserer de tre formatene der rapportene skal genereres.

Vi undersøker nå Java-koden for å lese oppføringene i vår rapporteringskonfigurasjonsmodul. Vi endrer Java-kilden for forrige eksempel ved å legge til følgende metode; den endrede kildefilen (klassen) får nytt navn Eksempel2.java, og finner du i src-mappen i arkivet som er tilknyttet denne opplæringen:

private static void printReportingConfig () {Configuration globalConfig = Configuration.getConfiguration ();

KonfigurasjonsrapporteringConig = globalConfig.getModule ("rapportering.parametre");

System.out.println ("Rapporter destinasjon: \ t \ t" + rapporteringConig.getValue ("rapporter.destinasjon.email"));

System.out.println ("Rapporteringsformater: \ t \ t" + rapporteringConig.getValues ​​("rapportformater")); }

Ved utførelse av denne klassen skal den produsere utdataene:

URL for datatjeneste: //www.some-exchange.com/marketdata Data Service Bruker-ID: trading_app_dbo Datatjenestepassord: nopassword Simuleringsantall: 10000

Rapporteringskonfigurasjonsparametere = Rapporter Destinasjon: [email protected] Rapporteringsformater: [regneark, tekstfil, pdf]

Når vi har undersøkt tilleggsmetoden i detalj, merker vi at den først får en referanse til det globale Konfigurasjon forekomst; deretter fortsetter den å anskaffe en referanse til konfigurasjonsmodulen som inneholder rapporteringskonfigurasjonsinformasjonen. Metoden oppnår disse oppgavene ved å påkalle metoden getModule (...) på foreldremodulen, og sender ID-en til modulen som skal mottas. Merk at denne syntaksen er generisk i den forstand at det å oppnå barnet til en hvilken som helst modul - selv om ikke rotmodulen - oppnås ved å påkalle getModule (...) på den gitte modulen.

$config[zx-auto] not found$config[zx-overlay] not found