portaldacalheta.pt
  • Põhiline
  • Tooteinimesed Ja Meeskonnad
  • Ux Disain
  • Protsess Ja Tööriistad
  • Andmeteadus Ja Andmebaasid
Tagumine Ots

Ehitage tavaliste vanade rubiinobjektidega elegantsete rööbaste komponente



Teie veebisait liigub edasi ja te kasvate kiiresti. Ruby / Rails on teie parim programmeerimisvõimalus. Teie meeskond on suurem ja olete juba lahkunud kontseptsioonist 'paksud mudelid, õhukesed juhid' ( paksud mudelid, kõhnad kontrollerid ) kui teie Railsi rakenduste kujundusstiil. Kuid te ei soovi ikkagi Railsi kasutamist lõpetada.

Pole probleemi. Täna arutame, kuidas kasutada OOP-i parimaid tavasid, et muuta oma kood puhtamaks, eraldatumaks ja eraldatumaks.



Kas tasub oma rakendust ümber teha?

Alustuseks uurime, kuidas peaksite otsustama, kas teie taotlus sobib refaktoriks.



Siin on loetelu mõõdikutest ja küsimustest, mida ma tavaliselt endalt küsin, et teha kindlaks, kas minu koodid vajavad refrakteerimist või mitte.

  • Aeglased katseüksused. PORO katseüksused töötavad tavaliselt kiiresti, hästi eraldatud koodidega, nii et aeglaselt kulgevad testid võivad sageli olla halva ülesehituse või liialt seotud kohustuste näitajaks.
  • FAT-mudelid või kontrollerid. Mudel või kontroller, millel on üle 200 koodiread ( KOHT ) see on üldiselt hea kandidaat refaktoreerimiseks.
  • Liiga pikk koodibaas. Kui teil on ERB / ​​HTML / HAML rohkem kui 30 000-ga KOHT või Ruby lähtekood (ilma GEMid ) enam kui 50 000-ga KOHT , on suur tõenäosus, et peate end refrakteerima.

Proovige kasutada midagi sellist, et teada saada, mitu rida Ruby lähtekoodi teil on:



find app -iname '*.rb' -type f -exec cat {} ;| wc -l

See käsk otsib kõiki rakenduse / app kaustas laiendiga .rb laiendatud faile (rubiinfailid) ja seejärel printib ridade arvu. Pange tähele, et see arv on ainult hinnanguline, kuna selle summa hulka lisatakse kommentaariread.



Teine täpsem ja informatiivsem võimalus on ülesande kasutamine reha stats Rails, mis pakub kiiret kokkuvõtet koodiridadest, klasside arvust, meetodite arvust, meetodite suhtest klassidesse ja koodiridade suhtest meetodi kohta:

*bundle exec rake stats* +----------------------+-------+-----+-------+---------+-----+-------+ | Nombre | Líneas | LOC | Clase | Método | M/C | LOC/M | +----------------------+-------+-----+-------+---------+-----+-------+ | Controladores | 195 | 153 | 6 | 18 | 3 | 6 | | Helpers | 14 | 13 | 0 | 2 | 0 | 4 | | Modelos | 120 | 84 | 5 | 12 | 2 | 5 | | Mailers | 0 | 0 | 0 | 0 | 0 | 0 | | Javascripts | 45 | 12 | 0 | 3 | 0 | 2 | | Bibliotecas | 0 | 0 | 0 | 0 | 0 | 0 | | Controlador specs | 106 | 75 | 0 | 0 | 0 | 0 | | Helper specs | 15 | 4 | 0 | 0 | 0 | 0 | | Modelo specs | 238 | 182 | 0 | 0 | 0 | 0 | | Petición specs | 699 | 489 | 0 | 14 | 0 | 32 | | Routing specs | 35 | 26 | 0 | 0 | 0 | 0 | | Vista specs | 5 | 4 | 0 | 0 | 0 | 0 | +----------------------+-------+-----+-------+---------+-----+-------+ | Total | 1472 |1042 | 11 | 49 | 4 | 19 | +----------------------+-------+-----+-------+---------+-----+-------+ Código LOC: 262 Prueba LOC: 780 Ratio Código a Prueba: 1:3.0
  • Kas ma saan oma koodibaasist välja tuua korduvaid mustreid?

Eraldamine tegevuses

Alustame reaalsest elust.



Oletame, et me tahame kirjutada rakenduse, mis jälgib sörkjooksjate ilma; Pealehel näeb kasutaja sisestatud aegu.



