Programmēšana

Lauku un metožu izstrāde

Šomēnes maksājums par Dizaina paņēmieni ir otrā kolonnu mini sērijā par objektu dizainu. Pagājušā mēneša slejā, kas ietvēra objektu projektēšanu pareizai inicializēšanai, es runāju par to, kā projektēt konstruktorus un inicializētājus. Šomēnes un nākamajā mēnesī es apspriedīšu klases faktisko jomu un metožu izstrādes principus. Pēc tam es uzrakstīšu par finišētājiem un parādīšu, kā viņu dzīves beigās noformēt objektus pareizai tīrīšanai.

Šī raksta materiāls (izvairīšanās no īpašām datu vērtībām, konstantu izmantošana, sasaistes samazināšana) un nākamais raksts (kohēzijas maksimizēšana) var būt pazīstams daudziem lasītājiem, jo ​​materiāla pamatā ir vispārīgi dizaina principi, kas ir diezgan neatkarīgi no Java programmēšanas valodas . Tomēr, tā kā gadu gaitā esmu sastapies ar tik daudz koda, kas neizmanto šos principus, es domāju, ka tie ir pelnījuši laiku pa laikam atkārtotu. Turklāt šajā rakstā es mēģinu parādīt, kā šie vispārējie principi attiecas tieši uz Java valodu.

Lauku projektēšana

Veidojot laukus, galvenais īkšķis ir izvairīties no viena mainīgā izmantošanas, lai attēlotu vairākus klases atribūtus. Jūs varat pārkāpt šo noteikumu, mainīgajā norādot īpašas vērtības, kurām katrai ir sava īpašā nozīme.

Kā šeit izmantots, atribūts ir objekta vai klases atšķirības pazīme. Divi atribūti a Kafijas krūzīte piemēram, objekts varētu būt:

  • Tases kafijas daudzums
  • Neatkarīgi no tā, vai kauss ir tīrs vai netīrs

Lai tuvāk apskatītu šo noteikumu, iedomājieties, ka jūs izstrādājat Kafijas krūzīte klase virtuālajai kafejnīcai, kas aprakstīta pagājušā mēneša Dizaina paņēmieni kolonna. Pieņemsim, ka vēlaties modelēt, vai kafijas tasīte jūsu virtuālajā kafejnīcā ir mazgāta un vai tā ir gatava lietošanai nākamajam klientam. Izmantojot šo informāciju, varat pārliecināties, ka kafijas tasi neizmantojat atkārtoti, pirms tā nav mazgāta.

Ja jūs nolemjat, ka jums rūp tikai tas, vai kauss ir mazgāts, ja tas ir tukšs, varat izmantot īpašu kausa vērtību IekšējāKafija lauks, ko parasti izmanto, lai izsekotu kafijas daudzumu tasē, lai attēlotu nemazgātu tasi. Ja 473 mililitri (16 šķidruma unces) ir maksimālais kafijas daudzums jūsu lielākajā tasītē, tad IekšējāKafija parasti būtu 473. Tādējādi jūs varētu izmantot IekšējāKafija vērtība, teiksim, 500 (īpaša vērtība), lai norādītu tukšu, nemazgātu kausu:

// Avota paketē failu laukos / ex1 / CoffeeCup.java klase CoffeeCup {private int innerCoffee; public boolean isReadyForNextUse () {// Ja kafijas tase nav mazgāta, tā // nav gatava nākamajai lietošanai, ja (innerCoffee == 500) {return false; } return true; } public void setCustomerDone () {internalCoffee = 500; // ...} public void wash () {innerCoffee = 0; // ...} // ...} 

Šis kods dos Kafijas krūzīte iebilst pret vēlamo uzvedību. Šīs pieejas problēma ir tā, ka īpašās vērtības nav viegli saprotamas, un tās apgrūtina koda mainīšanu. Pat ja komentārā aprakstāt īpašas vērtības, citiem programmētājiem var būt vajadzīgs ilgāks laiks, lai saprastu, ko dara jūsu kods. Turklāt viņi, iespējams, nekad nesapratīs jūsu kodu. Viņi var nepareizi izmantot jūsu klasi vai mainīt to tā, ka ievieš kļūdu.

