Úvod do AutoFactory

1. Úvod

V tomto výučbe stručne predstavíme AutoFactoryod spoločnosti Google.

Toto je generátor kódu na zdrojovej úrovni, ktorý pomáha generovať továrne.

2. Nastavenie Maven

Skôr ako začneme, pridajme do súboru nasledujúcu závislosť pom.xml:

 com.google.auto.factory auto-factory 1.0-beta5 

Najnovšiu verziu nájdete tu.

3. Rýchly štart

Poďme sa teraz rýchlo pozrieť na to, čo AutoFactory môže robiť a vytvárať jednoduché Telefón trieda.

Takže, keď anotujeme Telefón trieda s @AutoFactory a jeho konštruktorový parameter s @ Za predpokladu, dostaneme:

@AutoFactory verejná trieda Telefón {private final Camera camera; súkromné ​​finále String otherParts; PhoneAssembler (@Provided Camera camera, String otherParts) {this.camera = kamera; this.otherParts = otherParts; } // ...}

Použili sme iba dve anotácie: @AutoFactory a @ Za predpokladu. Keď potrebujeme továreň vygenerovanú pre našu triedu, môžeme ju anotovať @AutoFactory, keďže @ Za predpokladu sa vzťahuje na parametre konštruktora tejto triedy a znamená to, že anotovaný parameter by mal byť poskytnutý injected Poskytovateľ.

V úryvku vyššie očakávame fotoaparát poskytnúť akýkoľvek výrobca fotoaparátov a AutoFactory pomôže vygenerovať nasledujúci kód:

@Generated ("com.google.auto.factory.processor.AutoFactoryProcessor") verejná finálna trieda PhoneFactory {private final Provider cameraProvider; @Inject PhoneAssemblerFactory (poskytovateľ cameraProvider) {this.cameraProvider = checkNotNull (cameraProvider, 1); } PhoneAssembler create (String otherParts) {return new PhoneAssembler (checkNotNull (cameraProvider.get (), 1), checkNotNull (otherParts, 2)); } // ...}

Teraz máme PhoneFactory generované automaticky používateľom AutoFactory v čase kompilácie a môžeme ho použiť na vytvorenie inštancií telefónu:

PhoneFactory phoneFactory = nový PhoneFactory (() -> nová kamera („Neznáme“, „XXX“)); Telefón simplePhone = phoneFactory.create ("ďalšie časti");

The @AutoFactory anotáciu je možné použiť aj na konštruktérov:

verejná trieda ClassicPhone {súkromné ​​finále String dialpad; súkromné ​​záverečné Vyzváňanie strún; private String otherParts; @AutoFactory public ClassicPhone (@Provided String dialpad, @Provided String ringer) {this.dialpad = dialpad; this.ringer = zvonenie; } @AutoFactory public ClassicPhone (String otherParts) {this ("defaultDialPad", "defaultRinger"); this.otherParts = otherParts; } // ...}

V úryvku vyššie sme použili @AutoFactory obom konštruktérom. AutoFactory podľa toho pre nás jednoducho vygeneruje dve metódy vytvárania:

@Generated (value = "com.google.auto.factory.processor.AutoFactoryProcessor") verejná záverečná trieda ClassicPhoneFactory {súkromné ​​konečné poskytovateľ java_lang_StringProvider; @Inject public ClassicPhoneFactory (poskytovateľ java_lang_StringProvider) {this.java_lang_StringProvider = checkNotNull (java_lang_StringProvider, 1); } verejné ClassicPhone create () {return new ClassicPhone (checkNotNull (java_lang_StringProvider.get (), 1), checkNotNull (java_lang_StringProvider.get (), 2)); } verejné ClassicPhone create (String otherParts) {vrátiť nový ClassicPhone (checkNotNull (otherParts, 1)); } // ...}

AutoFactory podporuje aj parametre anotované pomocou @ Za predpokladu, ale iba pre anotácie JSR-330.

Napríklad, ak chceme cameraProvider byť „Sony“, môžeme zmeniť Telefón trieda do:

@AutoFactory verejná trieda Telefón {PhoneAssembler (@Provided @Named ("Sony") Fotoaparát fotoaparátu, String otherParts) {this.camera = fotoaparát; this.otherParts = otherParts; } // ...}

AutoFactory si ponechá @ Menovaný@Qualifier aby sme to mohli využiť napríklad pri použití rámcov Dependency Injection:

@Generated ("com.google.auto.factory.processor.AutoFactoryProcessor") verejná finálna trieda PhoneFactory {private final Provider cameraProvider; @Inject PhoneAssemblerFactory (@Named ("Sony") Provider cameraProvider) {this.cameraProvider = checkNotNull (cameraProvider, 1); } // ...}

4. Prispôsobené generovanie kódu

Existuje niekoľko atribútov, ktoré môžeme použiť s @AutoFactory anotácia na prispôsobenie vygenerovaného kódu.

4.1. Názov vlastnej triedy

Názov vygenerovanej továrenskej triedy je možné nastaviť pomocou className:

@AutoFactory (className = "SamsungFactory") verejná trieda SmartPhone {// ...}

Pomocou konfigurácie vyššie vytvoríme triedu s názvom SamsungFactory:

@Generated ("com.google.auto.factory.processor.AutoFactoryProcessor") verejná finálna trieda SamsungFactory {// ...}

4.2. nefinančné Továrne

Upozorňujeme, že vygenerovaná továrenská trieda je predvolene označená ako konečná, takže toto správanie môžeme zmeniť nastavením hodnoty allowSubclasses atribút nepravda:

@AutoFactory (className = "SamsungFactory", allowSubclasses = true) verejná trieda SmartPhone {// ...}

Teraz máme:

@Generated ("com.google.auto.factory.processor.AutoFactoryProcessor") verejná trieda SamsungFactory {// ...}

4.3. Viac možností

Ďalej môžeme určiť zoznam rozhraní pre implementovanú generovanú továreň pomocou „implementujúci “parameter.

Tu potrebujeme SamsungFactory vyrábať smartfóny s prispôsobiteľným úložiskom:

verejné rozhranie CustomStorage {SmartPhone customROMInGB (int romSize); }

Upozorňujeme, že metódy v rozhraní by mali vracať inštancie základnej triedy SmartPhone.

Potom vygenerujte továrenskú triedu s implementovaným vyššie uvedeným rozhraním, AutoFactory vyžaduje príslušné konštruktory v základnej triede:

@AutoFactory (className = "SamsungFactory", allowSubclasses = true, implementation = CustomStorage.class) verejná trieda SmartPhone {verejná SmartPhone (int romSize) {// ...} // ...}

Teda AutoFactory vygeneruje nasledujúci kód:

@Generated ("com.google.auto.factory.processor.AutoFactoryProcessor") verejná trieda SamsungFactory implementuje CustomStorage {// ... public SmartPhone create (int romSize) {return new SmartPhone (romSize); } @Override public SmartPhone customROMInGB (int romSize) {return create (romSize); }}

4.4. Továrne s rozšíreniami

Odkedy AutoFactory môže generovať implementácie rozhraní, je prirodzené očakávať, že bude môcť rozšíriť aj triedy, a je to skutočne možné:

verejná abstraktná trieda AbstractFactory {abstrakt CustomPhone newInstance (značka String); } @AutoFactory (rozšírenie = AbstractFactory.class) verejná trieda CustomPhone {súkromná konečná značka reťazca; public CustomPhone (značka reťazca) {this.brand = značka; }}

Tu sme rozšírili AbstractFactory trieda pomocou predlžujúci sa. Tiež by sme mali všimnite si, že každá abstraktná metóda v základnej abstraktnej triede (AbstractFactory) by mal mať zodpovedajúci konštruktor v triede betónu (CustomPhone).

Nakoniec vidíme nasledujúci vygenerovaný kód:

@Generated ("com.google.auto.factory.processor.AutoFactoryProcessor") verejná finálna trieda CustomPhoneFactory rozširuje AbstractFactory {@Inject public CustomPhoneFactory () {} verejné CustomPhone create (značka reťazca) {vrátiť nový CustomPhone (checkNotNull (značka, 1)) ); } @Override public CustomPhone newInstance (String brand) {return create (brand); } // ...}

To vidíme AutoFactory je dostatočne inteligentný na to, aby využil konštruktor na implementáciu zodpovedajúcej abstraktnej metódy - skvelé vlastnosti, ako je táto v AutoFactory určite nám ušetrí veľa času a kódu.

5. AutoFactory S Guice

Ako sme už spomínali v tomto článku, AutoFactory podporuje anotácie JSR-330, takže doň môžeme integrovať existujúci rámec na vkladanie závislostí.

Najprv dodajme Guice do pom.xml:

 com.google.inject guice 4.2.0 

Najnovšia verzia servera Guice nájdete tu.

Teraz si ukážeme, ako dobre AutoFactory integruje sa do Guice.

Pretože očakávame, že spoločnosť „Sony“ bude poskytovateľom fotoaparátov, musíme vložiť a SonyCameraProvider do PhoneFactoryKonštruktér:

@Generated ("com.google.auto.factory.processor.AutoFactoryProcessor") verejná finálna trieda PhoneFactory {private final Provider cameraProvider; @Inject public PhoneFactory (@Named ("Sony") Provider cameraProvider) {this.cameraProvider = checkNotNull (cameraProvider, 1); } // ...}

Nakoniec urobíme väzbu v a Guice modul:

verejná trieda SonyCameraModule rozširuje AbstractModule {private static int SONY_CAMERA_SERIAL = 1; @Named ("Sony") @Provides Camera cameraProvider () {return new Camera ("Sony", String.format ("% 03d", SONY_CAMERA_SERIAL ++)); }}

Poskytovateľa fotoaparátu sme nastavili s poznámkami @Named („Sony“) v Modul SonyCamera tak, aby zodpovedala PhoneFactoryParameter konštruktora.

Teraz to vidíme Guice spravuje vkladanie závislostí pre našu vygenerovanú továreň:

Injector injector = Guice.createInjector (nový SonyCameraModule ()); PhoneFactory injectedFactory = injector.getInstance (PhoneFactory.class); Telefón xperia = injectedFactory.create ("Xperia");

6. Pod kapotou

Všetky anotácie poskytnuté používateľom AutoFactory sú spracovávané v štádiu kompilácie, ako sme si v článku podrobne vysvetlili: ako funguje spracovanie anotácií na úrovni zdroja.

7. Záver

V tomto článku sme si predstavili, ako používať AutoFactory a ako ju integrovať do Guice - továrne na písanie môžu byť opakujúce sa a náchylné na chyby - napríklad nástroje na generovanie kódu AutoFactory a AutoValue môže nám ušetriť veľa času a zbaviť nás jemných chýb.

Úplnú implementáciu vzorov kódu nájdete ako vždy na serveri Github.


$config[zx-auto] not found$config[zx-overlay] not found