Slik Begynner Du Å Skrive ‘Kompleks’ Kode
Dette er et innlegg om å tenke på koden du skriver. Alt som finnes her, er min mening, og du bør alltid vurdere gyldigheten av mine meninger ved å sammenligne dem med bedre! Språket jeg bruker Er Javascript. En forutsetning for å forstå denne artikkelen er å vite mellomliggende Javascript og kjennskap til noen objektorienterte konsepter. Dette innlegget er inspirert av kapittel 9 I Cristina Lopes ‘utmerkede bok” Øvelser I Programmerings Stil”.
et veldig vanlig mønster i kode er—
- Definer et enkelt objekt
var store_item = {
name : 'wonderball'
}
2. Så for å få den klar til å vises på en nettside, kjører vi hver eiendom gjennom noen funksjoner.
addExclamationPoint(store_item);
capitalizeName(store_item);function addExclamationPoint(item) {
item.name = item.name + '!';
}function capitalizeName(item) {
// some code to capitalize item.name, cut out for brevity.
}
Og dette er hvordan vi ofte får data klar til å vise. Nå som vår store_item har et kapitalisert navn og et utropstegn, kan vi vise det på vår nettside ikke noe problem. Hvis det er en tredje ting vi trenger å gjøre, vil vi bare skrive en tredje funksjon for å transformere dataene, og passere elementet som vanlig.
det større, store bildemønsteret vi har laget her er:
Det er noen fancy vilkår for denne typen programmering som ‘prosedyre’ eller ‘imperativ’, men jeg vil kalle det et annet begrep: ‘enkelt’. Det er veldig enkel programmering. Det er den typen programmering alle lærer først. For programmer av liten skala er det absolutt den beste måten å programmere, fordi mennesker er gode til å følge alt fra 1 til 10 logiske trinn ganske bra.
når programmet blir tilstrekkelig stort (over 10 transformasjoner før dataene vises), eller en funksjon endrer mange dataobjekter (mer enn 2), eller vi har mange hvis setninger forårsaker forgreningslogikk, blir denne enkle programmeringen i stedet et rot.
De fleste hvert prosjekt eller stykke kode blir rotete. Det meste av programmering er faktisk kodere som kommer opp med måter å unngå å gjøre et rot, ikke løsninger på det faktiske problemet med å vise dataene. Arbeidet med programmering er å lære å skrive kode på en slik måte at vi kan bruke 100 av transformasjoner på 100 av biter av data og gjøre det ‘ikke et rot’.
nå, la meg introdusere deg til en stor forandring i mønsteret ovenfor, og vurder at det jeg skal vise deg er det første skrittet for å bli en mer avansert koder fordi det bryter deg ut av ‘enkel’ koding. Det introduserer deg til nye måter å tenke på hvordan du gjør en enkel ting som å endre noen data for en nettside. Objektet vil nå ha sin egen funksjon kalt ‘bind’, og den funksjonen vil være ansvarlig for å transformere dataene.
var store_item = {
name: 'wonderball',
bind: function(func) {
this.name = func(this.name);
return this;
}
}// Here are two functions I'll use to transform the store_item.name, each one now just takes a name and modifies it, neither function has any clue what properties it's changing in store_item anymore.function capitalize(name) {
return name.replace(/\w\S*/g, function(txt) {
return txt.charAt(0).toUpperCase() +
txt.substr(1).toLowerCase();
});
}function addExclamationPoint(name) {
return name + '!';
}store_item.bind(addExclamationPoint).bind(capitalize);
denne løsningen oppfører seg akkurat som den opprinnelige ‘enkle’ koden ovenfor, men det virker mer komplisert, hvorfor? Fordi for den enkle oppgaven vi har, er det overkill, men hva er handel offs av denne kompleksiteten?
for å svare på det, la oss snakke om hva som er annerledes:
- Vi har denne galne, rare, ‘bind’ – funksjonen, som tar som et argument, ikke en ny verdi for navn,men i stedet en annen funksjon, si hva nå?
- funksjonene kapitaliser og addExclamationPoint er forskjellige, nå ringer de ikke item.name direkte lenger.
- vi setter ikke navn med en ‘ = ‘ lenger, vi bruker i stedet denne rare store_item.bind (function_name), syntaks i stedet.
med disse tre forskjellene må vi nå spørre oss selv, er denne endringen bedre? Kanskje ikke hvis prosjektet forblir så lite. Kanskje ja hvis prosjektet blir mye større.
nøkkelendringen er at store_item-objektet nå er ansvarlig for å håndtere tilstanden via bind-funksjonen. Selvfølgelig hvis du ønsket, kan du direkte endre store_item.name, men objektet skriker praktisk talt: “Hei, bruk min bind-funksjon for å forandre meg !”.
men nå er det lett å se et mønster der flere store_items hver administrere sin egen tilstand med sine egne .bind funksjon:
// Three store items, each one with a different state.store_item1.bind(addExclamationPoint).bind(capitalize); //Wonderball!store_item2.bind(capitalize);
//Wonderballstore_item3.bind(addExclamationPoint);
//wonderball!
Vi kan lage 100 store_item og administrere statens ganske enkelt. Alt vi trenger å gjøre er å skrive en funksjon som bare har en returverdi og bruke objektets .bind funksjon.
magien i dette mønsteret er i bind-funksjonen, så la oss utforske det litt mer nå.
// 1. First define the function, and have it take as an argument another function. Taking a function as an argument, instead of data is the core change here. bind: function(func) { // 2. This second line is the secret sauce, it will run the function you passed in with 'this.name' as an argument, and then assign whatever value is returned to this.name. Mull this over. this.name = func(this.name);// 3. Finally, return 'this'. You don't have to have this step in here, but returning 'this' is what allows .bind chainging to happen (.e.g. doing .bind().bind() vs .bind(); .bind();) return this;
}
så der har du det, vi har gjort koden vår mer kompleks, men nå har vi noen nye fordeler:
- et objekt endrer nå sin egen tilstand, og det kan gjøre det betydelig på bare en linje.
- funksjonene vi har skrevet er renere, de endrer ikke objektegenskaper som i eksemplet ovenfor, de tar bare en inngang og returnerer en utgang.
- vi vet at når vi endrer et objekts tilstand, vil funksjonene vi bruker sannsynligvis ikke endre noe annet objekts tilstand ved et uhell
Men Vi har også noen ulemper:
- koden din er definitivt mindre intuitiv for en ny comer nå.
- for et lite nettsted er denne koden altfor kompleks.
så hva er den endelige dommen, er denne måten bedre? Verre? Mer forvirrende? (I begynnelsen, ja.) Alle disse spørsmålene er åpne, men jeg kan si en ting sikkert, å vurdere og forstå mønstre som dette er en del av å lære Javascript og vokse som en koder. Kontinuerlig bruk av den ‘enkle’ måten å kode på for å løse problemer blir uholdbar etter en stund. Hvis du tar deg tid til å lære mer ‘komplekse’ måter å gjøre ting mange gode ting skje: din evne til å tenke lateralt åpner opp, du kan lese flere ulike typer kode, og du øker måtene du kan tenke på å løse problemer. Kanskje det er den virkelige fordelen med å lære dette og andre mønstre.