Programmēšana

Pārāk daudz parametru Java metodēs, 6. daļa: Metode atgriež

Pašreizējā ziņojumu sērijā, kuru rakstu par to, kā samazināt nepieciešamo parametru skaitu, lai izsauktu Java metodes un konstruktorus, līdz šim esmu koncentrējies uz pieejām, kas tieši ietekmē pašus parametrus (pielāgotie veidi, parametru objekti, veidotāja modelis, metodes pārslodze un metodes nosaukšana). Ņemot to vērā, man varētu šķist pārsteidzoši veltīt ierakstu šajā sērijā tam, kā Java metodes nodrošina atgriešanās vērtības. Tomēr metožu atgriešanās vērtības var ietekmēt parametrus, kurus metodes pieņem, kad izstrādātāji izvēlas nodrošināt "atgriešanās" vērtības, iestatot vai mainot paredzētos parametrus, nevis tradicionālo metožu atgriešanas mehānismus vai papildus tiem.

"Parastos veidus", kā metode, kas nav konstruktora metode, atdod vērtību, abus var norādīt metodes parakstā. Visbiežāk tiek atzīta pieeja vērtības atgriešanai no Java metodes, izmantojot tās deklarēto atgriešanās veidu. Tas bieži vien darbojas labi, taču viens no visbiežāk sastopamajiem neapmierinātības gadījumiem ir atļauts atgriezt tikai vienu vērtību no Java metodes.

Java izņēmumu apstrādes mehānisms ir arī cita pieeja, lai saglabātu metodes "rezultātu" zvanītājiem. Pārbaudītie izņēmumi jo īpaši tiek reklamēti zvanītājam, izmantojot klauzulu par metieniem. Faktiski Džims Valdo savā grāmatā Java: labās daļas apgalvo, ka Java izņēmumus ir vieglāk saprast, ja kāds domā par Java izņēmumiem kā cita veida metode atgriežas tikai ar Throwable tipu.

Lai gan metodes atgriešanas veids un izmestie izņēmumi ir paredzēti kā primārās pieejas metodēm, kā atgriezt informāciju zvanītājiem, dažreiz ir vilinoši atgriezt datus vai stāvokli, izmantojot metodē nodotos parametrus. Ja metodei ir jāatdod vairāk nekā viena informācija, Java metožu vienas vērtības atdeve var šķist ierobežojoša. Lai gan izņēmumi nodrošina vēl vienu veidu, kā sazināties ar zvanītāju, šķiet, ka gandrīz visā pasaulē ir vienots viedoklis, ka izņēmumi jāizmanto tikai ziņošanai par ārkārtas situācijām, nevis ziņošanai par "normāliem" datiem vai jāizmanto vadības plūsmā. Ņemot vērā to, ka no metodes var atgriezt tikai vienu objektu vai primitīvu un ka izņēmumi ļauj atgriezt tikai a Metams un to vajadzētu izmantot tikai ziņošanai par ārkārtas situācijām, Java izstrādātājam kļūst arvien pievilcīgāk nolaupīt parametrus kā alternatīvu maršrutu, lai atgrieztu datus zvanītājam.

Metode, kuru izstrādātājs var izmantot, lai metodes parametrus izmantotu kā datu atgriešanas nesējus, ir mainīgu parametru pieņemšana un nodoto objektu stāvokļa mutācija. Šo maināmo objektu saturu var mainīt, izmantojot metodi, un pēc tam zvanītājs var piekļūt objektam, kuru tas sniedza, lai noteiktu tā jaunos stāvokļa iestatījumus, kas ir izmantoti ar izsaukto metodi. Lai gan to var izdarīt ar jebkuru maināmu objektu, kolekcijas šķiet īpaši pievilcīgas izstrādātājam, kurš mēģina nodot vērtības zvanītājam, izmantojot parametrus.

Ir daži trūkumi, ja stāvoklis tiek atgriezts izsauktajā, izmantojot norādītos parametrus. Šī pieeja bieži pārkāpj vismazākā izbrīna principu, jo lielākā daļa Java izstrādātāju, iespējams, sagaida, ka parametri būs Ienākošie, nevis OUTaizējie (un Java nenodrošina koda atbalstu, lai norādītu atšķirību). Bobs Martins to savā grāmatā Clean Code izsaka šādi: "Parasti jāizvairās no izvades argumentiem". Vēl viens trūkums, lietojot argumentus kā līdzekli metodei, lai zvanītājam sniegtu stāvokli vai izvadi, ir tāds, ka tas palielina metodei nodoto argumentu jucekli. Paturot to prātā, šī ziņojuma atlikums koncentrējas uz alternatīvām vairāku vērtību atgriešanai, izmantojot nodotos parametrus.

