Uvod u AutoFactory
1. Uvod
U ovom uputstvu dat ćemo kratki uvod u AutoFactory, od Googlea.
Ovo je generator koda na izvornoj razini koji pomaže u stvaranju tvornica.
2. Postavljanje Mavena
Prije nego što započnemo, dodajmo sljedeću ovisnost na pom.xml:
com.google.auto.factory auto-tvornica 1.0-beta5
Najnoviju verziju možete pronaći ovdje.
3. Brzi početak
Krenimo sada na brzinu što AutoFactory može napraviti i stvoriti jednostavan Telefon razred.
Dakle, kada označimo Telefon razred sa @AutoFactory i njegov parametar konstruktora sa @Provided, dobivamo:
@AutoFactory telefon javne klase {privatna završna kamera kamere; private final String otherParts; PhoneAssembler (@Provided Camera camera, String otherParts) {this.camera = camera; this.otherParts = drugiParts; } // ...}
Koristili smo samo dvije bilješke: @AutoFactory i @Provided. Kada trebamo tvornicu generiranu za naš razred, možemo je označiti s @AutoFactory, dok @Provided odnosi se na parametre konstruktora ove klase, a to znači da označeni parametar treba pružiti ubrizgavanjem Pružatelj usluga.
U gornjem isječku očekujemo Fotoaparat koju će osigurati bilo koji proizvođač fotoaparata i AutoFactory pomoći će u generiranju sljedećeg koda:
@Generated ("com.google.auto.factory.processor.AutoFactoryProcessor") javna završna klasa PhoneFactory {privatni konačni davatelj cameraProvider; @Inject PhoneAssemblerFactory (dobavljač cameraProvider) {this.cameraProvider = checkNotNull (cameraProvider, 1); } PhoneAssembler create (String otherParts) {return new PhoneAssembler (checkNotNull (cameraProvider.get (), 1), checkNotNull (otherParts, 2)); } // ...}
Sada imamo PhoneFactory generira automatski AutoFactory u vrijeme kompajliranja i možemo ga koristiti za stvaranje telefonskih instanci:
PhoneFactory phoneFactory = nova PhoneFactory (() -> nova kamera ("Nepoznato", "XXX")); Telefon jednostavanPhone = phoneFactory.create ("ostali dijelovi");
The @AutoFactory anotacija se može primijeniti i na konstruktore:
javna klasa ClassicPhone {privatna završnica String dialpad; privatno završno Zvono; private String otherParts; @AutoFactory javni ClassicPhone (@Provided String dialpad, @Provided String zvono) {this.dialpad = dialpad; this.ringer = zvono; } @AutoFactory javni ClassicPhone (niz ostalih dijelova) {this ("defaultDialPad", "defaultRinger"); this.otherParts = drugiParts; } // ...}
U gornjem isječku prijavili smo se @AutoFactory obojici konstruktora. AutoFactory jednostavno će za nas generirati dvije metode stvaranja:
@Generated (value = "com.google.auto.factory.processor.AutoFactoryProcessor") javna završna klasa ClassicPhoneFactory {privatni konačni davatelj java_lang_StringProvider; @Inject public ClassicPhoneFactory (Provider java_lang_StringProvider) {this.java_lang_StringProvider = checkNotNull (java_lang_StringProvider, 1); } javni ClassicPhone create () {return new ClassicPhone (checkNotNull (java_lang_StringProvider.get (), 1), checkNotNull (java_lang_StringProvider.get (), 2)); } javni ClassicPhone izradi (String otherParts) {vrati novi ClassicPhone (checkNotNull (otherParts, 1)); } // ...}
AutoFactory također podržava parametre označene s @Provided, ali samo za bilješke JSR-330.
Na primjer, ako želimo cameraProvider da bismo bili "Sony", možemo promijeniti Telefon razred do:
@AutoFactory telefon javne klase {PhoneAssembler (@Provided @Named ("Sony") Kamera kamere, niz ostalih dijelova) {this.camera = kamera; this.otherParts = drugiParts; } // ...}
AutoFactory će zadržati @Name@Kvalifikator kako bismo ga mogli iskoristiti, na primjer, kada koristimo okvire ubrizgavanja ovisnosti:
@Generated ("com.google.auto.factory.processor.AutoFactoryProcessor") javna završna klasa PhoneFactory {privatni konačni davatelj cameraProvider; @Inject PhoneAssemblerFactory (@Named ("Sony") Provider cameraProvider) {this.cameraProvider = checkNotNull (cameraProvider, 1); } // ...}
4. Prilagođeno generiranje koda
Postoji nekoliko atributa koje možemo koristiti s @AutoFactory napomena za prilagodbu generiranog koda.
4.1. Naziv prilagođene klase
Naziv generirane tvorničke klase može se postaviti s className:
@AutoFactory (className = "SamsungFactory") pametni telefon javne klase {// ...}
S gornjom konfiguracijom stvorit ćemo razred s imenom SamsungFactory:
@Generated ("com.google.auto.factory.processor.AutoFactoryProcessor") javna završna klasa SamsungFactory {// ...}
4.2. nepravomoćno Tvornice
Imajte na umu da je generirana tvornička klasa prema zadanim postavkama označena kao konačna, pa to ponašanje možemo promijeniti postavljanjem allowSubclasses pripisati lažno:
@AutoFactory (className = "SamsungFactory", allowSubclasses = true) javna klasa SmartPhone {// ...}
Sad imamo:
@Generated ("com.google.auto.factory.processor.AutoFactoryProcessor") javna klasa SamsungFactory {// ...}
4.3. Više mogućnosti
Uz to, možemo odrediti popis sučelja koja će generirana tvornica implementirati pomoću "provedba ”parametar.
Ovdje nam treba SamsungFactory za proizvodnju pametnih telefona s prilagodljivom pohranom:
javno sučelje CustomStorage {SmartPhone customROMInGB (int romSize); }
Imajte na umu da metode u sučelju trebaju vraćati instance osnovne klase SmartPhone.
Zatim, za generiranje tvorničke klase s implementiranim gornjim sučeljem, AutoFactory zahtijeva relevantne konstruktore u osnovnoj klasi:
@AutoFactory (className = "SamsungFactory", allowSubclasses = true, Implementation = CustomStorage.class) javna klasa SmartPhone {javni SmartPhone (int romSize) {// ...} // ...}
Tako, AutoFactory generirat će sljedeći kod:
@Generated ("com.google.auto.factory.processor.AutoFactoryProcessor") javna klasa SamsungFactory implementira CustomStorage {// ... javni SmartPhone create (int romSize) {return new SmartPhone (romSize); } @Preuzmi javni SmartPhone customROMInGB (int romSize) {return create (romSize); }}
4.4. Tvornice s proširenjima
Od AutoFactory može generirati implementacije sučelja, prirodno je očekivati da će moći proširiti i klase i to je zaista moguće:
javni sažetak klase AbstractFactory {sažetak CustomPhone newInstance (marka niza); } @AutoFactory (extending = AbstractFactory.class) javna klasa CustomPhone {private final String brand; javni CustomPhone (marka niza) {this.brand = brand; }}
Ovdje smo produžili SažetakTvornica razred koristeći produžujući. Također, trebali bismo imajte na umu da svaka apstraktna metoda u osnovnoj apstraktnoj klasi (SažetakTvornica) trebao bi imati odgovarajući konstruktor u klasi betona (CustomPhone).
Konačno, možemo vidjeti sljedeći generirani kôd:
@Generated ("com.google.auto.factory.processor.AutoFactoryProcessor") javna završna klasa CustomPhoneFactory proširuje AbstractFactory {@Inject public CustomPhoneFactory () {} public CustomPhone create (String brand) {return new CustomPhone (checkNotNull (brand, 1) ); } @Override javni CustomPhone newInstance (marka niza) {return create (brand); } // ...}
To možemo vidjeti AutoFactory je dovoljno pametan da koristi konstruktor za implementaciju odgovarajuće apstraktne metode - sjajne značajke poput ove u AutoFactory sigurno će nam uštedjeti puno vremena i koda.
5. AutoFactory S Guice
Kao što smo ranije spomenuli u ovom članku, AutoFactory podržava JSR-330 bilješke, tako da s njim možemo integrirati postojeći okvir za ubrizgavanje ovisnosti.
Prvo, dodajmo Guice prema pom.xml:
com.google.inject guice 4.2.0
Najnovija verzija Guice možete pronaći ovdje.
Sada ćemo pokazati koliko dobro AutoFactory integrira s Guice.
Budući da očekujemo da će "Sony" biti dobavljač fotoaparata, moramo ubrizgati a SonyCameraProvider do PhoneFactoryKonstruktor:
@Generated ("com.google.auto.factory.processor.AutoFactoryProcessor") javna završna klasa PhoneFactory {privatni konačni davatelj cameraProvider; @ Ubrizgajte javnu PhoneFactory (@Named ("Sony") Provider cameraProvider) {this.cameraProvider = checkNotNull (cameraProvider, 1); } // ...}
Konačno, obvezujemo u a Guice modul:
javna klasa SonyCameraModule proširuje AbstractModule {private static int SONY_CAMERA_SERIAL = 1; @Named ("Sony") @Provides Camera cameraProvider () {return new Camera ("Sony", String.format ("% 03d", SONY_CAMERA_SERIAL ++)); }}
I postavili smo dobavljača fotoaparata s bilješkama @Named ("Sony") u SonyCameraModule upariti PhoneFactoryParametar konstruktora.
Sad to možemo vidjeti Guice upravlja ubrizgavanjem ovisnosti za našu generiranu tvornicu:
Injector injector = Guice.createInjector (novi SonyCameraModule ()); PhoneFactory injectedFactory = injector.getInstance (PhoneFactory.class); Telefon xperia = injectedFactory.create ("Xperia");
6. Ispod haube
Sve bilješke pruža AutoFactory obrađuju se u fazi sastavljanja, kao što smo detaljno objasnili u članku: kako funkcionira obrada bilješki na razini izvora.
7. Zaključak
U ovom smo članku predstavili kako koristiti AutoFactory i kako ga integrirati Guice - tvornice pisanja mogu se ponavljati i sklonima pogreškama - alati za generiranje koda poput AutoFactory i AutoValue može nam uštedjeti puno vremena i osloboditi nas suptilnih bugova.
Kao i uvijek, potpunu primjenu uzoraka koda možete pronaći na Githubu.