Programmēšana

Pārāk daudz parametru Java metodēs, 3. daļa: veidotāja modelis

Savos divos iepriekšējos ierakstos es aplūkoju konstruktoru vai metožu izsaukšanai nepieciešamo parametru skaita samazināšanu, izmantojot pielāgotus tipus un parametru objektus. Šajā ziņojumā es aplūkoju būvētāja modeļa izmantošanu, lai samazinātu konstruktoram nepieciešamo parametru skaitu, ar nelielu diskusiju par to, kā šis modelis pat var palīdzēt ar metodēm, kas nav konstruktors un kurās ir pārāk daudz parametru.

Efektīvās Java otrajā izdevumā Džošs Blohs 2. pozīcijā ievieš būvētāja modeli, lai nodarbotos ar konstruktoriem, kuriem nepieciešams pārāk daudz parametru. Blohs ne tikai parāda, kā izmantot Builder, bet arī izskaidro tā priekšrocības salīdzinājumā ar konstruktoriem, kuri pieņem lielu skaitu parametru. Es gūšu pie šīm priekšrocībām šī ieraksta beigās, taču domāju, ka ir svarīgi norādīt, ka Blohs šai grāmatai ir veltījis veselu priekšmetu savā grāmatā.

Lai ilustrētu šīs pieejas priekšrocības, es izmantoju šādu piemēru Persona klasē. Tam nav visu metožu, kuras es parasti pievienotu šādai klasei, jo es vēlos koncentrēties uz tās uzbūvi.

Person.java (bez veidotāja modeļa)

iepakojums dustin.piemēri; / ** * Personas klase tiek izmantota kā daļa no pārāk daudz parametru demonstrēšanas. * * @autors Dastins * / publiskā klase Persona {privātā galīgā virknes uzvārds; privāts fināls String firstName; privāts fināls String middleName; privāts fināls Stīgu sveiciens; privāts gala virknes sufikss; privāts fināls String streetAddress; privāts fināls Stīgu pilsēta; privātā galīgā stīgu valsts; privātā galīgā būla vērtība ir Sieviete; privātā galīgā būla vērtība irNodarbināta; privātā gala būla vērtība ir HomeWWner; public Person (final String newLastName, final String newFirstName, final String newMiddleName, final String newSalutation, final String newSuffix, final String newStreetAddress, final String newCity, final String newState, final boolean newIsFemale, final boolean newIsEwooler, final this boolean newIsOmeans, final this boolean. uzvārds = newLastName; this.firstName = newFirstName; this.middleName = newMiddleName; this.salutation = newSalutation; this.suffix = newSuffix; this.streetAddress = newStreetAddress; this.city = newCity; this.state = newState; this.isFemale = newIsFemale; this.isEmployed = newIsEmployed; this.isHomewOwner = newIsHomeOwner; }} 

Šīs klases konstruktors darbojas, taču klienta kodu ir grūti pareizi izmantot. Builder modeli var izmantot, lai padarītu konstruktoru vieglāk lietojamu. NetBeans man to pārveidos, kā es jau iepriekš rakstīju. Nākamais tiek parādīts atjaunotā koda piemērs (NetBeans to dara, izveidojot visu jauno Builder klasi).

PersonBuilder.java

iepakojums dustin.piemēri; publiskā klase PersonBuilder {private String newLastName; privāta virkne newFirstName; privāta virkne newMiddleName; privāta virkne newSalutation; privāta virkne newSuffix; privātā virkne newStreetAddress; privāta virkne newCity; privāta virkne newState; privāts Būla jaunumsIsFemale; privāts būla jaunumsIsNodarbināts; privāts būla jaunumsIsHomeOwner; public PersonBuilder () {} public PersonBuilder setNewLastName (String newLastName) {this.newLastName = newLastName; atgriezt šo; } public PersonBuilder setNewFirstName (String newFirstName) {this.newFirstName = newFirstName; atgriezt šo; } public PersonBuilder setNewMiddleName (String newMiddleName) {this.newMiddleName = newMiddleName; atgriezt šo; } public PersonBuilder setNewSalutation (String newSalutation) {this.newSalutation = newSalutation; atgriezt šo; } public PersonBuilder setNewSuffix (String newSuffix) {this.newSuffix = newSuffix; atgriezt šo; } public PersonBuilder setNewStreetAddress (String newStreetAddress) {this.newStreetAddress = newStreetAddress; atgriezt šo; } public PersonBuilder setNewCity (String newCity) {this.newCity = newCity; atgriezt šo; } public PersonBuilder setNewState (String newState) {this.newState = newState; atgriezt šo; } public PersonBuilder setNewIsFemale (boolean newIsFemale) {this.newIsFemale = newIsFemale; atgriezt šo; } public PersonBuilder setNewIsEmployed (būla newIsEmployed) {this.newIsEmployed = newIsEmployed; atgriezt šo; } public PersonBuilder setNewIsHomeOwner (boolean newIsHomeOwner) {this.newIsHomeOwner = newIsHomeOwner; atgriezt šo; } public Person createPerson () {return new Person (newLastName, newFirstName, newMiddleName, newSalutation, newSuffix, newStreetAddress, newCity, newState, newIsFemale, newIsEmployed, newIsHomeOwner); }} 