Igal ajakirjel on kuupäev, vahemaa, kestus ja asjakohane täiendav teave oleku kohta (nt ilm, maastiku tüüp jne) ning keskmine kiirus, mida saab vajadusel arvutada.

Vajame aruannet, mis näitab keskmist kiirust ja vahemaad nädalas. Kui keskmine kiirus sissepääsu juures on suurem kui keskmine kiirus kokku, teavitame kasutajat SMS-iga (selle näite puhul kasutame Nexmo RESTful API SMS-i saatmiseks).



Pealeht võimaldab teil valida sörkjooksu kauguse, kuupäeva ja kellaaja, et luua sarnane kirje:

mis on Kreeka kriis

Meil on ka estadísticas leht, mis on põhimõtteliselt iganädalane aruanne, mis sisaldab nädala keskmist kiirust ja läbitud vahemaad.

  • Näidist näete veebis siin .

Kood

aplicación Kataloogistruktuur näeb välja selline:

⇒ tree . ├── assets │ └── ... ├── controllers │ ├── application_controller.rb │ ├── entries_controller.rb │ └── statistics_controller.rb ├── helpers │ ├── application_helper.rb │ ├── entries_helper.rb │ └── statistics_helper.rb ├── mailers ├── models │ ├── entry.rb │ └── user.rb └── views ├── devise │ └── ... ├── entries │ ├── _entry.html.erb │ ├── _form.html.erb │ └── index.html.erb ├── layouts │ └── application.html.erb └── statistics └── index.html.erb

Ma ei arutle mudeli Usuario üle kuna see pole midagi erakordset, kuna me kasutame seda koos Moto autentimise rakendamiseks.

Mis puudutab Entrada mudelit, sisaldab see meie rakenduse äriloogikat.

Iga Entrada kuulub a Usuario.

Kinnitame järgmiste atribuutide olemasolu iga sisendi jaoks distancia, períodode_tiempo, fecha_hora ja estatus.

Iga kord, kui loome kirje, võrdleme kasutaja keskmist kiirust kõigi süsteemi kasutajate keskmisega ja teavitame kasutajat SMS-iga, kasutades Nexmo (Me ei aruta, kuidas Nexmo teeki kasutatakse, kuigi tahtsin näidata juhtumit, kus kasutame välist teeki).

  • Põhisisu proov

Pange tähele, et Entrada mudel sisaldab enamat kui ainult äriloogikat. Samuti tegeleb see mõne kinnitamise ja kõnega.

entries_controller.rb omab aktsiaid JUUR peamine (ehkki värskenduseta). EntriesController#index saab praeguse kasutaja kirjed ja sorteerib kirjed loomise kuupäeva järgi, samal ajal kui EntriesController#create looge uus kirje. Ei ole vaja arutada EntriesController#destroy ilmset ega vastutust :

  • Põhisisu proov

Kuigi statistics_controller.rb vastutab nädalaaruande arvutamise eest StatisticsController#index saab sisselogitud kasutaja kirjed ja rühmitab need nädala kaupa, kasutades #group_by mis on klassis Loendamatu rööbastes. Seejärel proovige tulemusi privaatsete meetodite abil kaunistada.

  • Põhisisu proov

Me ei aruta siin vaateid palju, kuna lähtekood on iseenesestmõistetav.

Allpool on vaade sisseloginud kasutaja (index.html.erb) kirjete loetlemiseks. Seda mustrit kasutatakse indeksi toimingu (meetodi) tulemuste kuvamiseks sisendkäitluses:

  • Põhisisu proov

Pange tähele, et kasutame render @entries Partialid, et viia jagatud kood osaliseks mustriks _entry.html.erb et saaksime oma koodi säilitada KUIV ja korduvkasutatavad:

  • Põhisisu proov

Sama kehtib ka _forma osaline. Selle asemel, et kasutada sama koodi (uute ja muudetud) toimingutega, loome korduvkasutatava osalise vormi:

  • Põhisisu proov

Nädalase aruande lehe vaate osas statistics/index.html.erb näitab statistikat ja aruandeid kasutaja iganädalaste tegevuste kohta, rühmitades mõned kirjed:

  • Põhisisu proov

Ja lõpuks, abistaja sisendite puhul sisaldab entries_helper.rb abistajad readable_time_period ja readable_speed mis peaks atribuute hõlpsamini lugema:

node.js ekspress rest api näide
  • Põhisisu proov

Siiani pole midagi liiga keerulist.

Enamik teist võib väita, et selle ümbertegemine on põhimõttega vastuolus KISS ja see muudab süsteemi keerukamaks.

Kas see rakendus tuleb siis tõesti ümber teha?

