Vra

In die eerste plek, ek weet hoe om 'n Java program te bou. Maar ek het nog altyd verbaas oor waar om my klasse sit nie. Daar is voorstanders vir die organisering van die pakkette in 'n streng domein georiënteerde mode, ander te skei deur toegeroep.

Ek myself het nog altyd probleme met

  • benaming,
  • plaas

So,

  1. Waar kry jy jou domein spesifieke konstantes (en wat is die beste naam vir so 'n klas)?
  2. Waar kry jy klasse vir dinge wat beide infrastruktuur en domein spesifieke (byvoorbeeld ek het 'n FileStorageStrategy klas, wat die lêers of in die databasis, of alternatiewelik in die databasis gestoor word)?
  3. Waar om uitsonderings te sit?
  4. Is daar enige standaarde waaraan ek kan verwys?
Was dit nuttig?

Oplossing

Ek het regtig kom graag Maven se Standard Gids uitleg .

Een van die belangrikste idees vir my is om twee bron wortels het - een vir die produksie kode en een vir toets kode soos so:

MyProject/src/main/java/com/acme/Widget.java
MyProject/src/test/java/com/acme/WidgetTest.java

(hier, beide src / hoof / java en src / toets / java is bron wortels).

Voordele:

  • Jou toetse het pakket (of "default") vlak toegang tot jou klasse onder toets.
  • Jy kan maklik verpak net jou produksie bronne in 'n JAR deur die val src / toets / java as 'n bron wortel.

Een reël oor klas plasing en pakkette:

In die algemeen, sal goed gestruktureerde projekte gratis omsendbrief afhanklikhede . Leer wanneer hulle slegte (en wanneer hulle nie ), en oorweeg om 'n instrument soos JDepend of SonarJ wat sal help om hulle te skakel.

Ander wenke

Ek is 'n groot fan van georganiseerde bronne, so ek skep altyd die volgende gids struktuur:

/src - for your packages & classes
/test - for unit tests
/docs - for documentation, generated and manually edited
/lib - 3rd party libraries
/etc - unrelated stuff
/bin (or /classes) - compiled classes, output of your compile
/dist - for distribution packages, hopefully auto generated by a build system

In / src Ek gebruik die verstek Java patrone: name pakket begin met jou domein (org.yourdomain.yourprojectname) en klasname weerspieël die OOP aspek wat jy skep met die klas (sien die ander antwoorde het). Algemene pakket name soos util , model , view , gebeure is nuttig, ook.

Ek is geneig om konstantes vir 'n spesifieke onderwerp te sit in 'n eie klas, soos SessionConstants of ServiceConstants in dieselfde pakket van die domein klasse.

Waar ek werk, is ons met behulp van Maven 2 en ons het 'n aardige argetipe vir ons projekte. Die doel was om 'n goeie skeiding van kommer te verkry, dus 'n projek struktuur met behulp van verskeie modules (een vir elke aansoek 'n laag ') gedefinieer ons:   - gemeen: algemene kode wat gebruik word deur die ander lae (bv i18n)   - entiteite: die domein entiteite   - repositories: hierdie module bevat die daos koppelvlakke en implementering   - dienste-intf: koppelvlakke vir die dienste (byvoorbeeld, UserService, ...)   - dienste-Tenuitvoerlegging: implementering van die dienste (byvoorbeeld, UserServiceImpl)   - web: alles met betrekking tot die web-inhoud (bv css, JSP, JSF bladsye, ...)   - WS: web dienste

Elke module het sy eie afhanklikhede (bv repositories kan JPA het) en 'n paar is projek wye (dus hulle behoort in die algemeen module). Afhanklikhede tussen die verskillende projek modules duidelik aparte dinge (bv die web laag hang af van die diens laag, maar weet nie oor die bewaarplek laag).

Elke module het sy eie base pakket, byvoorbeeld indien die aansoek pakket is "com.foo.bar", dan het ons:

com.foo.bar.common
com.foo.bar.entities
com.foo.bar.repositories
com.foo.bar.services
com.foo.bar.services.impl
...

Elke module respekteer die standaard Maven projek struktuur:

   src\
   ..main\java
     ...\resources
   ..test\java
     ...\resources

Eenheid toetse vir 'n gegewe laag vind maklik hul plek onder \ src \ toets ... Alles wat domein spesifieke het sy plek in die entiteite module. Nou iets soos 'n FileStorageStrategy moet gaan in die repositories module, aangesien ons nie nodig het om te weet presies wat die implementering is. In die dienste laag, ons weet net die bewaarplek koppelvlak, ons gee nie om wat die spesifieke implementering is (skeiding van kommer).

Daar is verskeie voordele aan hierdie benadering:

  • duidelike skeiding van kommer
  • elke module is packageable as 'n pot (of 'n oorlog in die geval van die web module) en dus maak voorsiening vir makliker kode hergebruik (bv, kan ons die module in die Maven repository installeer en hergebruik dit in 'n ander projek)
  • maksimum onafhanklikheid van elke deel van die projek

Ek weet dit nie al jou vrae te beantwoord, maar ek dink dit kan jy op die regte pad te sit en nuttig vir ander kan wees.

Klas name moet altyd beskrywende en selfverduidelikend wees. As jy meer domeine van verantwoordelikheid vir jou klasse dan moet hulle waarskynlik refactored.

Net so vir jou pakkette. Hulle moet gegroepeer deur domein van verantwoordelikheid. Elke domein het sy eie uitsonderings.

In die algemeen sweet nie doen nie, totdat jy 'n punt waar dit steeds oorweldigend en opgeblase. Dan gaan sit en doen nie kode, net refactor die klasse uit, die opstel van gereeld om seker te maak alles werk. voortgaan dan as jy voor het.

Gebruik pakkette om groep verwante funksies saam.

Gewoonlik die top van jou pakket boom is jou domein naam omgekeer (com.domain.subdomain) om uniekheid te waarborg, en dan gewoonlik daar 'n pakket vir jou aansoek sal wees. onderverdeel dan dat deur verwante area, so jou FileStorageStrategy kan in gaan, sê, com.domain.subdomain.myapp.storage, en dan is daar dalk spesifiek te wees implementering / subklasse / wat ook al in com.domain.subdomain.myapp.storage.file en com.domain.subdomain.myapp.storage.database. Hierdie name kan redelik lank te kry, maar import hou hulle almal by die top van lêers en Ides kan help om te bestuur dat sowel.

Uitsonderings gaan gewoonlik in dieselfde pakket as die klasse wat hulle gooi, so as jy het, sê, FileStorageException dit sou gaan in dieselfde pakket as FileStorageStrategy. Net so 'n koppelvlak definieer konstantes sal wees in dieselfde pakket.

Daar is nie regtig 'n standaard as sodanig, net gesonde verstand gebruik, en as dit alles raak te morsig, refactor!

Een ding wat ek baie nuttig vir eenheid toetse was om 'n myApp / src het / en ook myApp / test_src / dopgehou. Op hierdie manier kan ek eenheid toetse te plaas in dieselfde pakkette as die klasse hulle te toets, en nog kan ek maklik die toets gevalle uitsluit wanneer ek my produksie installasie te berei.

Kort antwoord: trek jou stelsel argitektuur in terme van modules, getrek side-by-kant, met elke module vertikaal gesny in lae (bv oog, model, volharding). Gebruik dan 'n struktuur soos com.mycompany.myapp.somemodule.somelayer , bv com.mycompany.myapp.client.view of com.mycompany.myapp.server.model .

Die gebruik van die boonste vlak van pakkette vir aansoek modules , in die outydse rekenaar-wetenskap sin van modulêre programmering , behoort voor die hand liggend te wees. Maar op die meeste van die projekte wat ek gewerk het op ons uiteindelik vergeet om dit te doen, en eindig met 'n gemors van pakkette sonder dat top-vlak struktuur. Hierdie anti-patroon toon self gewoonlik as 'n pakket vir iets soos 'luisteraars' of 'aksies' dat groepe anders onverwante klasse bloot omdat hulle toevallig dieselfde koppelvlak implementeer.

In 'n module, of in 'n klein program, gebruik pakkette vir die aansoek lae. Waarskynlik pakkette sluit in dinge soos die volgende, afhangende van die argitektuur:

  • com.mycompany.myapp.view
  • com.mycompany.myapp.model
  • com.mycompany.myapp.services
  • com.mycompany.myapp.rules
  • com.mycompany.myapp.persistence (of 'dao' vir toegang data laag)
  • com.mycompany.myapp.util (pasop vir hierdie gebruik asof dit 'misc')

Binne elk van hierdie lae, is dit natuurlik om groepklasse deur die tipe of daar is 'n baie. 'N Algemene anti-patroon hier is om onnodig te stel te veel pakkette en vlakke van sub-pakket sodat daar slegs 'n paar klasse in elke pakket.

Ek dink hou dit eenvoudig en dink dit nie verby nie. Moenie meer as abstrakte en laag te veel. hou net dit netjies, en as dit groei, refactoring dit is triviale. Een van die beste eienskappe van Ides is refactoring, so hoekom nie daarvan gebruik te maak en te red wat jy breinkrag vir die oplossing van probleme wat verband hou met jou app, eerder dan meta kwessies soos code organisasie.

Een ding wat ek gedoen het in die verlede - as ek die uitbreiding van 'n klas wat ek sal probeer en volg hul konvensies. Byvoorbeeld, wanneer daar gewerk word met die lente Framework, ek sal my MVC Controller klasse het in 'n pakket genaamd com.mydomain.myapp.web.servlet.mvc As ek nie iets wat strek Ek gaan net met wat eenvoudigste. com.mydomain.domain vir Domain voorwerpe (alhoewel as jy 'n ton van domein hierdie pakket kan kry 'n bietjie lomp voorwerpe). Vir domein spesifieke konstantes, ek eintlik sit hulle as openbare konstantes in die meeste verwante klas. Byvoorbeeld, as ek 'n "lid" klas en het 'n maksimum lid naam lengte konstant, sit ek dit in die lid klas. Sommige winkels maak 'n aparte Konstantes klas maar nie die waarde in uitslepen onverwante nommers en stringe in 'n enkele klas sien. Ek het gesien 'n paar ander winkels probeer om hierdie probleem op te los deur die skep van AFSONDERLIKE Konstantes klasse, maar dat net lyk soos 'n vermorsing van tyd en die resultaat is te verwarrend. Die gebruik van hierdie opstel, sal 'n groot projek met verskeie ontwikkelaars duplisering konstantes oor die hele plek.

Ek hou van my klasse af te breek in pakkette wat verband hou met mekaar.

Byvoorbeeld: Model Vir databasis verwante oproepe

Beeld Klasse wat te doen het met wat jy sien

Control Core funksie klasse

Util Enige misc. klasse wat gebruik word (tipies statiese funksies)

ens.

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top