Programavimas

Sukurkite paprastą į paslaugas orientuotą J2EE programų sistemą

Šiandien kūrėjus užplūsta atvirojo kodo sistemos, kurios padeda programuoti J2EE: „Struts“, „Spring“, „Hibernate“, „Tiles“, „Avalon“, „WebWorks“, „Tapestry“ ar „Oracle ADF“. Daugelis kūrėjų mano, kad šios sistemos nėra panacėja jų problemoms spręsti. Tai, kad jie yra atviro kodo, dar nereiškia, kad juos lengva pakeisti ir tobulinti. Kai pagrindinėje srityje trūksta pagrindo, jis nukreipiamas tik į konkretų domeną arba yra tiesiog išpūstas ir per brangus, gali tekti ant jo sukurti savo sistemą. Sukurti tokią sistemą kaip „Struts“ yra nereikšminga užduotis. Tačiau nebūtina sukurti palaipsniui pagrindą, kuris valdo „Struts“ ir kitas sistemas.

Šiame straipsnyje aš jums parodysiu, kaip tobulėti X18p („Xiangnong 18 Palm“, pavadintas legendiniu galingu kung fu kovotoju), pavyzdinė sistema, kurioje sprendžiami du įprasti klausimai, kurių nepaiso dauguma J2EE sistemų: griežtas susiejimas ir išpūstas DAO (duomenų prieigos objektas) kodas. Kaip pamatysite vėliau, „X18p“ įvairiuose sluoksniuose naudoja „Struts“, „Spring“, „Axis“, „Hibernate“ ir kitas sistemas. Tikimės, kad atlikdami panašius veiksmus, galite lengvai sukurti savo sistemą ir auginti ją nuo projekto iki projekto.

Kurdamas šią struktūrą, naudoju IBM racionalaus vieningo proceso (RUP) koncepcijas. Aš atlieku šiuos veiksmus:

  1. Iš pradžių nustatykite paprastus tikslus
  2. Išanalizuokite esamą J2EE programos architektūrą ir nustatykite problemas
  3. Palyginkite alternatyvias sistemas ir pasirinkite tą, kurią paprasčiausia kurti
  4. Kurkite kodą palaipsniui ir dažnai pertvarkykite
  5. Susitikite su „Framework“ galutiniu vartotoju ir reguliariai rinkite atsiliepimus
  6. Testas, testas, testas

1 žingsnis. Nustatykite paprastus tikslus

Gunda išsikelti ambicingus tikslus ir įgyvendinti pažangiausią sistemą, kuri išspręstų visas problemas. Jei turite pakankamai išteklių, tai nėra bloga idėja. Paprastai išankstinio projekto pagrindo kūrimas laikomas pridėtiniu, kuris nesuteikia apčiuopiamos verslo vertės. Pradėdami nuo mažesnio, galite sumažinti nenumatytą riziką, mėgautis trumpesniu vystymosi laiku, sumažinti mokymosi kreivę ir gauti projekto suinteresuotųjų šalių įpirką. „X18p“ nustatiau tik du tikslus, remdamasis ankstesniais susitikimais su J2EE kodu:

  1. Sumažinkite J2EE Veiksmas kodo sujungimas
  2. Sumažinkite kodo kartojimą J2EE DAO sluoksnyje

Apskritai noriu pateikti geresnės kokybės kodą ir sumažinti bendras kūrimo ir priežiūros išlaidas padidindamas savo produktyvumą. Atlikdami du tikslus, atliksime 2–6 žingsnių pakartojimus.

Sumažinkite kodų sujungimą

2 žingsnis. Išanalizuokite ankstesnę J2EE programos architektūrą

Jei yra J2EE taikymo sistema, pirmiausia turime pamatyti, kaip ją galima patobulinti. Akivaizdu, kad pradėti nuo nulio nėra prasmės. „X18p“ pažiūrėkime į tipinį „J2EE Struts“ programos pavyzdį, parodytą 1 paveiksle.

Veiksmas skambučių „XXXManager“ir „XXXManager“ skambučių XXXDAOs. Tipiško „J2EE“ dizaino, kuriame yra atramos, turime šiuos elementus:

  • „HttpServlet“ arba Struts Veiksmas sluoksnis, kuris tvarko „HttpRequest“ ir HttpResponse
  • Verslo logikos sluoksnis
  • Duomenų prieigos sluoksnis
  • Domeno sluoksnis, susietas su domeno objektais