Absoluutselt ei , kuid kaalume seda ainult valimi eesmärgil.

Lõppude lõpuks, kui vaatate järgmist jaotist ja omadusi, mis näitavad, et rakendus vajab taastamist, saab ilmseks, et meie näites toodud rakendus ei ole sobiv refaktoreerimise kandidaat.

Eluring

Alustame struktuurimustri selgitamisest MVC rööbastes.

Tavaliselt algab see otsingumootorist, tehes sellise päringu nagu https://www.toptal.com/jogging/show/1.

Veebiserver võtab päringu vastu ja kasutab rutas määratleda, mida controlador kasutamine.

Kontrollerid analüüsivad kasutaja päringuid, andmeedastust, küpsiseid, seansse jne ja analüüsivad seejärel modelo saada andmeid.

modelos Need on rubiiniklassid, mis räägivad andmebaasiga, salvestavad ja kinnitavad andmeid, täidavad äriloogikat ja teevad rasket tõsta. Vaated on need, mida kasutaja näeb: HTML, CSS, XML, Javascript, JSON.

Kui tahame näidata Railsi elutsüklitaotluse järjestust, näeks see välja järgmine:

Rööpad eraldavad MVC elutsükli

Mida ma tahan saavutada, on lisada rohkem abstraktsioone, kasutades PORO-sid, ja muuta muster toimingutega create/update järgmiseks:

Rööbaste skeem loob vormi

Ja midagi sarnast toimingute jaoks list/show :

Rööbaste skeemiloendi päring

POROs sisalduvate abstraktsioonide lisamisega tagame vastutuse täieliku lahususe HAIGE , midagi, mida Rails täielikult ei valda.

Suunised

Uue kujunduse saavutamiseks kasutan allolevaid juhiseid, kuid pidage meeles, et need pole reeglid, mida peate tähele järgima. Mõelge neile kui paindlikele juhistele, mis muudavad taastamise lihtsamaks.

  • ActiveRecordi mudelid võivad sisaldada seoseid ja konstante, kuid mitte midagi muud. See tähendab, et ei toimu kõnesid (kasutage teenuse objekte ja lisage sinna kõned) ega valideerimisi (kasutamine Vormi objektid lisada mudeli nimed ja valideerimised).

  • Hoidke kontrollereid õhukeste kihtidena ja helistage alati teenuse objektidele. Mõni teist võib küsida, miks peaks kontrollereid kasutama, kui tahame loogikat sisaldavaid teenuseobjekte pidevalt kutsuda? Kontrollerid on hea koht marsruutimine HTTP, parameetrite parsimine, autentimine, sisuline läbirääkimine, õige teenuse või redaktori objekti kutsumine, erandite püüdmine, vastuste vormindamine ja õige HTTP-koodi oleku tagastamine.

  • Teenused peaksid objektidele helistama Päring ja ärge hoidke olekut. Kasutage klassiväliseid eksemplare. Avalikke meetodeid peab olema salvestatud väga vähe HAIGE .
  • Päringud tuleks teha esemetega päring . Objekti meetodid Päring peab tagastama objekti, a räsi või massiiv , kuid mitte ActiveRecordi seost.

  • Vältige kasutamist Abistajad , paremini kasutada dekoraatoreid. Miks? Ühine raskus abistajad Railsis on see, et neid saab muuta hunnikuks mitte- OO , mis jagavad ruuminime ja kattuvad üksteisega. Kuid see on palju hullem, et mitte see, et te ei saa polümorfismi kasutada abistajad Rööpad - pakkudes erinevat rakendust erinevatele kontekstidele või tüüpidele ning möödaminnes või alamklassifitseerides abilisi. Ma arvan, et sellised abistaja rööbastes tuleks neid tavaliselt kasutada kasulike meetodite jaoks, mitte konkreetsete kasutusviiside jaoks; kuidas vormindada mis tahes esitlusloogika mudeli atribuute. Hoidke need kerged ja hõlpsasti jälgitavad. Kaunistajad / delegaadid paremad. ** Miks? Lõppude lõpuks näivad mured olevat Railsi osa ja need võivad kuivada ( KUIV ) kood, kui seda jagatakse mitme mudeli vahel. Suurem probleem on aga see, et mured ei muuda mudeli objekti sidusamaks. Ainult kood on paremini korraldatud. Teisisõnu, mudeli API-l pole tegelikke muudatusi.

  • Proovige välja tõmmata Väärtuslikud esemed mudelitest hoida oma kood puhtamana ja grupiga seotud atribuudid.

  • Iga vaate jaoks edastage alati eksemplari muutuja.

