Mukavan, hyvin suunnitellun ja hyvännäköisen koodin kirjoittaminen ei ole niin vaikeaa kuin miltä se näyttää. Se vaatii hieman vaivannäköä, jotta oppii tuntemaan tärkeimmät säännöt ja käyttää niitä koodissaan. Eikä kaikkea tarvitse tehdä kerralla, vaan kun tunnet olosi mukavaksi yhden asian kanssa, yritä miettiä toista, ja niin edelleen.
Rakenna vankkaa, ei typerää koodia
Aloitetaan esittelemällä alkeellisimmat säännöt, joita kutsutaan SOLID-säännöiksi. Se on termi, joka kuvaa kokoelmaa suunnitteluperiaatteita hyvän koodi jonka Robert C. Martin keksi ja miten se toimii:
S tarkoittaa yhden vastuun periaatetta
Siinä todetaan, että luokalla pitäisi olla yksi ja vain yksi syy muuttua. Toisin sanoen luokalla pitäisi olla vain yksi tehtävä, joten meidän pitäisi välttää kirjoittamasta suuria luokkia, joilla on monia vastuualueita. Jos luokkamme on tehtävä paljon asioita, jokainen niistä tulisi delegoida erillisiksi.
luokka Ilmoitus
def initialize(params)
@params = params
end
def call
EmailSender.new(message).call
end
private
def message
# jokin toteutus
end
end
O tarkoittaa avoimen/suljetun periaatetta
Sen mukaan luokan käyttäytymistä pitäisi voida laajentaa muuttamatta sitä. Toisin sanoen luokan laajentamisen pitäisi olla helppoa ilman, että siihen tehdään muutoksia. Tämä voidaan saavuttaa esimerkiksi käyttämällä strategiamallia tai koristeita.
luokka Ilmoitus
def initialize(params, sender)
@params = params
@sender = lähettäjä
end
def call
sender.call message
end
private
def viesti
# jokin toteutus
end
end
luokka EmailSender
def call(message)
# jokin toteutus
end
end
luokka SmsSender
def call(message)
# jokin toteutus
end
end
Tämän mallin avulla on mahdollista lisätä uusia lähettäjiä muuttamatta mitään koodia.
L tarkoittaa Liskovin substituutioperiaatetta.
Sen mukaan johdettujen luokkien on oltava korvattavissa perusluokillaan. Toisin sanoen samasta esi-isästä peräisin olevien luokkien käytön pitäisi olla helposti korvattavissa toisella jälkeläisellä.
luokka Logger {
info (message) {
console.info(this._prefixFor('info') + message)
}
error (message, err) {
console.error(this._prefixFor('error') + message)
if (err) {
console.error(err)
}
}
_prefixFor (type) {
// jokin toteutus
}
}
class ScepticLogger extends Logger {
info (message) {
super.info(message)
console.info(this._prefixFor('info') + 'Ja siinä kaikki mitä minulla oli sanottavaa.')
}
error (message, err) {
super.error(message, err)
console.error(this._prefixFor('error') + 'Iso juttu!')
}
}
Voimme helposti korvata luokan nimen, koska molemmilla on täsmälleen sama käyttöliittymä.
Tarkoitan rajapinnan erotteluperiaatetta
Siinä todetaan, että sinun pitäisi tehdä hienojakoisia, asiakaskohtaisia rajapintoja. Mikä on rajapinta? Se on tietyn koodin osan käyttötapa. Tämän säännön rikkominen voisi siis olla esimerkiksi luokka, jossa on liian monta metodia, tai metodi, jossa on liian monta argumenttivaihtoehtoa. Hyvä esimerkki tämän periaatteen havainnollistamiseksi on repository-kuvio, ei ainoastaan siksi, että usein laitamme yhteen luokkaan paljon metodeja, vaan myös siksi, että nämä metodit ovat alttiina riskille hyväksyä liian monta argumenttia.
# ei ole paras esimerkki tällä kertaa.
class IlmoitusVarasto
def find_all_by_ids(ids:, info:)
notifications = Notification.where(id: ids)
info ? notifications.where(type: :info) : notifications
end
end
# ja parempi
class IlmoitusVarasto
def find_all_by_ids(ids:)
Notification.where(id: ids)
end
def find_all_all_by_ids_info(ids:)
find_all_all_by_ids(ids).where(type: :info)
end
end
D tarkoittaa Dependency Inversion Principle -periaatetta.
Siinä todetaan, että sinun pitäisi tukeutua abstraktioihin, ei konkretioihin. Toisin sanoen luokan, joka käyttää toista luokkaa, ei pitäisi olla riippuvainen sen toteutuksen yksityiskohdista, vaan kaikki, mikä on tärkeää, on käyttöliittymä.
luokka Ilmoitus
def initialize(params, sender)
@params = params
@sender = lähettäjä
end
def call
sender.call message
end
private
def viesti
# jokin toteutus
end
end
Meidän tarvitsee tietää lähettäjäobjektista vain, että se tarjoaa `call`-metodin, joka odottaa viestin argumenttina.
Ei paras koodi koskaan
On myös erittäin tärkeää tietää, mitä asioita pitäisi ehdottomasti välttää koodia kirjoitettaessa, joten tässä on toinen kokoelma typeriä periaatteita, jotka tekevät koodista vaikeasti ylläpidettävää, vaikeasti testattavaa ja uudelleenkäyttöä.
S tarkoittaa Singletonia
Singletoneja pidetään usein antikuvioina, ja niitä tulisi yleensä välttää. Tämän mallin suurin ongelma on kuitenkin se, että se on eräänlainen tekosyy globaaleille muuttujille/metodeille, ja kehittäjät voivat käyttää sitä nopeasti liikaa.
T tarkoittaa tiivistä kytkentää
Se säilyy, kun muutos yhdessä moduulissa edellyttää muutoksia myös muissa sovelluksen osissa.
U tarkoittaa testaamattomuutta
Jos koodisi on hyvä, testien kirjoittamisen pitäisi kuulostaa hauskalta, ei painajaiselta.
P tarkoittaa ennenaikaista optimointia
Sana "ennenaikainen" on tässä avainasemassa, sillä jos et tarvitse sitä nyt, se on ajanhukkaa. On parempi keskittyä hyvään, puhtaaseen koodiin kuin joihinkin mikro-optimointeihin, jotka yleensä aiheuttavat monimutkaisempaa koodia.
Tarkoitan kuvaamatonta nimeämistä
Se on vaikeinta hyvän koodin kirjoittamisessa, mutta muista, että se ei ole vain muullekin joukkue mutta myös tulevaa sinua varten, joten kohtele sinua oikein 🙂 On parempi kirjoittaa menetelmälle pitkä nimi, mutta se kertoo kaiken, kuin lyhyt ja arvoituksellinen nimi.
D tarkoittaa päällekkäisyyttä
Tärkein syy koodin päällekkäisyyteen on tiukan kytkennän periaatteen noudattaminen. Jos koodisi on tiukasti kytketty, et voi käyttää sitä uudelleen ja päällekkäistä koodia syntyy, joten noudata DRY-periaatetta äläkä toista itseäsi.
Se ei ole oikeastaan tärkeää juuri nyt
Haluaisin myös mainita kaksi hyvin tärkeää asiaa, jotka usein jätetään mainitsematta. Teidän olisi pitänyt kuulla ensimmäisestä - se on YAGNI, joka tarkoittaa: ette tule tarvitsemaan sitä. Ajoittain havaitsen tämän ongelman tehdessäni koodin tarkistusta tai jopa kirjoittaessani omaa koodiani, mutta meidän pitäisi vaihtaa ajatteluamme ominaisuuden toteuttamisesta. Meidän pitäisi kirjoittaa juuri sitä koodia, jota tarvitsemme juuri tällä hetkellä, ei enempää tai vähempää. Meidän pitäisi pitää mielessä, että kaikki muuttuu hyvin nopeasti (erityisesti sovellusten vaatimukset), joten on turha ajatella, että jokin asia tulee vielä joskus tarpeeseen. Älä tuhlaa aikaasi.
En ymmärrä
Ja viimeinen asia, joka ei liene aivan itsestäänselvyys ja joka saattaa olla joillekin varsin kiistanalainen, on kuvaileva koodi. En tarkoita sillä vain oikeiden nimien käyttämistä luokille, muuttujille tai metodeille. On todella, todella hyvä, kun koko koodi on luettavissa ensi silmäyksellä. Mikä on hyvin lyhyen koodin tarkoitus, kun taas se on niin arvoituksellinen kuin se vain voi olla, eikä kukaan tiedä, mitä se tekee, paitsi sen kirjoittanut henkilö? Minun mielestäni on parempi kirjoittaa joitakin merkkejä.ehtolausekkeetjotain muuta kuin yksi sana ja sitten eilen istuu ja ihmettelee: odota, mikä on tulos, miten se tapahtui, ja niin edelleen.
const params = [
{
movies: [
{ title: 'The Shawshank Redemption' },
{ title: 'Yksi lensi yli käenpesän' } }
]
},
{
movies: [
{ title: 'Saving Private Ryan' },
{ title: 'Pulp Fiction' },
{ title: 'The Shawshank Redemption' },
]
}
]
// ensimmäinen ehdotus
function uniqueMovieTitlesFrom (params) {
const titles = params
.map(param => param.movies)
.reduce((prev, nex) => prev.concat(next))
.map(elokuva => elokuva.title)
return [...new Set(titles)]
}
// toinen ehdotus
function uniqueMovieTitlesFrom (params) {
const titles = {}
params.forEach(param => {
param.movies.forEach(movie => titles[movie.title] = true)
})
return Object.keys(titles)
}
Yhteenvetona
Kuten huomaat, muistettavia sääntöjä on paljon, mutta kuten alussa mainitsin, hienon koodin kirjoittaminen on ajan kysymys. Jos alat miettiä yhtä parannusta koodaustottumuksiisi, huomaat, että toinen hyvä sääntö seuraa, koska kaikki hyvät asiat syntyvät itsestään aivan kuten huonotkin.
Lue lisää:
Mikä on Ruby on Jets ja miten rakentaa sovellus sen avulla?
1TP53Kalenteri. Uusi Codestin projekti, joka perustuu Vue.js:ään.
Codestin viikoittainen raportti parhaista teknologia-artikkeleista. Ohjelmiston rakentaminen 50 miljoonalle yhtäaikaiselle pistorasialle (10)