Hva er en konfigurasjon Object, og hvorfor bry å bruke den?

What er en konfigurasjonsobjekt, og hvorfor bry å bruke den?
Del
Del
3
Share
Cyber ​​Monday Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av

Det er en smerte å måtte endre parameterne for en funksjon.; du må endre hver annen oppfordring til at funksjonen for å unngå feil. Men du kan komme rundt dette ved hjelp av bare én parameter: a. Konfigurasjon objekt



Slik ser det ut

Her er et dumt eksempel på en funksjon for å skape en robot:
funksjon generateRobot (armene: int, personlighet: String): Robot {var robot: robot = new Robot (); for (var i: int = 0; i < våpen; i ++) {//oppretter arm og legge den til robot} if (personlighet == "onde") {robot.commands = ". Destroy menneskeheten"; } Else {robot.commands = "Bake cookies." } Avkastning robot;} generateRobot (2, "onde");

Nå, her er den samme eksempel bruker en konfigurasjon objekt:
funksjon generateRobot (conf: Object): Robot {var robot: robot = new Robot ( ); for (var i: int = 0; i < conf.arms; i ++) ". Destroy menneskeheten" {//oppretter arm og legge den til roboten} if (conf.personality == "onde") {robot.commands =; } Else {robot.commands = "Bake cookies." } Avkastning robot;} generateRobot ({armer: 2, personlighet: "onde"});

Jeg har uthevet linjene som krever endring; du kan se at det er ikke mye forskjell.



Hvorfor bry seg?

Så hvis det er knapt noen forskjell, hvorfor skulle vi bry gjør det den andre veien? Tross alt, det faktisk gjør funksjonen litt vanskeligere å bruke; mens før vår IDE ville være i stand til å gi oss denne informasjonen om parameterne funksjonen forventet:

... nå kan det bare gi oss dette:

Tenk deg at du vil legge til et par mer parametere: en angivelse av materiale å bruke, og en annen for å spesifisere hvilken farge sin laser skal være. Det er ikke så vanskelig, i begge tilfeller:
funksjon generateRobot (armer: int, personlighet: String, materiale: String, laserColor: String): Robot {var robot: robot = new Robot (); for (var i: int = 0; i < våpen; i ++) {//oppretter arm og legge den til robot} if (personlighet == "onde") {robot.commands = ". Destroy menneskeheten"; } Else {robot.commands = "Bake cookies." } Switch (material) {case "tre": //tre robot break; case "stål": default: //stål robot break; } Robot.laser = new Laser (); robot.laser.color = laserColor; returnere robot;} generateRobot (2, "onde", "stål", "rød"); funksjon generateRobot (conf: Object): Robot {var robot: robot = new Robot (); for (var i: int = 0; i < conf.arms; i ++) ". Destroy menneskeheten" {//oppretter arm og legge den til roboten} if (conf.personality == "onde") {robot.commands =; } Else {robot.commands = "Bake cookies." } Switch (conf.material) {case "tre": //tre robot break; case "stål": default: //stål robot break; } Robot.laser = new Laser (); robot.laser.color = conf.laserColor; returnere robot;} generateRobot ({armene: 2, personlighet: "ondt", materiale: "stål", laserColor: "rød"});

Så langt fortsatt ikke mye av en forskjell. Hva hvis du vil at roboter til alle har røde lasere som standard? Simple igjen. Uten en konfigurasjonsobjekt, du trenger bare å endre metoden signaturen (funksjonen linje), og deretter kan du fjerne den siste argument fra funksjonen samtale:
funksjon generateRobot (armene: int, personlighet: String, materiale: String, laserColor: String = "red"): Robot {//dette er alt det samme} generateRobot (2, sant, "stål"); //Jeg fjernet det siste argumentet

Med en konfigurasjon objekt, det er litt mer komplisert - men ikke mye:
funksjon generateRobot (conf: Object): Robot {if (! Conf.laserColor) {conf.laserColor = " rød"; } Var robot: robot = new Robot (); for (var i: int = 0; i < conf.arms; i ++) ". Destroy menneskeheten" {//oppretter arm og legge den til roboten} if (conf.personality == "onde") {robot.commands =; } Else {robot.commands = "Bake cookies." } Switch (conf.material) {case "tre": //tre robot break; case "stål": default: //stål robot break; } Robot.laser = new Laser (); robot.laser.color = conf.laserColor; returnere robot;} generateRobot ({armene: 2, personlighet: "ondt", materiale: "stål"}); //Jeg fjernet det siste argumentet

OK. Nå antar du finner ut at du setter nesten alle dine roboter til å være onde (jeg mener, hvorfor ikke?), Så det er faktisk litt vondt å skrive "onde" som en parameter hver gang. Naturligvis, du ønsker å sette "onde" som standard -. Men du ikke
ønsker å sette en standard material

Den eneste måten du kan gjøre dette, med en vanlig sett funksjonsparametre, er å bytte rekkefølgen på personlighet og materialparametere:
funksjon generateRobot (armene: int, materiale: String, personlighet: String = "ondt", laserColor: String = "red"): Robot {

Ah, men nå må du bytte rekkefølgen på argumentene runde på hver enkelt funksjon call of generateRobot (2, "onde", "stål"); //ikke lenger fungerer

En konfigurasjon objektet ikke gir deg dette problemet. Sjekk det ut:
funksjon generateRobot (conf: Object): Robot {if (! Conf.laserColor) {conf.laserColor = "red"; } If (conf.personality!) {Conf.personality = "onde"} //dette er alt det samme} generateRobot ({armer: 2, materiale: "stål"}); //ingen "personlighet" parameter? ikke noe problem!

Kult! All din gamle generateRobot () funksjonskall vil fortsette å jobbe, men du kan opprette nye samtaler som ikke gidder å spesifisere personlighet

Du kan selv bestemme seg for å kvitte seg med personligheten parameter helt.
Funksjon generateRobot (conf: Object): Robot {if (conf.laserColor!) {conf.laserColor = "red"; } If (conf.personality!) {Conf.personality = "onde"} Var robot: robot = new Robot (); for (var i: int = 0; i < conf.arms; i ++) {//oppretter arm og legge den til robot} robot.commands = ". Destroy menneskeheten"; bryteren (conf.material) {case "tre": //tre robot break; case "stål": default: //stål robot break; } Robot.laser = new Laser (); robot.laser.color = conf.laserColor; returnere robot;}

Ovennevnte versjon av funksjonen refererer ikke til conf.personality i det hele tatt - men du vil ikke få en feilmelding hvis du fortsatt har samtaler som dette:
generateRobot ({våpen: 2, personlighet: "onde", materiale: "stål"});

Selvfølgelig, du kan få noen forvirrede brukere hvis du har samtaler som dette:
generateRobot ({armer: 2, personlighet: "good", materiale: "stål"});

... siden alle roboter er nå onde. Men minst koden vil kompilere

Av samme grunn, kan du endre rekkefølgen på argumentene uten det mattering i det hele tatt, og selv legge inn nye parametere som ikke gjør noe ennå.
generateRobot ({materiale: "stål", laserColor: "grønn", armer: 2, stemme: ". Mr T"});



Å gjøre det enklere å sette Defaults

Koden for sette standard er lett å forstå så langt, men kommer til å være veldig irriterende å forlenge hvis vi trenger å ha mange parametere:
if (! conf.laserColor) {conf.laserColor = "red"; } If (conf.personality!) {Conf.personality = "onde"}

La oss skrive litt mer generell kode for å takle det:
Var mislighold: Object = {laserColor: rød, personlighet: "onde"} for (var nøkkelen: String i mislighold) (! conf [nøkkel]) {if {conf [nøkkel] = mislighold [key]; }}

Som for loop kan være litt forvirrende, så jeg vil bryte det ned. Først se på dette:
for (var nøkkelen: String i mislighold) {trace (nøkkel); }

Dette er en for ... i loop, som vil sende ut navnene på tastene inne standardobjektet:
laserColorpersonality

Neste, se på denne linjen:
trace (defaults ["laserColor "]);

Dette vil produksjonen rød - det er det samme som å skrive trace (defaults.laserColor)

Etter på fra det, se på dette eksempelet:
Var eksempel: Object = {demo. : "test"}; trace (f.eks ["demo"]); trace (f.eks ["foo"]);

Hva tror du dette vil produksjonen

Vel, eksempel ["demo"? ] er den samme som example.demo, som tilsvarer "test". Men example.foo ikke eksisterer, så eksempel ["foo"] vil returnere null. Dette betyr at f.eks ["foo"] (merk utropstegn) vil være tilsvarende sant

Sett at alle sammen, og du bør være i stand til å forstå hvorfor denne koden fungerer:!.
Var mislighold : Object = {laserColor: rød, personlighet: "onde"} for (var nøkkelen: String i mislighold) (! conf [key]) {if {conf [key] = mislighold [key]; }}

Gi meg et rop i kommentarfeltet hvis du trenger en hånd

I Want More

For en enda raskere versjon, prøv dette:!
Funksjon generateRobot (conf : Object = null): Robot {var conf: Object = conf || {}; Var mislighold: Object = {laserColor: rød, personlighet: "onde"} for (var nøkkelen: String i mislighold) {conf [key] = conf [key] || mislighold [nøkkel]; }

Endringen i Linje 1 (og ny linje 2) betyr at selv de conf objektet selv er valgfritt, så du kan bare ringe generateRobot (). (Selvfølgelig, må du endre koden for å håndtere de verdier som i dag ikke har mislighold.)



Hjelpe IDE hjelpen du

Som jeg nevnte ovenfor , IDE kan ikke gi deg noen tips om hvilke parameter en funksjon forventer, hvis det funksjonen bruker en konfigurasjon objekt. Dette er en stor ulempe, da det kan gjøre koden veldig vanskelig å bruke; du må huske hvilke parametere gå i conf objekt, samt alle navnene deres og typer

Men vi kan likevel vise denne informasjonen til koder når det trengs.; vi må bare gjøre det manuelt, som så: Twitter /** * Lag en robot, basert på parametere som er gitt. *param Conf Configuration-objektet. Forventer: * armene (int) Antall armer robot skal ha. * Personlighet (String) Personlighet av robot. Kan være "onde" eller "gode". Standard er "onde". * Materiale (String) Hva roboten skal være laget av. Kan være "stål" eller "tre" på dette tidspunktet. * LaserColor (String) Color av robotens laser. Standard er "rød". * Stemme (String) Vokal stylings av roboten. Foreløpig ikke implementert. *return Den ferdige roboten. * /Funksjon generateRobot (conf: Object): Robot {//}

Nå, hvis jeg begynner å skrive et kall til denne funksjonen i FlashDevelop (min IDE valg), ser jeg dette:

Sure , er det litt av en smerte å holde dette manuelt oppdatert, men i mange tilfeller er det verdt det.



Konklusjon

Jeg skal ikke hevde at du bør bruke en konfigurasjon objekt for hver enkelt funksjon
du lager fra nå av; bare tenke på det som en annen nyttig verktøy i arsenalet ditt.

Personlig synes jeg det er en spesielt nyttig mønster når jeg bygger det første utkastet av noen sett med klasser som alle må arbeide sammen. Den ekstra fleksibiliteten av en conf gir meg så mye mer fleksibilitet, frigjør meg opp til zip rundt alle de forskjellige funksjonene og endre hvordan de kaller hverandre, uten å bekymre deg for å bryte koden ved å sette inn eller ta ut en parameter.

Husk fordelene:

Det er lett å legge til og fjerne parametre (i begge ender)

Det er enkelt å sette standardverdier

Du trenger ikke.. å bekymre seg om rekkefølgen av parametrene

Det er ulemper med å bruke enkle gjenstander som jeg har, men -. særlig hvis du gjør det i et prosjekt som er forbi prototypestadiet. Sjekk ut de flotte kommentarene nedenfor for mer informasjon! Anmeldelser