Refactorizar

Enne alustamist tahan midagi muud arutada. Kui refaktoreerimine algab, mõtlete tavaliselt: 'Kas see on hea refrakteerimine?'

Kui tunnete, et eraldate või eraldate rohkem kohustusi (isegi kui see tähendab rohkem koodi ja uute failide lisamist), on see hea. Lõppude lõpuks on rakenduse eraldamine väga hea tava ja see lihtsustab meil korraliku ühikutesti tegemist.

Ma ei hakka arutama asju, nagu näiteks loogika liikumine kontrolleritelt mudelitele, kuna eeldan, et teete seda ja teil on Railsi (tavaliselt Skinny Controller ja FAT mudel) mugav.

Selle artikli kokkuvõtlikkuse huvides ei hakka ma arutama, kuidas testida, kuid see ei tähenda, et te ei peaks testima.

Vastupidi, peaksite alusta alati testiga enne edasiliikumist veendumaks, et asjad sujuvad. See on midagi nõutud, eriti refrakteerimisel.

Seejärel saame muudatusi rakendada ja veenduda, et testid läbiksid koodi asjakohased osad.

Väljavõte väärtuslikest

Esiteks, mis on väärtuslik objekt?

Martin Fowler Seletama:

Väärtusobjekt on väike objekt, näiteks raha- või kuupäevavahemiku objekt. Nende peamine omadus on see, et nad järgivad väärtussemantikat, mitte referentssemantikat.

Mõnikord võite sattuda olukorda, kus mõiste väärib oma abstraktsiooni ja kus selle võrdsus ei põhine väärtustel, vaid identiteedil. Selle näiteks võib olla: Ruby's Date, URI ja Pathname. Väärtusliku objekti (või domeenimudeli) väljavõtmine on suur mugavus.

Miks vaeva näha?

Väärtusobjekti üks suur eelis on see, et need aitavad teie koodis ilmekust saavutada. Teie kood kipub olema selgem või vähemalt nii võib see olla, kui teil on head nimetamistavad. Kuna väärtusobjekt on abstraktsioon, toob see kaasa selgemad koodid ja vähem vigu.

Teine kasu on muutumatus . Esemete muutumatus on väga oluline. Kui me salvestame teatud andmekogumeid, mida saab väärtusobjektis kasutada, ei meeldi mulle tavaliselt andmetega manipuleerimine.

Millal see kasulik on?

Sellele küsimusele pole täiuslikku vastust. Tehke seda, mis on teile parim ja mis on antud olukorras kõige mõistlikum.

Lisaks sellele on mõned juhised, mida kasutan selle otsuse tegemisel.

Kui arvate, et rühm meetodeid on omavahel seotud, on väärisesemed kallimad. See väljendusrikkus tähendab, et väärtusobjekt peaks tähistama eristavat andmekogumit, mille teie keskmine arendaja saab tuletada lihtsalt objekti nime vaadates.

veebisaidid, mis kasutavad gestalt põhimõtteid

Kuidas seda teha?

Väärisesemed peaksid järgima teatavaid reegleid:

  • Väärisesemetel peaks olema mitu atribuuti.
  • Atribuudid peaksid olema muutumatud kogu objekti elutsükli vältel.
  • Võrdsuse määravad objekti atribuudid.

Meie näites loome atribuutide EntryStatus abstraktseks väärtusobjekti Entry#status_weather ja Entry#status_landform oma klassi, mis näeb välja selline:

  • Põhisisu proov

Märkus. See on lihtsalt PORO (tavaline vana rubiinobjekt), seda ei pärita ActiveRecord::Base Oleme oma atribuutide jaoks määranud lugeja meetodid ja määrame need käivitamisel. Samuti kasutame objektide sobitamiseks meetodi () abil võrreldavat segu.

Saame mudelit muuta Entry meie loodud väärtusobjekti kasutamiseks:

  • Põhisisu proov

Samuti saame modifitseerida meetodit EntryController#create uue väärtuse objekti vastavalt kasutamiseks:

  • Põhisisu proov

Paki välja teenuse objektid

Mis on teenuse objekt?

Teenuse objekti ülesandeks on koodi hoidmine äriloogika kindlas ruumis. Erinevalt stiilist 'Paks mudel' , kus väike arv objekte sisaldab kogu vajaliku loogika jaoks palju-palju meetodeid, tulemuseks on teenuseobjektide kasutamine paljudes klassides, millest kõigil on ainulaadne eesmärk.