Es vēlētos, lai mans Builder būtu ligzdota klase tās klases iekšpusē, kuras objektu tā veido, bet NetBeans atsevišķā Builder automātisko ģenerēšanu ir ļoti viegli izmantot. Vēl viena atšķirība starp NetBeans ģenerēto veidotāju un veidotājiem, kurus man patīk rakstīt, ir tā, ka manām vēlamajām Builder ieviešanām ir nepieciešami lauki, kas jānorāda Builder konstruktorā, nevis jānodrošina konstruktors bez argumentiem. Nākamais kodu saraksts parāda manu Persona klase no augšas, un tajā kā ligzdotu klasi ir pievienots celtnieks.

Persona. Java ar ligzdotu personu. Celtnieks

iepakojums dustin.piemēri; / ** * Personas klase tiek izmantota kā daļa no pārāk daudz parametru demonstrēšanas. * * @autors Dastins * / publiskā klase Persona {privātā galīgā virknes uzvārds; privāts fināls String firstName; privāts fināls String middleName; privāts fināls Stīgu sveiciens; privāts gala virknes sufikss; privāts fināls String streetAddress; privāts fināls Stīgu pilsēta; privātā galīgā stīgu valsts; privātā galīgā būla vērtība ir Sieviete; privātā galīgā būla vērtība irNodarbināta; privātā gala būla vērtība ir HomeWWner; public Person (final String newLastName, final String newFirstName, final String newMiddleName, final String newSalutation, final String newSuffix, final String newStreetAddress, final String newCity, final String newState, final boolean newIsFemale, final boolean newIsEwooler, final this boolean newIsOmeans, final this boolean. uzvārds = newLastName; this.firstName = newFirstName; this.middleName = newMiddleName; this.salutation = newSalutation; this.suffix = newSuffix; this.streetAddress = newStreetAddress; this.city = newCity; this.state = newState; this.isFemale = newIsFemale; this.isEmployed = newIsEmployed; this.isHomewOwner = newIsHomeOwner; } public static class PersonBuilder {private String nestedLastName; privāta virkne nestedFirstName; privāta virkne nestedMiddleName; privāta virkne nestedSalutation; privāta virkne nestedSuffix; privātā virkne nestedStreetAddress; privāta virkne nestedCity; privāta virkne nestedState; privāts Būla ligzdotsIsFemale; privāts Būla ligzdotsIsNodarbināts; privāts Būla ligzdotsIsHomeOwner; public PersonBuilder (final String newFirstName, final String newCity, final String newState) {this.nestedFirstName = newFirstName; this.nestedCity = newCity; this.nestedState = newState; } public PersonBuilder uzvārds (virkne newLastName) {this.nestedLastName = newLastName; atgriezt šo; } public PersonBuilder firstName (String newFirstName) {this.nestedFirstName = newFirstName; atgriezt šo; } public PersonBuilder middleName (String newMiddleName) {this.nestedMiddleName = newMiddleName; atgriezt šo; } public PersonBuilder sveiciens (String newSalutation) {this.nestedSalutation = newSalutation; atgriezt šo; } public PersonBuilder sufikss (String newSuffix) {this.nestedSuffix = newSuffix; atgriezt šo; } public PersonBuilder streetAddress (String newStreetAddress) {this.nestedStreetAddress = newStreetAddress; atgriezt šo; } public PersonBuilder city (String newCity) {this.nestedCity = newCity; atgriezt šo; } public PersonBuilder state (String newState) {this.nestedState = newState; atgriezt šo; } public PersonBuilder isFemale (boolean newIsFemale) {this.nestedIsFemale = newIsFemale; atgriezt šo; } public PersonBuilder isEnployed (būla jaunumsIsEmployed) {this.nestedIsEmployed = newIsEmployed; atgriezt šo; } public PersonBuilder isHomeOwner (boolean newIsHomeOwner) {this.nestedIsHomeOwner = newIsHomeOwner; atgriezt šo; } public Person createPerson () {return new Person (nestedLastName, nestedFirstName, nestedMiddleName, nestedSalutation, nestedSuffix, nestedStreetAddress, nestedCity, nestedState, nestedIsFemale, nestedIsEmployed, nestedIsHomeOwner); }}} 

