Organizarea si gruparea pachetelor va poate ajuta la biblioteca dvs. sa fie mai usor de navigat, inteles si dezvoltat in timp.

Motiv pentru Sculpture, Hamilton Township, NJ

Java ne ofera pachete pentru a organiza clase si interfete conexe. Pachetele sunt extrem de utile, dar pot fi greu de valorificat eficient, deoarece fiecare pachet necesita un nume. Numirea lucrurilor este grea. Organizarea eficienta a lucrurilor intr-o ierarhie poate fi o provocare. Redenumirea si mutarea lucrurilor pot fi usoare in IDE-ul dvs., dar poate fi extrem de greu pentru clientii dvs. daca acestia trebuie sa redea manual redenumirea si sa mute refactorizarile in codul lor atunci cand va actualizeaza biblioteca.

Array

Poate parea o decizie banala de a pune totul in acelasi pachet si borcan atunci cand numarul de clase din biblioteca dvs. este mai mic de zece sau douazeci. Dar ce faci daca numarul de clase si interfete pe care le ai este mult mai mult decat atat? Daca aveti un numar mare de interfete si clase in biblioteca dvs., luati in considerare impartirea API-urilor si a claselor de implementare in pachete separate. De asemenea, daca doriti sa permiteti altor persoane sa va implementeze API-ul fara a fi nevoie sa includeti implementarile implicite, este util sa aveti un jar API separat.

Voi explica strategia de blocare a informatiilor pe care o folosim in colectiile Eclipse. Ierarhia noastra de pachete a evoluat semnificativ in timp, pe masura ce biblioteca a crescut. Deciziile de proiectare a pachetelor pe care le-am luat in mod constient inainte de a deschide colectiile Eclipse sursa ne-au facut posibil sa continuam sa dezvoltam biblioteca pe o perioada extinsa de timp.

Mintea umana isi poate aminti sapte plus sau minus doua lucruri la un moment dat.

Array

Acesta este motivul pentru care numerele de telefon au sapte cifre in Statele Unite. Oamenii pot gestiona mai eficient un set mare de informatii daca conceptele conexe sunt grupate impreuna in bucati de sapte plus sau minus doua lucruri. Uneori, lipirea stricta a acestui numar nu este posibila fara a exploda inutil numarul de pachete. De exemplu, organizarea fiecarui container de tip primitiv in propriul pachet ar fi, probabil, exagerata. Sortarea alfabetica a interfetei si a numelor de clase ne ofera o grupare vizuala intr-un pachet, astfel incat sa putem focaliza sau ignora mai rapid lucrurile pe baza prefixului lor.

Recomandare: Nu ma face sa derulez. Daca ma faceti sa derulez pentru a vedea toate clasele dintr-un pachet, atunci sunt prea multe.

  • Separati interfetele de implementare
  • Organizati pachetele de nivel superior dupa tipul de container
  • Organizati specializari de tip container cu tipuri de containere (de exemplu, sortate)
  • Organizati pachetele impl in functie de tipul interfetei (de exemplu, mutabil, imuabil)
  • Organizati tipurile primitive intr-un pachet separat

Preocupari la nivel inalt in colectiile Eclipse

Eclipse Collections are pachete separate si fisiere jar pentru interfete si clase de implementare. Acest lucru permite clientilor din biblioteca noastra sa inteleaga atat API-ul, cat si implementarea separat si sa le grupeze pe amandoua intr-un model mental similar dupa tipul de container.

Array

Eclipse Collections pachete org.eclipse.collections.api / impl

Eclipse Collections are module separate si nume de pachete pentru API si implementare. Pachetele API sunt in stanga, iar pachetele impl sunt in dreapta.

Eclipse Collections API si structuri de pachete de implementare

Eclipse Collections este o biblioteca mare, dar are un numar usor de concepte de nivel inalt grupate in pachete. Am organizat colectiile Eclipse astfel incat sa fie usor sa explorati tipurile de containere acceptate si sa va aruncati in detalii suplimentare, dupa caz.

Separarea interfetelor API de clasele de implementare a dus la beneficii suplimentare pentru biblioteca.

Clasele de implementare depind de interfetele API, dar nu invers. Cand interfetele API si clasele de implementare se afla in aceleasi pachete si se afla in acelasi jar, devine posibila introducerea unor dependente nedorite intre interfete si implementarea lor, care sunt greu de eliminat ulterior.

Pachetul JDK java.util

Interfetele si clasele continute in pachetul JDK java.util sunt prezentate mai jos.

Pachetul JDK java.util

Aceasta este o multime de clase si interfete pentru un singur pachet. Puteti diferentia interfetele si clasele dupa pictogramele lor, dar nu exista nicio modalitate de a intelege relatia dintre oricare dintre aceste clase de utilitati. Exista colectii, exceptii, formate, comparatoare, statistici, optionale, calendare, data, incarcator de servicii, lucruri legate de siruri, fusuri orare, clase de temporizatoare si alte utilitare, toate in acelasi pachet. Acesta este un pachet de interfete si clase sortate alfabetic dupa nume.

Pachetul java.util a devenit o parcare pentru lucruri clasificate vag ca „utilitate”. In mod ideal, ar trebui sa existe un pachet java.util.collection care contine doar clase si interfete care se ocupa de colectii. Datorita garantiei de compatibilitate cu versiunea anterioara a Java, singura cale rezonabila este introducerea de noi concepte in pachete noi, cum ar fi java.util.stream.

Pachetul Google Guava com.google.collect

Acestea sunt clasele si interfetele din pachetul com.google.collect de la Google Guava.

Pachetul Guava com.google.collect