Miks? Mis on selle eelised?

  • Lahku tõmbama. Teenuseobjektid aitavad teil objektide vahel rohkem isoleerida.

  • Nähtavus. Teenuse objektid (kui neil on õige nimi) näitavad, mida rakendus teeb. Võin teenuste kataloogist läbi vaadata, et näha, milliseid võimalusi rakendus pakub.

  • Puhastage mudeleid ja draivereid. Kontrollerid lülitavad taotluse sisse ( params , seanss, küpsised) edastab see argumentides teenusele ja suunab või jätab need sõltuvalt teenuse vastusest. Kui mudelid tegelevad ainult assotsiatsioonide ja püsivusega. Toetaks koodi ekstraktimist kontrolleritelt / mudelitelt teenuse objektidele HAIGE ja see eraldaks koodi veelgi. Mudeli vastutus peaks tegelema ainult seostega ja salvestama / kustutama kirjeid, samas kui teenuse objektil oleks ainult üks vastutus ( HAIGE ). See toob kaasa parema disaini ja paremad testimisüksused.
  • KUIV ja nõustu muudatusega. Teenuse esemed hoian võimalikult lihtsad ja väikesed. Koostan teenuseobjektid teiste teenuseobjektidega ja kasutan neid uuesti.

  • Puhastage ja kiirendage oma testipaketti. Teenuseid on kiire ja lihtne testida, kuna need on väikesed rubiinobjektid, millel on sisenemispunkt (nn meetod). Komplekssed teenused on ühendatud teiste teenustega, nii et saate testid hõlpsasti eraldada. Samuti hõlbustab teenuseobjektide kasutamine seotud objektide hankimist kogu rööbaste keskkonda laadimata.

  • Lunastatav kõikjalt. Teenindusobjekte kutsutakse kindlasti nii kontrolleritelt kui ka teenuseobjektidelt, DelayedJob / Rescue / Sidekiq Jobs, Rake'i ülesanded, konsool jne.

Teiselt poolt pole miski täiuslik. Teenuseobjektide üks puudus on see, et need võivad iga väikese toimingu puhul olla üle jõu. Sellistel juhtudel võite lõpuks oma koodi keerulisemaks muuta ja mitte lihtsustada.

Millal peaksite teenuse objekte välja pakkima?

Ka siin pole kindlat reeglit.

Tavaliselt on teenuseobjektid parimad keskmistele ja suurtele süsteemidele: korraliku loogikaga süsteemidele, tavalistest CRUD-toimingutest kaugemale.

Nii et kui arvate, et koodijupp ei kuulu kataloogi, on kohas, kuhu kavatsesite selle lisada, tasub see uuesti läbi mõelda ja vaadata, kas oleks parem, kui see läheks teenuseobjektile.

Siin on mõned näpunäited teenuse objektide kasutamise kohta:

raspberry pi veebiserver nginx
  • Tegevus on keeruline.
  • Toiming jõuab mitme mudelini.
  • Tegevus suhtleb välise teenusega.
  • Tegevus ei ole allajoonitud mudeli peamine mure.
  • Toimingut saab teha mitmel viisil.

Kuidas peaksite teenuseobjekte kujundama?

Teenuseobjekti klassi kujundamine on suhteliselt lihtne, kuna te ei vaja seda kalliskivid te ei peaks õppima a DLS uus, kuid kui suudate enam-vähem toetuda juba olemasolevatele tarkvara kujundamise oskustele.