Piemēram, ja vēlāk kāds virtuālās kafejnīcas piedāvājumam pievieno 20 unces tasi, tad tasē būtu iespējams turēt līdz 592 mililitriem (ml) kafijas. Ja programmētājs pievieno jauno glāzes izmēru, nemanot, ka jūs lietojat 500 ml, lai norādītu, ka krūzīte ir jāmazgā, visticamāk, tiks ieviesta kļūda. Ja klients jūsu virtuālajā kafejnīcā nopirka 20 unces tasi un pēc tam paņēma lielu 92 ml lielu dzērienu, tad viņam vai viņai tasē būtu palikuši tieši 500 ml. Klients būtu šokēts un neapmierināts, kad, izdzerot tikai 92 ml, krūzīte pazuda no viņa rokas un parādījās izlietnē, gatava mazgāt. Pat ja programmētājs, veicot izmaiņas, saprata, ka izmantojat īpašu vērtību, būtu jāizvēlas cita īpaša vērtība nemazgātam atribūtam.

Labāka pieeja šai situācijai ir atsevišķs lauks, lai modelētu atsevišķu atribūtu:

// Avota paketē failu laukos / ex2 / CoffeeCup.java klase CoffeeCup {private int innerCoffee; privātas Būla vajadzības Mazgāšana; public boolean isReadyForNextUse () {// Ja kafijas tase nav mazgāta, tā // nav gatava nākamajai lietošanai return! needsWashing; } public void setCustomerDone () {needsWashing = true; // ...} public void wash () {needsWashing = false; // ...} // ...} 

Šeit IekšējāKafija lauks tiek izmantots tikai, lai modelētu kafijas daudzumu tases atribūtā. Kausa vajadzību mazgāšanas atribūtu modelē needsWashhing laukā. Šī shēma ir vieglāk saprotama nekā iepriekšējā shēma, kurā tika izmantota īpaša vērtība IekšējāKafija un netraucētu kādam paplašināt maksimālo vērtību IekšējāKafija.

Izmantojot konstantes

Vēl viens īkšķis, kas jāievēro, veidojot laukus, ir konstantu (statisko galīgo mainīgo) izmantošana nemainīgām vērtībām, kas tiek nodotas metodēm, tiek atgrieztas no tām vai tiek izmantotas metodēs. Ja metode vienā no parametriem sagaida kādu no ierobežotas nemainīgu vērtību kopas, konstantu noteikšana palīdz klienta programmētājiem padarīt skaidrāku to, kas ir jānodod šajā parametrā. Tāpat, ja metode atgriež vienu no ierobežotām vērtību kopām, konstantu deklarēšana klienta programmētājiem padara acīmredzamāku to, kas gaidāms kā izeja. Piemēram, to ir vieglāk saprast:

if (cup.getSize () == Kafijas krūze.TALL) {} 

nekā to saprast:

ja (cup.getSize () == 1) {} 

Jums vajadzētu arī definēt konstantes iekšējai lietošanai ar klases metodēm - pat ja šīs konstantes netiek izmantotas ārpus klases, tāpēc tās ir vieglāk saprast un mainīt. Izmantojot konstantes, kods kļūst elastīgāks. Ja saprotat, ka esat nepareizi aprēķinājis vērtību un neizmantojāt konstanti, jums būs jāiziet kods un jāmaina katrs grūti kodētās vērtības gadījums. Ja tomēr izmantojāt konstanti, tā būs jāmaina tikai tur, kur tā ir definēta kā konstante.

Konstanti un Java kompilators

Noderīga lieta, kas jāzina par Java kompilatoru, ir tas, ka tas izturas pret statiskajiem gala laukiem (konstantēm) atšķirīgi no cita veida laukiem. Atsauces uz statiskajiem galīgajiem mainīgajiem, kas inicializēti apkopošanas laika konstante, kompilēšanas laikā tiek atrisinātas līdz konstantas vērtības lokālai kopijai. Tas attiecas uz visu primitīvo tipu un tipa konstantēm java.lang.Strings.