Kas blogai minėtoje architektūroje? Atsakymas: tvirtas sukabinimas. Architektūra veikia puikiai, jei logika yra Veiksmas yra paprasta. Bet ką daryti, jei reikia pasiekti daugelį EJB („Enterprise JavaBeans“) komponentų? Ką daryti, jei jums reikia prieigos prie interneto paslaugų iš įvairių šaltinių? Ką daryti, jei jums reikia prisijungti prie JMX („Java“ valdymo plėtiniai)? Ar „Struts“ turi įrankį, kuris padeda jums ieškoti tų išteklių iš struts-config.xml failas? Atsakymas yra neigiamas. Struts yra skirta tik žiniatinklio pakopos sistemai. Galima koduoti Veiksmass kaip įvairūs klientai ir paskambina į galinę dalį naudodami „Service Locator“ modelį. Tačiau tai padarius bus įmaišyti du skirtingi kodų tipai Veiksmas's vykdyti () metodas.

Pirmasis kodo tipas yra susijęs su žiniatinklio pakopa „HttpRequest“/HttpResponse. Pavyzdžiui, kodas gauna HTTP formos duomenis iš „ActionForm“ arba „HttpRequest“. Jūs taip pat turite kodą, kuris nustato HTTP užklausos ar HTTP seanso duomenis ir persiunčia juos į JSP (JavaServer Pages) puslapį, kad jie būtų rodomi.

Tačiau antrasis kodo tipas yra susijęs su verslo pakopa. Į Veiksmas, taip pat pasikviečiate backend kodą, pvz EJBObject, JMS („Java Message Service“) temą ar net JDBC („Java Database Connectivity“) duomenų šaltinius ir gaukite rezultatų duomenis iš JDBC duomenų šaltinių. Galite naudoti „Service Locator“ modelį Veiksmas kad padėtų jums atlikti paiešką. Tai taip pat įmanoma Veiksmas nurodyti tik vietinį POJO (paprastą seną „Java“ objektą) xxxValdytojas. Nepaisant to, užpakalinis objektas arba xxxValdytojasmetodo lygio parašai yra veikiami Veiksmas.

Štai taip Veiksmas veikia, tiesa? Gamtos pobūdis Veiksmas yra servletas, kuriam turėtų rūpėti, kaip perimti duomenis iš HTML ir nustatyti duomenis į HTML su HTTP užklausa / sesija. Jis taip pat sąsaja su verslo logikos sluoksniu, kad gautų ar atnaujintų duomenis iš to sluoksnio, bet kokia forma ar protokolu, Veiksmas galėtų rūpintis mažiau.

Kaip galite įsivaizduoti, kai „Struts“ programa auga, galite rasti glaudžių nuorodų tarp jų Veiksmass (interneto pakopa) ir verslo vadybininkai (verslo pakopa) (žr. raudonas linijas ir rodykles 1 paveiksle).

Norėdami išspręsti šią problemą, galime atsižvelgti į atviras rinkos sistemas - tegul jos įkvepia mūsų pačių mąstymą, kol darome įtaką. „Spring Framework“ pasirodo mano radaro ekrane.

3 žingsnis. Palyginkite alternatyvias sistemas

„Spring Framework“ esmė yra vadinama sąvoka Pupelių fabrikas, kuris yra geras paieškos fabriko diegimas. Nuo „Service Locator“ modelio jis skiriasi tuo, kad jame anksčiau buvo vadinama valdymo inversija (IoC) Injekcijos priklausomybė. Idėja yra gauti objektą paskambinus savo „ApplicationContext“'s „getBean“ () metodas. Šis metodas ieško pavasario konfigūracijos failo objekto apibrėžimams, sukuria objektą ir grąžina a java.lang.Object objektas. „getBean“ () yra naudinga objektų paieškai. Atrodo, kad tik viena objekto nuoroda, „ApplicationContext“, turi būti nuoroda į Veiksmas. Tačiau taip nėra, jei jį naudojame tiesiogiai programoje Veiksmas, nes mes turime mesti „getBean“ ()grąžina objekto tipą atgal į EJB / JMX / JMS / žiniatinklio paslaugos klientą. Veiksmas vis tiek turi žinoti apie backend objektą metodo lygiu. Tvirtas sujungimas vis dar egzistuoja.