Exista o multime de clase in acest pachet, dar toate sunt legate de colectii. Exista o grupare vizuala care se intampla datorita prefixului unor clase (de exemplu, filtrat, redirectionat, imuabil, regulat), dar este greu sa te concentrezi pe interfete fata de implementari pentru a intelege focalizarea generala si sfera bibliotecii.

Pachetul Apache org.apache.commons.collections4

Ultima biblioteca cu care voi compara aici este Apache Commons Collections, care este cea mai veche biblioteca de colectii Java terta parte.

Apache Commons Collections isi organizeaza implementarile dupa tipul de container, dar nu imparte interfetele si implementarile API in pachete separate.

Eclipse Collections este singura biblioteca de colectii Java din cele patru care si-a impartit API-ul si implementarile in pachete separate si fisiere jar separate.

Cand am decis sa adaugam tipuri si implementari de containere imuabile la Colectiile Eclipse, am stiut ca trebuie sa reorganizam biblioteca. Stiam ca nu va functiona bine daca am avea peste o suta de clase si interfete intr-un singur pachet. De asemenea, am decis ca ar fi bine sa separam interfetele noastre API intr-o structura de pachete separata. Apoi am ales „tipul containerului” ca grupare de pachete de nivel inalt.

Acesta este setul de containere de nivel inalt pe care trebuia sa ne dam seama cum sa le organizam in pachetele noastre de implementare si API.

Tipuri de containere Eclipse Collections

Fiecare tip de container avea apoi un set de preocupari suplimentare care trebuiau abordate in ierarhia pachetelor.

Asa arata cand extindeti pachetul de tip List container atat in ​​interfata, cat si in pachetele de implementare.

Interfetele din pachetul API conduc ierarhia pachetelor in pachetul de implementare

Eclipse Collections a sortat versiuni de Bag, Set si Map. Fiecare dintre aceste tipuri de containere are un subpachet denumit sortat . Aceasta strategie poate fi utilizata cu alte specializari de tip container, dupa cum este necesar.

Bag, Set si Map au toate versiuni sortate

Exista trei tipuri de interfete principale pentru toate tipurile de containere din colectiile Eclipse. Acestea sunt modificabile, imuabile si iterabile (alias citibil).

Simetrie intre tipurile de containere – Iterabil, mutabil, imuabil

Pentru tipul de container Lista, exista clase de punere in aplicare pentru tipurile de interfata de Schimbabil , imuabile si FixedSize. FixedSize este in prezent limitat la tipurile de containere List, Set si Map si este pentru a obtine eficienta memoriei pentru tipurile de containere mutabile care sunt ca matrici. Adica pot fi modificate, dar nu pot fi cultivate.

Implementari ale listei de obiecte organizate de FixedSize, Immutable si Mutable

Containerele primitive sunt organizate sub pachetele de tip container din borcanul API si sub pachetele mutabile si imuabile din borcanul de implementare.

Pachete API (stanga) si pachete Impl (dreapta) numai pentru tipul de container List si implementari mutabile

Am fi putut imparti colectiile primitive in pachete separate dupa tipul primitiv. Acest lucru ar fi dus la opt pachete pentru fiecare dintre pachetele primitive. Am decis sa nu facem acest lucru, deoarece sortarea alfabetica a numelor de clase cu prefixele lor a asigurat o grupare vizuala suficienta in pachetele primitive.

In cele din urma, trebuie sa luati o decizie atunci cand aveti suficiente pachete in ierarhia dvs. si este posibil sa nu functioneze perfect cu numarul magic sapte in minte.

Implementarile de colectie mutabile au cateva preocupari suplimentare de rezolvat – sincronizate, nemodificabile si MultiReader. Am considerat ca aceste concepte nu justifica propriile pachete. Nu exista un nume bun pe care sa-l putem gasi pentru a le grupa intr-un pachet. Un nume precum „mutable.other” nu ar fi teribil de util. Deci ne-am oprit la list.mutable si list.mutable.primitive pe pachetele de implementare.

Am reorganizat pachetele din colectiile Eclipse atunci cand am adaugat colectii imuabile la biblioteca (# 10), chiar inainte de a deschide biblioteca sub forma de colectii GS. Colectiile imuabile au crescut semnificativ numarul de concepte pe care trebuia sa le gestionam in pachetele noastre.

Restructurarea pachetelor s-a produs in jurul articolului 10

Urmatorul punct in care am introdus ceva mare ecosistemului care trebuia sa se incadreze in ierarhia noastra de pachete a fost cu colectiile primitive (# 13). Am reusit sa realizam acest lucru fara o restructurare completa prin inserarea pachetelor primitive in ierarhia existenta sub omologii lor obiect.

Pachetele parinte s-au schimbat din nou de la com.gs.collections la org.eclipse.collections cand biblioteca a fost migrata catre Eclipse Foundation si a devenit Eclipse Collections. Deschidem o biblioteca separata pentru a ajuta utilizatorii colectiilor GS sa converteasca in colectiile Eclipse – https://github.com/eclipse/gsc-ec-converter

Pachetele Java sunt o solutie pentru a ajuta la problema spatierii numelor si a gruparii logice. Cand evoluati si dezvoltati o biblioteca, ar trebui sa fiti pregatiti sa va optimizati structura pachetelor pentru a permite o mai buna grupare logica si fragmentarea informatiilor.

Sunt conducator de proiect si responsabil pentru proiectul Eclipse Collections OSS de la Fundatia Eclipse . Colectiile Eclipse sunt deschise pentru contributii . Daca iti place biblioteca, ne poti anunta cu o vedeta pe GitHub.