Parasti, kad jūsu klase attiecas uz citu klasi - teiksim, klase java.lang.Math - Java kompilators ievieto simboliskas atsauces uz klasi Matemātika klases failā. Piemēram, ja tiek izmantota kāda jūsu klases metode Math.sin (), jūsu klases failā būs divas simboliskas atsauces uz Matemātika:

  • Viena simboliska atsauce uz klasi Matemātika
  • Viena simboliska atsauce uz Matemātika's grēks () metodi

Lai izpildītu jūsu klasē esošo kodu, uz kuru attiecas Math.sin (), JVM būtu jāielādē klase Matemātika lai atrisinātu simboliskās atsauces.

No otras puses, ja jūsu kods atsaucās tikai uz statisko galīgo klases mainīgo PI klasē deklarēts Matemātika, Java kompilators neliks simboliskas atsauces uz Matemātika klases failā. Tā vietā tas vienkārši ievietotu burtiskās vērtības kopiju Math.PI klases klases failā. Lai izpildītu kodu, kas atrodas jūsu klasē, kurā tiek izmantots Math.PI nemainīgs, JVM nevajadzētu ielādēt klasi Matemātika.

Šīs Java kompilatora funkcijas rezultāts ir tāds, ka JVM, lai izmantotu konstantes, nav jāstrādā vairāk, nekā literāru lietošanai. Priekšroka konstantēm, nevis literāļiem ir viena no nedaudzajām dizaina vadlīnijām, kas uzlabo programmas elastību, neriskējot par programmas veiktspējas pasliktināšanos.

Trīs veidu metodes

Šī raksta atlikušajā daļā tiks apspriestas metodes izstrādes metodes, kas attiecas uz datiem, kurus metode izmanto vai modificē. Šajā kontekstā es gribētu identificēt un nosaukt trīs pamatmetodes Java programmās: lietderības metode stāvokļa skata metodeun stāvokļa maiņas metode.

Lietderības metode

Lietderības metode ir klases metode, kas neizmanto un nemaina savas klases stāvokli (klases mainīgos). Šāda veida metode vienkārši nodrošina noderīgu pakalpojumu, kas saistīts ar tā objekta klasi.

Daži lietderības metožu piemēri no Java API ir:

  • (Klasē Vesels skaitlis) public static int toString (int i) - atgriež jaunu Stīga objekts, kas 10. norādē norāda norādīto veselu skaitli
  • (Klasē Matemātika) valsts statiskā dzimtā dubultā cos (dubultā a) - atgriež leņķa trigonometrisko kosinusu

Valsts skata metode

Stāvokļa skata metode ir klases vai instances metode, kas atgriež zināmu skatu uz klases vai objekta iekšējo stāvokli, nemainot šo stāvokli. (Šāda veida metode nekaunīgi neņem vērā Heisenbergas nenoteiktības principu - skatiet resursus, ja jums ir nepieciešams atsvaidzināt šo principu.) Valsts stāvokļa skata metode var vienkārši atgriezt klases vai instances mainīgā vērtību vai arī atgriezt vērtību, kas aprēķināta no vairāki klases vai instances mainīgie.

Daži stāvokļa skata metožu piemēri no Java API ir:

  • (Klasē Objekts) publiskā virkne līdz virknei () - atgriež objekta virknes attēlojumu
  • (Klasē Vesels skaitlis) publiskais baits baitsVērtība () - atgriež vērtību Vesels skaitlis objekts kā baits
  • (Klasē Stīga) public int indexOf (int ch) - atgriež indeksu norādītajā rakstzīmē pirmās parādīšanās virknē

Stāvokļa maiņas metode

Stāvokļa maiņas metode ir metode, kas var pārveidot tās klases stāvokli, kurā metode ir deklarēta, vai, ja eksemplāra metodi, objektu, uz kuru tā tiek atsaukta. Kad tiek izmantota stāvokļa maiņas metode, tā klasē vai objektā apzīmē "notikumu". Metodes kods "apstrādā" notikumu, potenciāli mainot klases vai objekta stāvokli.