Lai gan Java metodes var atgriezt tikai vienu objektu vai primitīvu, tas patiešām nav daudz ierobežojums, ja tiek uzskatīts, ka objekts var būt gandrīz viss, ko mēs vēlamies. Ir vairākas pieejas, kuras esmu redzējis, bet neiesaku. Viens no tiem ir objektu masīva vai kolekcijas atgriešana ar katru Objekts būt atšķirīgai un atšķirīgai un bieži vien nesaistītai "lietai". Piemēram, metode var atgriezt trīs vērtības kā trīs masīva vai kolekcijas elementus. Šīs pieejas variants ir izmantot pāra vai n lieluma pogu, lai atgrieztu vairākas saistītās vērtības. Vēl viena šīs pieejas variācija ir atgriezt Java karti, kas patvaļīgas atslēgas kartē ar to saistīto vērtību. Tāpat kā citu risinājumu gadījumā, šī pieeja liek pārmērīgu slogu klientam, lai viņš zinātu, kas ir šie taustiņi, un piekļūtu kartes vērtībām, izmantojot šos taustiņus.

Nākamajā kodu sarakstā ir vairākas no šīm mazāk pievilcīgajām pieejām, lai atgrieztu vairākas vērtības, nolaupot metodes parametrus, lai atgrieztu vairākas vērtības.

Vairāku vērtību atgriešana, izmantojot vispārīgas datu struktūras

 // ================================================== =============== // PIEZĪME. Šie piemēri ir paredzēti tikai, lai ilustrētu punktu //, un NAV ieteicami ražošanas kodam. // ================================================== =============== / ** * Sniedziet informāciju par filmu. * * @return Filmas informācija masīva veidā, kur informācija tiek kartēta ar * elementiem ar šādiem masīva rādītājiem: * 0: filmas nosaukums * 1: izlaiduma gads * 2: režisors * 3: vērtējums * / publisks objekts [] getMovieInformation () {final Object [] movieDetails = {"Pasaules karš Z", 2013, "Marc Forster", "PG-13"}; atgriešanās filmaDetails; } / ** * Sniedziet informāciju par filmu. * * @return Filmas informācija saraksta veidā, kur ir sniegta informācija * šādā secībā: filmas nosaukums, izlaiduma gads, režisors, vērtējums. * / public list getMovieDetails () {return Arrays.asList ("Ender's Game", 2013, "Gavin Hood", "PG-13"); } / ** * Sniedziet informāciju par filmu. * * @return Filmas informācija kartes formā. Filmas raksturojumu * var iegūt, kartē meklējot šādus galvenos elementus: "Nosaukums", "Gads", * "Režisors" un "Vērtējums" ./ * / public Map getMovieDetailsMap () {final HashMap map = new HashMap (); map.put ("Nosaukums", "nicināms Es 2"); map.put ("Gads", 2013); map.put ("Režisors", "Pjērs Zārks un Kriss Renauds"); map.put ("Vērtējums", "PG"); atgriešanās karte; } 

Iepriekš norādītās pieejas atbilst nodomam nenodot datus zvanītājam, izmantojot izsaukto metožu parametrus, taču zvanītājam joprojām ir lieks slogs, lai zinātu intīmo informāciju par atgriezto datu struktūru. Ir patīkami samazināt metodes parametru skaitu un nepārkāpt mazākā pārsteiguma principu, taču nav tik jauki pieprasīt klientam zināt sarežģītas datu struktūras sarežģījumus.

Es labprātāk rakstītu pielāgotus objektus atgriešanai, kad man jāatdod vairāk nekā viena vērtība. Tas ir nedaudz vairāk darba nekā masīva, kolekcijas vai dubultstruktūras izmantošana, taču ļoti mazais papildu darba apjoms (parasti dažas minūtes ar moderniem Java IDE) atmaksājas ar lasāmību un tekošumu, kas nav pieejams ar šīm vispārīgākajām pieejām. Tā vietā, lai man būtu jāpaskaidro ar Javadoc vai jāpieprasa mana koda lietotājiem rūpīgi izlasīt manu kodu, lai zinātu, kuri parametri masīvā vai kolekcijā ir norādīti kādā secībā vai kura vērtība ir kopā, manās pielāgotajās atgriešanās objektos var būt definētas metodes tie, kas klientam precīzi pasaka, ko viņi sniedz.

Sekojošie kodu fragmenti parāda vienkāršu Filma klase, kuru lielākoties ģenerē NetBeans un kuru var izmantot kā atgriešanās tipu kopā ar kodu, kas varētu atgriezt šīs klases instanci, nevis vispārīgāku un mazāk lasāmu datu struktūru.

Filma.java