Tavaliselt kasutan teenuse objekti kujundamiseks järgmisi juhiseid ja tavasid:

  • Ärge salvestage objekti olekut.
  • Kasutage eksemplarimeetodeid, mitte klassimeetodeid.
  • Avalikke meetodeid peaks olema väga vähe (eelistatavalt selline, mis toetab * HAIGE .
  • Meetodid peaksid tagastama rikkalikud, mitte tõeväärtusega objektide tulemused.
  • Teenused lähevad kataloogi app/services alla . Soovitan teil tugevate äriloogika domeenide jaoks kasutada alamkatalooge. Näiteks fail app/services/report/generate_weekly.rb määratleb Report::GenerateWeekly samal ajal app/services/report/publish_monthly.rb määratleb Report::PublishMonthly
  • Teenused algavad verbiga (ja ei lõpe teenimisega): ApproveTransaction, SendTestNewsletter, ImportUsersFromCsv.
  • Teenused reageerivad nimetatud meetodile. Leidsin, et teise verbi kasutamine muudab selle veidi üleliigseks: ApproveTransaction.approve () ei loe hästi. Nimetatud meetod on ka de facto meetod lambda , procs ja meetodi objektid.

Kui vaatate StatisticsController#index, siis märkate kontrollerile rühmitatud meetodite rühma (weeks_to_date_from, weeks_to_date_to, avg_distance jne). See ei ole hea. Mõelge tagajärgedele, kui soovite nädala aruande luua väljaspool statistics_controller

Meie puhul loome Report::GenerateWeekly ja väljavõtke loogikaaruanne StatisticsController

  • Põhisisu proov

Niisiis StatisticsController#index nüüd näeb see puhtam välja:

  • Põhisisu proov

Rakendades teenuse objekti mustrit, rühmitame koodi keeruka ja konkreetse toimingu ümber ning edendame väiksemate ja selgemate meetodite loomist.

Kodutöö: kaaluge kasutamist Väärtuslik objekt WeeklyReport jaoks Struct asemel .

Objektide ekstraktimine Päring Kontrollerid

Mis on objekt Päring ?

Objekt Päring on PORE, mis tähistab päringute andmebaasi. Seda saab taaskasutada rakenduse erinevates kohtades, varjates samal ajal päringuloogikat. Samuti on see testimiseks hea isoleeritud seade.

Peaksite keerukad SQL / NoSQL-päringud eraldama oma klassidesse.

Iga objekt Päring vastutab tulemuste kogumi tagastamise eest, lähtudes kriteeriumidest / ärireeglitest.

Selles näites pole meil päringut ( päring ) keeruline, nii et kasutage objekti Päring see ei oleks tõhus. Kuid demonstreerimise eesmärgil eraldame päringu Report::GenerateWeekly#call ja loome generate_entries_query.rb:

  • Põhisisu proov

Ja asendame Report::GenerateWeekly#call

def call @user.entries.group_by(&:week).map do |week, entries| WeeklyReport.new( ... ) end end

koos:

def call weekly_grouped_entries = GroupEntriesQuery.new(@user).call weekly_grouped_entries.map do |week, entries| WeeklyReport.new( ... ) end end

Objekti muster päring (päring) aitab hoida teie mudeli loogikat rangelt seotud klassi käitumisega, hoides samal ajal oma kontrollereid kõhnana. Sest nad pole muud kui tavalised vanad Ruby klassid , objektid päring nad ei pea pärima ActiveRecord::Base -st ja peaksid vastutama muu kui päringu täitmise eest.

Väljavõte Loo kanne teenuse objektile

Nüüd võtame välja uue teenuseobjekti uue kirje loomise loogika. Kasutame konventsiooni ja loome CreateEntry:

  • Põhisisu proov

Ja nüüd on meie EntriesController#create on järgmine:

def create begin CreateEntry.new(current_user, entry_params).call flash[:notice] = 'Entry was successfully created.' rescue Exception => e flash[:error] = e.message end redirect_to root_path end

Kujuobjekti rohkem valideerimisi

Nüüd hakkavad asjad huvitavamaks minema.

Pidage meeles, et meie juhistes leppisime kokku, et soovime, et mudelitel oleksid assotsiatsioonid ja konstandid, kuid mitte midagi muud (ei valideerimisi ega kõnesid). Alustame tähelepanulaiendite eemaldamisega ja kasutame selle asemel objekti Shape.

Kujuobjekt on PORO (tavaline vana rubiinobjekt). Kui peate andmebaasiga rääkima, võtke kontroller / teenuseobjekt käsku.

Miks kasutada Shape objekte?

Kui peate oma rakenduse ümber kujundama, on alati hea meeles pidada peamist vastutust ( HAIGE ).

HAIGE aitab teil teha paremaid kujundusotsuseid klassiga seotud vastutuse osas.

Näiteks teie andmebaasitabeli mudel (rööbaste kontekstis ActiveRecordi mudel) tähistab koodis ainulaadset andmebaasikirjet, nii et teil pole põhjust muretseda midagi, mida teie kasutaja teeb.

Siit tuleb Shape objekt.

Kujuobjekt vastutab teie rakenduses kuju esindamise eest. Seega saab iga sisendvälja käsitleda tunnis atribuudina. Võite kinnitada, et need atribuudid vastavad mõnele valideerimisreeglile, ja võite edastada 'puhtad' andmed sinna, kuhu need peaksid minema (nt teie andmebaasi mudel või võib-olla teie päringuotsingu koostaja).

Millal peaksite kasutama objekti Shape?

  • Kui soovite kinnitada Railsi mudelitest valideerimised.
  • Kui mitut mudelit saab ühe kättetoimetamise meetodi abil värskendada, peaksite looma objekti Shape.

See võimaldab teil kogu oma vormiloogika (nimetamiskonventsioonid, valideerimised ja muud) ühte kohta panna.

Kuidas luua objekti Shape?

  • Looge lihtne Ruby klass.
  • Sisaldab ActiveModel::Model (Rööbastesse 3 peate selle asemel lisama nime, teisenduse ja valideerimise).
  • Alustage oma uue kuju klassi kasutamist, nagu oleks see tavaline ActiveRecordi mudel, kus suurim erinevus seisneb selles, et te ei saa sellesse objekti salvestatud andmetega jätkata.

Pange tähele, et saate kasutada pärl reform , kuid jätkates PORO-ga, loome entry_form.rb mis näeb välja selline:

  • Põhisisu proov

Ja me muudame CreateEntry objekti Vorming EntryForm kasutamise alustamiseks:

class CreateEntry ...... ...... def call @entry_form = ::EntryForm.new(@params) if @entry_form.valid? .... else .... end end end

Märge: Mõni teist ütleb, et teenuse objektilt pole vaja Shape-objekti juurde pääseda ja me võime Shape-objektile helistada otse kontrollerilt, mis on kehtiv argument. Kuid mul oleks pigem selge voog, seetõttu helistan alati vormi objekt teenuse objektilt.

Kõnede teisaldamine teenuse objektile.

Nagu me varem kokku leppisime, ei soovi me, et meie mudelid sisaldaksid valideerimisi ja kõnesid. Tõmbasime valideerimised objektide Shape abil. Kuid me kasutame endiselt mõnda kõnet (after_create mudelis Entry compare_speed_and_notify_user).

Miks me tahame modellidest kõned eemaldada?

Rööbaste arendajad testide ajal hakkavad nad tavaliselt helistamise ajal valu tundma. Kui te ei testi oma ActiveRecordi mudeleid, hakkate valusid märkama hiljem, kui teie rakendus kasvab ja kuna helistamiseks või kõnede vältimiseks on vaja rohkem loogikat.

después_* kõnesid kasutatakse peamiselt seoses objekti salvestamise või sellega jätkamisega.

Kui objekt on salvestatud, on objekti eesmärk (nt vastutus) täidetud. Nii et kui me ikkagi näeme, et kõnesid kutsutakse, siis pärast objekti salvestamist on need tõenäoliselt kõned, mille eesmärk on pääseda objekti vastutusalast välja ja siis tekivad meil probleemid.

Meie puhul saadame kasutajale SMS-i, mis pole seotud sisenddomeeniga.

toote hinnaelastsuse teadmine võimaldab majandusteadlastel:

Lihtne viis probleemi lahendamiseks on kõne viimine seotud teenuse objektile. Lõppude lõpuks on SMS-i saatmine vastavale kasutajale seotud teenuseobjektiga CreateEntry mitte sisenemismudel kui selline.

Seda tehes ei pea me enam sulgema, compare_speed_and_notify_user meie testides. Oleme teinud selle lihtsaks, luues sissekande ilma SMS-i saatmata ja järgime head objektile orienteeritud kujundust, tagades, et meie klassidel on ainulaadne vastutus ( HAIGE ).

Nii et nüüd CreateEntry see on midagi sarnast sellega:

  • Põhisisu proov

Abistajate asemel kasutage kaunistajaid

Kuigi saame kollektsiooni hõlpsalt kasutada Draper vaatemudelite ja sisekujundajate osas jään PORO juurde, selle artikli jaoks, nagu olen siiani teinud.

Mul on vaja klassi, mis kutsub kaunistatud objektil meetodeid.

Ma saan kasutada method_missing selle rakendamiseks, kuid ma kasutan standardset Ruby teeki SimpleDelegator. Järgmine kood näitab, kuidas SimpleDelegator meie baasdekoraatori rakendamiseks:

% app/decorators/base_decorator.rb require 'delegate' class BaseDecorator

Miks meetod _h

See meetod toimib vaate konteksti puhverserverina. Vaikimisi on vaate kontekst vaate klassi eksemplar, selleks on ActionView::Base Teil on juurdepääs abistajad seisukohti järgmiselt:

_h.content_tag :div, 'my-div', class: 'my-class'

Selle mugavamaks muutmiseks lisame meetodi decorado a ApplicationHelper:

module ApplicationHelper # ..... def decorate(object, klass = nil) klass ||= '#{object.class}Decorator'.constantize decorator = klass.new(object, self) yield decorator if block_given? decorator end # ..... end

Nüüd saame liikuda abistajad EntriesHelper dekoraatoritele:

# app/decorators/entry_decorator.rb class EntryDecorator

Ja saame kasutada readable_time_period ja readable_speed järgnevalt:

# app/views/entries/_entry.html.erb - + - +

Struktuur pärast taastamist

Lõpuks saime rohkem faile, kuid see pole tingimata halb asi (ja pidage meeles, et algusest peale olime teadlikud, et see näide oli mõeldud tutvustamiseks ja ei oli tingimata hea taaskasutamise juhtum):

app ├── assets │ └── ... ├── controllers │ ├── application_controller.rb │ ├── entries_controller.rb │ └── statistics_controller.rb ├── decorators │ ├── base_decorator.rb │ └── entry_decorator.rb ├── forms │ └── entry_form.rb ├── helpers │ └── application_helper.rb ├── mailers ├── models │ ├── entry.rb │ ├── entry_status.rb │ └── user.rb ├── queries │ └── group_entries_query.rb ├── services │ ├── create_entry.rb │ └── report │ └── generate_weekly.rb └── views ├── devise │ └── .. ├── entries │ ├── _entry.html.erb │ ├── _form.html.erb │ └── index.html.erb ├── layouts │ └── application.html.erb └── statistics └── index.html.erb

järeldus

Kuigi selles blogipostituses keskendume Railsile, ei sõltu RoR (Ruby on Rails) teenuseobjektidest ega muudest PORO-dest. Seda lähenemist saate kasutada ükskõik millisega raamistiku veeb , mobiili- või konsoolirakendus.

Kasutamisel MVC Arhitektuurina kleepub kõik kokku ja aeglustab teid, sest enamik muudatusi mõjutab rakenduse muid osi. Samuti sunnib teid mõtlema, kuhu panna mõni äriloogika - kas see peaks minema mudeli, kontrolleri või vaate sisse?

Lihtsa PORO abil oleme viinud äriloogika mudelitesse või teenustesse, mis ei pärine ActiveRecord -st, mis on juba kasum, rääkimata sellest, et meil on selgem kood, mis toetab HAIGE ja kiirem seadmete testimine.

Puhas arhitektuur üritab panna kasutuskastid oma struktuuri keskele / ülaossa, nii et näeksite hõlpsalt, mida teie rakendus teeb. See hõlbustab ka muudatuste vastuvõtmist, kuna see on modulaarsem ja isoleeritum. Loodan, et olen näidanud, kuidas Tavalised vanad rubiinobjektid ja rohkem abstraktsioone, see eraldab mured, lihtsustab testimist ja aitab luua puhast ja hooldatavat koodi.

Seotud: Mis kasu on Ruby on Rails'ist? Pärast kaks aastakümmet programmeerimist. Kasutage rööpaid

Kuidas läbi viia tõhus disainisprint

Kujundusprotsess

Kuidas läbi viia tõhus disainisprint
25-aastase Linuxi tuumaarenduse tähistamine

25-aastase Linuxi tuumaarenduse tähistamine

Tagumine Ots

Lemmik Postitused
Äriplaani anatoomia
Äriplaani anatoomia
Ladina-Ameerika ühinemiste ja ühinemiste parimad tavad
Ladina-Ameerika ühinemiste ja ühinemiste parimad tavad
Tarkvara kulude hindamine agiilses projektijuhtimises
Tarkvara kulude hindamine agiilses projektijuhtimises
Andekus pole kaup
Andekus pole kaup
Veebi juurdepääsetavus: miks W3C standardeid sageli eiratakse
Veebi juurdepääsetavus: miks W3C standardeid sageli eiratakse
 
Bränding on surnud, CX Design on kuningas
Bränding on surnud, CX Design on kuningas
Chatbot UX - disaininõuanded ja kaalutlused
Chatbot UX - disaininõuanded ja kaalutlused
Uus ettevõtluslaine
Uus ettevõtluslaine
Optimeeritud järjestikune keskmine kvantimise teisendus
Optimeeritud järjestikune keskmine kvantimise teisendus
Kasutajauuringute väärtus
Kasutajauuringute väärtus
Lemmik Postitused
  • kujundusmustri määratlemise põhimõtted
  • häkitud krediitkaardinumbrid koos cvv ja sihtnumbriga 2017
  • veakäsitluse parimaid tavasid
  • multimeedia disain vs graafiline disain
  • loetlege disaini põhimõtted
Kategooriad
  • Tooteinimesed Ja Meeskonnad
  • Ux Disain
  • Protsess Ja Tööriistad
  • Andmeteadus Ja Andmebaasid
  • © 2022 | Kõik Õigused Kaitstud

    portaldacalheta.pt