Jei norime išvengti objekto-metodo lygio nuorodos, ką dar galime naudoti? Natūralu, paslaugą, ateina i galva. Tarnyba yra visur esanti, bet neutrali sąvoka. Viskas gali būti paslauga, nebūtinai tik vadinamosios interneto paslaugos. Veiksmas taip pat gali traktuoti seanso pupelių be pilietybės metodą kaip paslaugą. JMS temos iškvietimą taip pat galima laikyti paslaugos vartojimu. Tai, kaip mes planuojame vartoti paslaugą, gali būti labai įprastas.

Suformulavus strategiją, pastebėjus pavojų ir sumažinus riziką pagal pirmiau pateiktą analizę ir palyginimą, galime paskatinti savo kūrybiškumą ir pridėti ploną paslaugų brokerio sluoksnį, kad pademonstruotume į paslaugas orientuotą koncepciją.

4 žingsnis. Sukurkite ir pertvarkykite

Norėdami įgyvendinti į paslaugą orientuotą koncepciją, galvodami apie kodą, turime atsižvelgti į šiuos dalykus:

  • Paslaugų tarpininko sluoksnis bus pridėtas tarp žiniatinklio ir verslo lygio.
  • Konceptualiai an Veiksmas iškviečia tik verslo paslaugų užklausą, kuri perduoda užklausą paslaugų maršrutizatoriui. Paslaugų kelvedis žino, kaip prijungti verslo paslaugų užklausas prie skirtingų paslaugų teikėjų valdiklių ar adapterių ieškant paslaugų susiejimo XML failo, X18p-config.xml.
  • Paslaugų teikėjo kontrolierius turi specialių žinių apie pagrindinių verslo paslaugų paiešką ir pasitelkimą. Čia verslo paslaugos gali būti bet kokios, pradedant POJO, LDAP (lengvas prieigos prie katalogų protokolas), EJB, JMX, COM ir žiniatinklio paslaugomis ir baigiant COTS (komercinės lentynos) produktų API. X18p-config.xml turėtų pateikti pakankamai duomenų, kad paslaugų teikėjo valdiklis galėtų atlikti darbą.
  • Pasinaudokite „X18p“ vidinio objekto paieškos ir nuorodų spyruokle.
  • Kurkite paslaugų teikėjų valdiklius palaipsniui. Kaip pamatysite, kuo daugiau įdiegtų paslaugų teikėjų valdiklių, tuo daugiau integravimo galios turi „X18p“.
  • Saugokite esamas žinias, tokias kaip „Struts“, bet atidarykite akis naujiems dalykams.

Dabar mes palyginame Veiksmas kodas prieš ir pritaikius į paslaugą orientuotą X18p sistemą:

„Struts Action“ be „X18p“

 viešas „ActionForward“ vykdymas („ActionMapping“ atvaizdavimas, „ActionForm“ forma, „HttpServletRequest“ užklausa, „HttpServletResponse“ atsakymas) išmeta IOException, ServletException {... UserManager userManager = new UserManager (); Eilutė userIDRetured = userManager.addUser ("John Smith") ...} 

„Struts Action“ su „X18p“

viešas „ActionForward“ vykdymas („ActionMapping“ susiejimas, „ActionForm“ forma, „HttpServletRequest“ užklausa, „HttpServletResponse“ atsakymas) išmeta IOException, ServletException {... ServiceRequest bsr = this.getApplicationContext (). getBean ("businessServiceRequest"); bsr.setServiceName („Vartotojo paslaugos“); bsr.setOperation („addUser“); bsr.addRequestInput ("param1", "addUser"); Eilutė userIDRetured = (eilutė) bsr.service (); ...} 

„Spring“ palaiko verslo paslaugų užklausos ir kitų objektų paiešką, įskaitant POJO valdytojus, jei tokių yra.

2 paveiksle parodyta, kaip „Spring“ konfigūracijos failas, applicationContext.xml, palaiko „businessServiceRequest“ ir serviceRouter.

Į ServiceRequest.java, paslauga () metodas tiesiog paskambina „Spring“, norėdamas rasti paslaugų maršrutizatorių, ir perduoda save maršrutizatoriui:

 public Object service () {return ((ServiceRouter) this.serviceContext.getBean ("service router")). maršrutas (tai); } 