Veidotājs var būt vēl jaukāks, ja to uzlabo, izmantojot pielāgotu veidu un parametru objektus, kā norādīts manos pirmajos divos ziņojumos par problēmu "pārāk daudz parametru". Tas ir parādīts nākamajā kodu sarakstā.

Person.java ar Nested Builder, Custom Types un Parameters Object

iepakojums dustin.piemēri; / ** * Personas klase tiek izmantota kā daļa no pārāk daudz parametru demonstrēšanas. * * @ autors Dastins * / publiskā klase Persona {privātais galīgais vārds, uzvārds; privātā galīgā adreses adrese; privāts fināls Dzimums; privātā galīgā EmploymentStatus nodarbinātība; privāts fināls HomeownerStatus homeOwnerStatus; / ** * Parametrizētais konstruktors var būt privāts, jo tikai manam iekšējam veidotājam * man ir jāzvana, lai klientiem sniegtu instanci. * * @param newName Šīs personas vārds. * @param newAddress Šīs personas adrese. * @param newGender Šīs personas dzimums. * @param newEmployment Šīs personas nodarbinātības statuss. * @param newHomeOwner Šīs personas īpašumtiesību statuss mājās. * / privāta persona (galīgais Pilns Vārds jaunsNOSAUKUMS, gala adrese newAddress, gala Dzimums newGender, gala EmploymentStatus newEmployment, gala HomeownerStatus newHomeOwner) {this.name = newName; this.address = newAddress; this.gender = newGender; this.nodarbinātība = newNodarbinātība; this.homeOwnerStatus = newHomeOwner; } public Pilns Vārds getName () {atgriezt šo.nosaukumu; } public Address getAddress () {return this.address; } public Gender getGender () {return this.gender; } public EmploymentStatus getEmployment () {return this.employment; } public HomeownerStatus getHomeOwnerStatus () {return this.homeOwnerStatus; } / ** * Celtnieku klase, kā izklāstīts Džošua Bloka grāmatas * Efektīva Java kas tiek izmantots, lai izveidotu {@link Person} instanci. * / public static class PersonBuilder {private Pilns Vārds nestedName; privātā adrese nestedAddress; privāts Dzimums ligzdotsDzimums; private EmploymentStatus nestedEmploymentStatus; privātā māju īpašniekaStatus ligzdotsHomeOwnerStatus; public PersonBuilder (galīgais Pilns Vārds newFullName, gala adrese newAddress) {this.nestedName = newFullName; this.nestedAddress = newAddress; } public PersonBuilder nosaukums (galīgais PilnsNOSAUKUMS newName) {this.nestedName = newName; atgriezt šo; } publiskā PersonBuilder adrese (galīgā adrese newAddress) {this.nestedAddress = newAddress; atgriezt šo; } public PersonBuilder dzimums (galīgais Dzimums newGender) {this.nestedGender = newGender; atgriezt šo; } publiskā PersonBuilder nodarbinātība (galīgais EmploymentStatus newEmploymentStatus) {this.nestedEmploymentStatus = newEmploymentStatus; atgriezt šo; } public PersonBuilder homeOwner (gala HomeownerStatus newHomeOwnerStatus) {this.nestedHomeOwnerStatus = newHomeOwnerStatus; atgriezt šo; } public Person createPerson () {return new Person (nestedName, nestedAddress, nestedGender, nestedEmploymentStatus, nestedHomeOwnerStatus); }}} 

Pēdējie pāris kodu saraksti parāda, kā parasti tiek izmantots veidotājs - objekta konstruēšanai. Džošua Bloka efektīvā Java otrā izdevuma elements būvētājā (Nr. 2) atrodas nodaļā par objekta izveidošanu (un iznīcināšanu). Tomēr celtnieks var netieši palīdzēt ar metodēm, kas nav konstruktors, ļaujot vieglāk veidot parametriem objektus, kas tiek nodoti metodēm.

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