iepakojums dustin.piemēri; importēt java.util.Objects; / ** * Vienkāršā filmu klase, lai parādītu, cik viegli ir nodrošināt vairākas vērtības * vienā Java metodē un nodrošināt klientam lasāmību. * * @autors Dastins * / publiskās klases filma {privātais fināls Stīgu filmaTitle; privāts galīgais starpgads Atbrīvots; privāts fināls Stīgu filmaDirectorName; privāts fināls Stīgu filmaRating; public Movie (String movieTitle, int yearReleased, String movieDirectorName, String movieRating) {this.movieTitle = movieTitle; this.yearReleased = gadsReleased; this.movieDirectorName = movieDirectorName; this.movieRating = movieRating; } public String getMovieTitle () {return movieTitle; } public int getYearReleased () {return yearReleased; } public String getMovieDirectorName () {return movieDirectorName; } public String getMovieRating () {return movieRating; } @ Pārvarēt publisko int hashCode () {int hash = 3; hash = 89 * hash + Objects.hashCode (this.movieTitle); hash = 89 * hash + this.yearReleased; hash = 89 * hash + Objects.hashCode (this.movieDirectorName); hash = 89 * hash + Objects.hashCode (this.movieRating); atgriešanās hash; } @Orride public Boolean equals (Object obj) {if (obj == null) {return false; } if (getClass ()! = obj.getClass ()) {return false; } gala filma cita = (Filma) obj; if (! Objects.equals (this.movieTitle, other.movieTitle)) {return false; } if (šis.gadu Atbrīvots! = cits.gadu Atbrīvots) {atgriezt nepatiesu; } if (! Objects.equals (this.movieDirectorName, other.movieDirectorName)) {return false; } if (! Objects.equals (this.movieRating, other.movieRating)) {return false; } return true; } @Override public String toString () {return "Movie {" + "movieTitle =" + movieTitle + ", yearReleased =" + yearReleased + ", movieDirectorName =" + movieDirectorName + ", movieRating =" + movieRating + '}'; }} 

Atgriežot vairākas detaļas vienā objektā

 / ** * Sniedziet informāciju par filmu. * * @return Filmas informācija. * / public Movie getMovieInfo () {return new Movie ("Aizmirstība", 2013, "Džozefs Kosinskis", "PG-13"); } 

Vienkārša Filma klase man prasīja apmēram 5 minūtes. Es izmantoju NetBeans klases izveides vedni, lai atlasītu klases nosaukumu un paketi, un pēc tam es ierakstīju četrus klases atribūtus. No turienes es vienkārši izmantoju NetBeans mehānismu "Ievietot kodu", lai ievietotu "get" piekļuves metodes kopā ar ignorētām metodēm toString (), hashCode () un equals (Object). Ja es nedomāju, ka man kaut kas no tā ir vajadzīgs, es varētu saglabāt klasi vienkāršāku, bet to tiešām ir viegli izveidot tādu, kāda tā ir. Tagad man ir daudz izmantojamāks atgriešanās veids, un to atspoguļo kods, kas izmanto klasi. Tam nav vajadzīgs gandrīz tik daudz Javadoc komentāru par atgriešanās veidu, jo šis tips runā pats par sevi un reklamē tā saturu ar savām metodēm "get". Es uzskatu, ka nelielais papildu pūles, lai izveidotu šīs vienkāršās klases vairāku vērtību atgriešanai, atmaksājas ar milzīgām dividendēm, salīdzinot ar tādām alternatīvām kā atgriešanās stāvoklis, izmantojot metodes parametrus, vai izmantojot vispārīgākas un grūtāk izmantojamas atgriešanās datu struktūras.

Nav pārāk pārsteidzoši, ka pielāgots veids, kā turēt vairākas vērtības, kas jāatgriež zvanītājam, ir pievilcīgs risinājums. Galu galā tas ir konceptuāli ļoti līdzīgs tiem jēdzieniem, par kuriem es iepriekš rakstīju blogā un kas saistīti ar pielāgotu tipu un parametru objektu izmantošanu vairāku saistītu parametru pārsūtīšanai, nevis to visu nodošanai atsevišķi. Java ir uz objektu orientēta valoda, un tāpēc mani pārsteidz tas, ka es neredzu objektus, kas Java kodā tiek izmantoti biežāk parametru UN atgriezenisko vērtību sakārtošanai jaukā paketē.

Priekšrocības un priekšrocības

Priekšrocības, izmantojot pielāgotu parametru objektus, lai attēlotu un iekapsulētu vairākas atgriešanās vērtības, ir acīmredzamas. Metodes parametri var palikt kā "ievades" parametri, jo visu izvades informāciju (izņemot kļūdu informāciju, kas tiek paziņota, izmantojot izņēmuma mehānismu) var norādīt pielāgotajā objektā, ko atdod metode. Šī ir tīrāka pieeja nekā vispārīgu masīvu, kolekciju, karšu, kopu vai citu vispārīgu datu struktūru izmantošana, jo visas šīs alternatīvās pieejas attīstības centienus novirza uz visiem potenciālajiem klientiem.

Izmaksas un trūkumi

Es redzu ļoti nelielu trūkumu, rakstot pielāgotus veidus ar vairākām vērtībām, kas jāizmanto kā atgriešanas veidi no Java metodēm. Varbūt visbiežāk pieteiktās izmaksas ir šo nodarbību rakstīšanas un testēšanas cena, taču šīs izmaksas ir diezgan mazas, jo šīs klases mēdz būt vienkāršas un tāpēc, ka mūsdienu IDE veic lielāko daļu darba mūsu vietā. Tā kā IDE to dara automātiski, kods parasti ir pareizs. Nodarbības ir tik vienkāršas, ka kodu pārskatītāji tās ir viegli nolasāmas, un tās ir viegli pārbaudīt.

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