Daži stāvokļa maiņas metožu piemēri no Java API ir:

  • (Klasē StringBuffer) publiskais StringBuffer papildinājums (int i) - pievieno virknes attēlojumu int arguments StringBuffer
  • (Klasē Hashtable) publiski sinhronizēta tukša notīrīšana () - notīra Hashtable lai tajā nebūtu atslēgu
  • (Klasē Vector) publiskā gala sinhronizētā anulētā addElement (objekta obj) - pievieno norādīto komponentu Vector, palielinot tā izmēru par vienu

Metodes savienojuma samazināšana līdz minimumam

Bruņojoties ar šīm lietderības, stāvokļa skata un stāvokļa maiņas metožu definīcijām, jūs esat gatavs diskusijai par metožu savienošanu.

Izstrādājot metodes, vienam no jūsu mērķiem vajadzētu būt samazināt sakabe - metodes un tās vides savstarpējās atkarības pakāpe (citas metodes, objekti un klases). Jo mazāk ir saikne starp metodi un tās vidi, jo šī metode ir neatkarīgāka un dizains ir elastīgāks.

Metodes kā datu transformatori

Lai saprastu sasaisti, tas palīdz domāt par metodēm tikai par datu pārveidotājiem. Metodes pieņem datus kā ievades datus, veic darbības ar šiem datiem un ģenerē datus kā izvadi. Metodes saistīšanas pakāpi galvenokārt nosaka tas, kur tā iegūst ievaddatus un kur ievieto izejas datus.

1. attēlā parādīts metodes kā datu transformatora grafisks attēlojums: datu plūsmas diagramma no strukturēta (nevis objektorientēta) dizaina.

Ieeja un izeja

Java metode var iegūt ievades datus no daudziem avotiem:

  • Tas var prasīt, lai zvanītājs izsaukuma brīdī norādītu savus ievaddatus kā parametrus
  • Tas var paķert datus no visiem pieejamiem klases mainīgajiem, piemēram, klases pašas klases mainīgajiem vai jebkuriem pieejamiem citas klases klases mainīgajiem
  • Ja tā ir instances metode, tā var paķert instances mainīgos no objekta, uz kuru tā tika izsaukta

Tāpat metode var izteikt savu iznākumu daudzās vietās:

  • Tas var atgriezt vērtību, vai nu primitīvu tipu, vai objekta atsauci
  • Tas var mainīt objektus, uz kuriem atsauces nodod kā parametrus
  • Tas var mainīt visus savas klases klases mainīgos vai jebkurus pieejamos citas klases klases mainīgos
  • Ja tā ir instances metode, tā var mainīt visus objekta mainīgos, uz kuriem tā tika izsaukta
  • Tas var mest izņēmumu

Ņemiet vērā, ka parametri, atgriešanās vērtības un izmesti izņēmumi nav vienīgie metožu ievades un izvades veidi, kas minēti iepriekšējos sarakstos. Gadījuma un klases mainīgos arī uzskata par ievadi un izvadi. No objektorientēta viedokļa tas var šķist neint intuitīvi, jo piekļuve Java eksemplāru un klases mainīgajiem ir "automātiska" (jums nekas nav skaidri jānodod metodei). Mēģinot novērtēt metodes savienojumu, jums jāaplūko izmantoto un koda modificēto datu veids un apjoms neatkarīgi no tā, vai koda piekļuve šiem datiem bija "automātiska".

Minimāli saistītas lietderības metodes

Vismazāk saistītā metode, kas ir iespējama Java, ir lietderības metode, kas:

  1. Ievada tikai parametrus
  2. Izteic produkciju tikai ar parametriem vai atgriešanās vērtību (vai ar izņēmuma palīdzību)
  3. Pieņem kā ievadi tikai tos datus, kas metodei faktiski nepieciešami
  4. Atgriež kā izvadi tikai datus, kas faktiski iegūti ar metodi

Laba lietderības metode

Piemēram, metode convertOzToMl () parādīts zemāk, pieņem int kā vienīgo ievadi un atgriež int kā vienīgo rezultātu:

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