Cum ar trebui să structurez o aplicație Java, unde să-mi pun cursurile?

În primul rând, știu cum să construiesc o aplicație Java. Dar am fost întotdeauna nedumerit de unde să-mi pun cursurile. Există susținători pentru organizarea pachetelor într-un mod strict orientat pe domenii, alții separați de niveluri.

Eu însumi am avut întotdeauna probleme cu

  • denumirea,
  • plasarea

Asa de,

  1. Unde plasați constantele specifice domeniului (și care este cel mai bun nume pentru o astfel de clasă)?
  2. Unde plasați clase pentru lucruri care sunt atât de infrastructură, cât și de domeniu specific (de exemplu, am o clasă FileStorageStrategy, care stochează fișierele fie în baza de date, fie în baza de date)?
  3. Unde să plasezi excepții?
  4. Există standarde la care să mă refer?
0
fr hi bn
Nu este evident un răspuns definitiv, dar după ce am folosit Maven2 pentru o vreme, am venit să mă apreciez structura dată și, prin urmare, eu declar răspunsul maven ca unul. (Asta nu înseamnă că celelalte sunt greșite sau altceva) Tocmai mi-am dat seama cât de ușor este să nu trebuie să te gândești la etapele inițiale ale construirii tale, să scapi de sursele și resursele tale în acele directoare și să compilezi fără a crea fișiere ant și lucruri.
adăugat autor Mauli, sursa

10 răspunsuri

Îmi place să-mi rup clasele în pachete care sunt legate între ele.

De exemplu: Model pentru apelurile bazate pe baze de date

View Classes that deal with what you see

Control Core functionality classes

Util Any misc. classes that are used (typically static functions)

etc.

0
adăugat

Numele de clase ar trebui să fie întotdeauna descriptive și explicite. Dacă aveți mai multe domenii de responsabilitate pentru clasele dvs., atunci ar trebui probabil să fie refactate.

La fel și pentru pachetele tale. Acestea ar trebui grupate pe domenii de responsabilitate. Fiecare domeniu are propriile excepții.

În general, nu transpirați până nu ajungeți într-un punct în care devine copleșitor și umflat. Apoi, stai jos și nu codifică, doar refactor clasele afară, compilarea regulat pentru a vă asigura că totul funcționează. Apoi continuați așa cum ați făcut înainte.

0
adăugat

Utilizați pachetele pentru a grupa împreună funcționalitatea.

De obicei, partea de sus a arborelui dvs. de pachete este numele dvs. de domeniu inversat ( com.domain.subdomain ) pentru a garanta unicitatea și, de obicei, va exista un pachet pentru aplicația dvs. Apoi, subdivizați-l prin zona asociată, astfel încât FileStorageStrategy să poată intra, să zicem, com.domain.subdomain.myapp.storage , și apoi să existe implementări / subclase / indiferent în com.domain.subdomain.myapp.storage.file și com.domain.subdomain.myapp.storage.database . Aceste nume pot deveni destul de lungi, dar import îi păstrează pe toate în partea de sus a fișierelor, iar IDE-urile pot ajuta și la gestionarea acestora.

Excepțiile merg, de obicei, în același pachet ca și clasele care le aruncă, deci, dacă ai fi spus FileStorageException , ar merge în același pachet ca FileStorageStrategy . De asemenea, o interfață care definește constantele ar fi în același pachet.

Nu există nici un standard ca atare, folosiți doar bunul simț și dacă totul devine prea dezordonat, refactor!

0
adăugat

Cred că păstrați-o simplu și nu gândiți prea mult. Nu depășiți abstracția și nu prea mult. Doar păstrați-l îngrijit, iar pe măsură ce crește, refactorizarea este banală. Una dintre cele mai bune caracteristici ale IDE-urilor este refactorizarea, deci de ce să nu o folosiți și să vă salvați puterea creierului pentru rezolvarea problemelor legate de aplicația dvs., mai degrabă decât cu meta-probleme cum ar fi organizarea codurilor.

0
adăugat

Sunt un mare fan al surselor organizate, așa că întotdeauna creez următoarea structură de directoare:

/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 Folosesc modelele Java implicite: numele pachetelor incepand cu domeniul dvs. (org.yourdomain.yourprojectname) si numele de clasa care reflecta aspectul OOP pe care il creati cu clasa (vezi ceilalti comentatori). Sunt utile și nume comune de pachete, cum ar fi util , model , vizualizări , evenimente .

Am tendința de a pune constante pentru un anumit subiect într-o clasă proprie, cum ar fi SessionConstants sau ServiceConstants în același pachet din clasele de domenii.

0
adăugat

Un lucru pe care l-am făcut în trecut - dacă prelungesc o clasă, voi încerca să-i urmez convențiile. De exemplu, atunci când lucrăm cu Framework-ul de primăvară, voi avea clasele MVC Controller într-un pachet numit com.mydomain.myapp.web.servlet.mvc Dacă nu extind ceva, mă duc cu cel mai simplu lucru. com.mydomain.domain pentru obiecte de domeniu (deși dacă aveți o tona de obiecte de domeniu, acest pachet ar putea deveni un pic greu). Pentru constantele specifice domeniului, le-am pus de fapt ca constante publice în cea mai apropiată clasă. De exemplu, dacă am o clasă "Membru" și am o constantă maximă a numelui de membru, am pus-o în clasa Membru. Unele magazine fac o clasă de constante separate, dar nu văd valoarea în lumping numere independente și șiruri de caractere într-o singură clasă. Am văzut alte magazine care încearcă să rezolve această problemă prin crearea de clase SEPARATE Constants, dar asta pare a fi o pierdere de timp și rezultatul este prea confuz. Folosind această setare, un proiect mare cu mai mulți dezvoltatori va fi duplicarea constantelor peste tot.