„X18p“ paslaugų maršrutizatorius nukreipia vartotojo paslaugas į verslo logikos sluoksnį naudodamas X18p-config.xmlpagalba. Svarbiausia yra tai, kad Veiksmas kodui nereikia žinoti, kur ir kaip įdiegiamos vartotojo paslaugos. Ji turi žinoti tik apie paslaugų vartojimo taisykles, pvz., Parametrų nustatymą teisinga tvarka ir tinkamo grąžinimo tipo liejimą.

3 paveiksle parodytas X18p-config.xml kuri teikia paslaugų susiejimo informaciją, kuri „ServiceRouter“ ieškos X18p.

Vartotojo paslaugoms paslaugos tipas yra POJO. „ServiceRouter“ sukuria POJO paslaugų teikėjo valdiklį paslaugų užklausai tvarkyti. Šis POJO springObjectId yra „userServiceManager“. POJO paslaugų teikėjo valdiklis naudoja „Spring“ ieškodamas šio POJO springObjectId. Nuo „userServiceManager“ nurodo klasės tipą X18p.framework.UserPOJOManager, „UserPOJOManager“ klasė yra konkrečios programos loginis kodas.

Nagrinėk „ServiceRouter.java“:

 public Object route („ServiceRequest serviceRequest“) išmeta išimtį {// / 1. Perskaitykite visą susiejimą iš XML failo arba gaukite iš gamyklos // Config config = xxxx; // 2. Gaukite paslaugos tipą iš config. String businessServiceType = Config.getBusinessServiceType (serviceRequest.getServiceName ()); // 3. Pasirinkite atitinkamą maršrutizatorių / tvarkytuvą / valdiklį, kad galėtumėte su juo susidoroti. if (businessServiceType.equalsIgnoreCase ("LOCAL-POJO")) {POJOController pojoController = (POJOController) Config.getBean ("POJOController"); pojoController.process (serviceRequest); } else if (businessServiceType.equalsIgnoreCase ("WebServices")) {String endpoint = Config.getWebServiceEndpoint (serviceRequest.getServiceName ()); „WebServicesController ws“ = („WebServicesController“) Config.getBean („WebServicesController“); ws.setEndpointUrl (galutinis taškas); ws.process (serviceRequest); } else if (businessServiceType.equalsIgnoreCase ("EJB")) {EJBController ejbController = (EJBController) Config.getBean ("EJBController"); ejbController.process (serviceRequest); } else {// TODO System.out.println („Nežinomi tipai, tik jūs patys nuspręsite, kaip tai tvarkyti sistemoje“); } // Viskas, tai yra jūsų sistema, galite pridėti bet kurį naują „ServiceProvider“ savo kitam projektui. return null; } 

Pirmiau nurodytą „if-else“ bloką galima pertvarkyti į „Command“ modelį. Konfig objektas pateikia „Spring“ ir „X18p XML“ konfigūracijos paiešką. Tol, kol bus galima gauti galiojančius duomenis, jūs patys pasirenkate, kaip įdiegti paieškos mechanizmą.

Darant prielaidą, kad POJO vadovas, TestPOJOBusinessManager, POJO paslaugų teikėjo valdiklis (POJOServiceController.java), tada ieško addUser () metodas iš TestPOJOBusinessManager ir kviečia jį apmąstyti (žr. kodą, kurį galite rasti iš išteklių).

Įvesdami tris klases („BusinessServiceRequester“, „ServiceRouter“ir „ServiceProviderController“) plius vienas XML konfigūracijos failas, mes turime į paslaugas orientuotą sistemą kaip koncepcijos įrodymą. Čia Veiksmas neturi žinių, kaip paslauga įgyvendinama. Jam rūpi tik įvestis ir išvestis.

Įvairių API ir programavimo modelių naudojimo, siekiant integruoti įvairius paslaugų teikėjus, sudėtingumas apsaugotas nuo „Struts“ kūrėjų, dirbančių žiniatinklio pakopoje. Jei X18p-config.xml yra sukurta iš anksto kaip paslaugų sutartis, „Struts“ ir „backend“ kūrėjai gali dirbti vienu metu pagal sutartį.

4 paveiksle parodyta nauja architektūros išvaizda.

1 lentelėje apibendrinau įprastus paslaugų teikėjų valdiklius ir įgyvendinimo strategijas. Galite lengvai pridėti daugiau.

1 lentelė. Įgyvendinimo strategijos bendriems paslaugų teikėjų valdikliams