0
adăugat

Un lucru pe care l-am găsit foarte util pentru testele de unitate a fost să aibă un director myApp / src / și, de asemenea, myApp / test_src /. În acest fel, pot efectua teste unitare în aceleași pachete ca și clasele pe care le testează și totuși pot să exclud cu ușurință cazurile de testare atunci când pregătesc instalația de producție.

0
adăugat

Răspuns scurt: trageți arhitectura sistemului în termeni de module, desenate una lângă alta, fiecare modul fiind tăiat vertical în straturi (de exemplu, vizualizare, model, persistență). Apoi, utilizați o structură ca com.mycompany.myapp.somemodule.somelayer , de ex. com.mycompany.myapp.client.view sau com.mycompany.myapp.server.model .

Folosind un nivel superior de pachete pentru modulele de aplicație , în sentimentul de tehnologie de modă veche de programarea modulară ar trebui să fie evidentă. Cu toate acestea, în majoritatea proiectelor la care am lucrat, ajungem să uităm să facem acest lucru și să ajungem la o mulțime de pachete fără această structură de nivel superior. Acest model anti-tipar se arată de obicei ca un pachet pentru ceva de genul "ascultători" sau "acțiuni" care grupează clase altminteri fără legătură, pur și simplu pentru că se întâmplă să implementeze aceeași interfață.

În cadrul unui modul sau într-o aplicație mică, utilizați pachete pentru straturile aplicației. Pachetele probabil includ lucruri cum ar fi următoarele, în funcție de arhitectură:

  • com.mycompany.myapp.view
  • com.mycompany.myapp.model
  • com.mycompany.myapp.services
  • com.mycompany.myapp.rules
  • com.mycompany.myapp.persistence (or 'dao' for data access layer)
  • com.mycompany.myapp.util (beware of this being used as if it were 'misc')

În cadrul fiecăruia dintre aceste straturi, este firesc să clasificați clasele după tip dacă există multe. Un model comun anti-model aici este de a introduce în mod inutil prea multe pachete și niveluri de sub-pachet, astfel încât să existe doar câteva clase în fiecare pachet.

0
adăugat

Am ajuns într-adevăr ca Maven Formatarea directorului standard .

Una dintre ideile cheie pentru mine este să am două rădăcini sursă - una pentru codul de producție și una pentru codul de testare, cum ar fi:

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

(aici, atât src / main / java și src / test / java sunt rădăcini sursă).

avantaje:

  • Testele dvs. au acces la nivel de pachet (sau "implicit") la clasele dvs. în curs de testare.
  • Puteți să împachetați cu ușurință numai sursele dvs. de producție într-un JAR, renunțând la src / test / java ca o sursă de sursă.

O regulă importantă privind plasarea în clasă și pachetele:

Generally speaking, well structured projects will be free of circular dependencies. Learn when they are bad (and when they are not), and consider a tool like JDepend or SonarJ that will help you eliminate them.

0
adăugat

Unde lucrez, folosim Maven 2 și avem un arhetip destul de frumos pentru proiectele noastre. Scopul a fost acela de a obține o bună separare a preocupărilor, astfel încât am definit o structură de proiect folosind mai multe module (câte unul pentru fiecare strat de aplicație):   - comun: codul comun utilizat de celelalte straturi (de exemplu, i18n)   - entități: entitățile domeniului   - depozite: acest modul conține interfețele și implementările daos   - services-intf: interfețe pentru servicii (de exemplu, UserService, ...)   - servicii-impl: implementări ale serviciilor (de exemplu, UserServiceImpl)   - web: tot ce privește conținutul web (de exemplu, css, jsps, pagini jsf, ...)   - ws: servicii web

Fiecare modul are propriile dependențe (de exemplu, arhivele ar putea avea jpa) și unele sunt proiectate la nivel lat (astfel, aparțin în modulul comun). Dependențele dintre diferitele module de proiect clar separă lucrurile (de exemplu, stratul web depinde de stratul de serviciu, dar nu știe despre stratul de depozitare).

Fiecare modul are propriul pachet de bază, de exemplu dacă pachetul de aplicații este "com.foo.bar", atunci avem:

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

Fiecare modul respectă structura de proiect standard maven:

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

Testele unităților pentru un anumit strat își găsesc cu ușurință locul sub \ src \ test ... Tot ceea ce este domeniul specific are loc în modulul entități. Acum ceva asemănător cu FileStorageStrategy ar trebui să intre în modulul repositories, deoarece nu trebuie să știm exact ce este implementarea. În stratul de servicii, cunoaștem doar interfața repozitorială, nu ne pasă ce este implementarea specifică (separarea preocupărilor).

Există mai multe avantaje pentru această abordare:

  • separarea clară a preocupărilor
  • fiecare modul poate fi ambalat ca un borcan (sau un război în cazul modulului web) și astfel permite o reutilizare mai ușoară a codului (de exemplu, am putea instala modulul în depozitul maven și reutilizați-l într-un alt proiect) li>
  • independența maximă a fiecărei părți a proiectului

Știu că acest lucru nu răspunde la toate întrebările dvs., dar cred că acest lucru v-ar putea pune pe calea cea bună și s-ar putea dovedi util altora.

0
adăugat