Press "Enter" to skip to content

GOTO 2018 • SOLID Elixir • Georgina McFadyen


[Musica]
oggi parlerò del
principi solidi che sono un insieme di cinque
principi di progettazione originariamente creati per
programmazione orientata agli oggetti
discuteremo se questi principi
può essere applicato a una base di codice funzionale
o se esigenze di programmazione funzionale
il suo insieme di principi di design il mio nome
è Georgina e io sono uno sviluppatore di software
e la maggior parte della mia esperienza è stata in
sviluppo Java orientato agli oggetti ma a
nel momento in cui sto lavorando a un progetto
che comprende servizi di Micra e
alcuni di questi servizi sono scritti in
elisir quando ho iniziato la mia prima volta
carriera c’era molto da imparare che ero
usando Java e C ++ quindi probabilmente il più
lingue orientate agli oggetti che puoi
trovare e ho dovuto imparare a vedere il
mondo come oggetti e come quegli oggetti
interagirebbe tra di loro anche io
dovuto imparare la sintassi della lingua
così ho potuto portare le soluzioni per la vita
e in questa fase iniziale la maggior parte dei miei
lo sforzo è stato speso solo per legare il codice
insieme sperando che funzionasse
riuscendo a farlo funzionare ma col tempo ho ottenuto
fare i conti con il modo di pensare OO e
Presto mi sono reso conto di aver appena ottenuto il mio
il codice per il lavoro non era abbastanza in realtà io
necessario per prendere ulteriormente il mio codice in ordine
per produrre soluzioni che potrebbero vivere
più lungo ed essere più facile da mantenere e
test e per altre persone a lavorare su così
per fortuna ho fatto una mossa di carriera e io
è entrato in una società che era molto
investito nell’insegnare i propri sviluppatori
alcune buone pratiche e il solido
i principi sono diventati parte integrante di
gli sviluppatori elaborano dopo l’applicazione
i principi solidi per il mio codice Java I
sentivo di poter essere fiero delle mie soluzioni
erano più facili da mantenere ed estendere
erano più robusti il
la stessa compagnia mi ha chiesto di imparare a
linguaggio funzionale così come un consulente I
potrebbe entrare in diversi clienti e
valutare quale paradigma e quale
le lingue sarebbero le più adatte a risolvere
i problemi che stavano affrontando così io
ho deciso di imparare una leccata di signore a questo
punto che ho avuto anni di esperienza di
analisi dei sistemi e problem solving I
potrebbe già programmare in Java così
imparare la sintassi dell’elisir non lo era
molto difficile non era davvero un
barriera e ho subito ottenuto qualcosa
lavorando ma poi ho sentito di essere nel
la stessa posizione in cui ero stato in precedenza
la mia carriera ho avuto una base di codice funzionale
che ha funzionato ma ho sentito che dovevo prendere
è un passo avanti e non l’ho fatto davvero
sapere quali principi applicare non lo ero
consapevole di ogni principio specifico per
linguaggi di programmazione funzionale quindi io
ho deciso di restare con ciò che sapevo e facevo
un esperimento e applicare il solido
principi per una base di codice funzionale così
i principi solidi sono un insieme di cinque
principi di progettazione in cui ogni lettera
sta per un principio diverso quando
applicati sono destinati a migliorare il
qualità del tuo software in termini di
rendendo più facile estendere meno probabile
da spezzare se si affrontano delle modifiche
e sono stati originariamente ideato per
programmazione orientata agli oggetti ma volevo
per vedere se avrebbero funzionato nel funzionale
paesaggio il case study che ho
scelto per dimostrare questi principi
oggi sono un micro servizio di elisir che
fa parte di un sito di prenotazione per le vacanze
codice vedremo le preoccupazioni
i clienti cercano le preferenze in modo che possano
cerca per quale alloggio che loro
voglio trovare quando stanno andando
vacanza
è un servizio di plug elisir e il
i servizi interagiranno utilizzando HTTP
i siti di prenotazione hanno molte forme di ricerca
così quando i clienti accedono e loro
puoi navigare in questa scheda che possono selezionare
quello che stanno cercando in termini di
alloggio premere ricerca ed essere
presentato con un elenco di opzioni il
la prima volta che un utente accede alla pagina
non ci saranno opzioni preselezionate su
il modulo
ma non appena sono andati avanti e fatti
una ricerca salveremo quella ricerca
preferenze in modo che dovrebbero venire
indietro saremo in grado di pre popolare il
forma con le ultime preferenze che
sono usati così per recuperarli
preferenze pre-salvate abbiamo una fine
puntare nel nostro sistema un tipico flusso di lavoro
l’utente effettuerà l’ accesso e andrà
alla scheda Ricerca scaricando la pagina a
ottenere la richiesta è licenziato e sotto il cofano
andremo a fare un accesso al database
e stiamo usando Dynamo DB per questo
esempio che è un database non SQL
associato in 8 pozzi è disponibile in
AWS ma potresti usare qualsiasi tipo di persistente
negozio memorizziamo i nostri dati internamente in a
formato di mappa e poi lo traduciamo in
alcuni JSON e rinviarlo al
chiamare il client e questo è usato allora
popolare il modulo di ricerca
ha spiegato come ottenere i dati anche noi
devono essere in grado di mantenere i dati così
il caso d’uso qui è che un utente lo farebbe
accedi e naviga verso il modulo loro
selezionare ciò che vogliono cercare
per e poi su premendo la ricerca lo farà
innescare un post che andrà avanti
e avviare il flusso di lavoro di persistenza
dobbiamo tradurre i nostri dati l’altro
in questo periodo dal JSON a
la nostra mappa interna in modo che possiamo archiviare
quello nel database e otterrà
spuntato nel DB dinamo quindi per il
gli scopi di questo discorso basti pensare
il servizio come servizio crudele, quindi ora tu
avere un sapore del dominio che possiamo ottenere
torna ai nostri solidi principi il primo
uno è chiamato singola responsabilità quindi
la definizione ufficiale di single
la responsabilità di Wikipedia è quella
ogni classe o modulo dovrebbe essere
responsabile di una parte particolare del
sistema, quindi cosa significa?
bene usando questa definizione su questo
Occasionalmente decidiamo di andare a prendere utente
preferenze è una singola parte del
sistema in modo che possiamo scrivere un modulo di elisir
che incapsulerà
quella logica abbiamo il nostro modulo qui il
la prima cosa che dobbiamo fare è interrogare il
database con l’ID cliente che è
ottenuto quando gli utenti hanno effettuato l’accesso
quindi è necessario tradurre il nostro database raw
dati in una struttura interna e quella
elimina i metadati che DynamoDB
ritorna che non siamo veramente
interessato e poi trasformiamo il nostro
dati grezzi la nostra struttura in alcuni JSON e
allora lo restituiremo al
chiamare il cliente così in poche parole che abbiamo
tre passaggi all’interno di questo modulo che guardiamo
up i dati dal database che spogliamo
fuori i metadati e poi li traduciamo
che a una risposta JSON modo è che
davvero una sola responsabilità, bene quelli
tre passaggi completano il recupero dell’utente
preferenze ma chiediamoci
un’altra domanda un modo per provare
identifica se stai violando il singolo
il principio di responsabilità è chiedere
voi stessi dei passi all’interno di questo
modulo può cambiare qualcuno di loro
indipendentemente, per esempio, se decidessimo
per cambiare la query al database così
invece di usare l’ID cliente che usiamo
l’ID cliente e il paese di origine o
qualcosa significherebbe il nostro JSON
la risposta doveva cambiare probabilmente no
finché i dati torneranno
è nello stesso formato di tutti i
le fasi a valle non sarebbero realmente
interessati , questo potrebbe significare che lo abbiamo
passi che potrebbero divergere e cambiare
indipendentemente che potrebbe portare a a
violazione della singola responsabilità
principio ci sono alcune definizioni su
Wikipedia di questo principio e tendo
per favorire questo da zio Bob e lui
esprime che il principio dovrebbe significare
che una classe dovrebbe avere solo una ragione
cambiare e in elisir che non abbiamo
le classi invece abbiamo moduli così noi
potrebbe aggiornare questa definizione per essere un
il modulo ha solo una ragione per cambiare
così come promemoria abbiamo iniziato con uno
modulo contenente tre passaggi, quindi facciamolo
applica questa definizione aggiornata da Uncle
Bob e vedere se la nostra soluzione si adatta a
ogni passo dentro è il proprio modulo, quindi lo faremo
inizia con la funzionalità che
interroga il database che abbiamo avvolto che
nel suo modulo e possiamo già vedere
è lontano per più piccolo e molto altro
focalizzato così ora possiamo testarlo davvero
indipendentemente e avremo molto di più
test focalizzati se la risposta JSON
cambia ora non dovremmo toccare
questo è completamente separato
il secondo passo che abbiamo definito è stato
trasformando la nostra risposta ai dati grezzi in
una struttura per spogliare i dati in eccesso noi
non serve ora se guardiamo da vicino
questo modulo in realtà stiamo semplicemente avvolgendo
una chiamata in biblioteca qui stiamo usando il
libreria X AWS per aiutarci a interagire con
il database quindi è discutibile se
questo in realtà ha bisogno del proprio modulo o
se questo potrebbe essere unito con
il modulo precedente che cerca il
preferenze dell’utente perché non c’è
davvero qualsiasi logica di business qui ma
il punto è non aver paura di rompere
giù i tuoi sistemi e se ti trovi
bisogno di mettere bit nuovo insieme
allora va bene l’ultimo passo
trasformando in jason e ha senso
per avere questo separato perché sta facendo
un lavoro completamente diverso non lo è
interagendo con il database a tutti e
possiamo cambiare questa risposta JSON come noi
desiderio senza influenzare nessuno dei
database interroga il nostro controller ora
diventa piuttosto sottile e si limita a coordinare
le chiamate tra i nuovi moduli e questo
significa che il test di questo è più facile come
bene quindi se ripensiamo a quando abbiamo avuto
tutta la logica in un controller se noi
volevo testare la formattazione JSON che avremmo
bisogno di colpire il punto finale di cui abbiamo bisogno
imitare i dati provenienti dal database
dobbiamo quindi tradurlo in a
struct trasformarlo in Jason e and
allora potremmo verificare che il jason fosse
come previsto e questo è un sacco di
impostare in modo da avere questi più piccoli
moduli focalizzati possiamo avere molto di più
vengono effettuati test focalizzati e test di messa a fuoco
fallimenti molto più focalizzati e quello
tende a portare a un molto più veloce
risoluzione
il numero di test di alto livello può essere
ridotto perché c’è solo bisogno di te
controlla che il coordinamento stia accadendo
correttamente e tendono ad essere più
costoso da eseguire e richiede più configurazione
comunque tenerle sottili è bello
idea c’è sempre trade-off e con
ogni modulo che esiste è un
in testa devi tenerlo e tu
fare in modo che sia aggiornato
quindi è bene assicurarsi che ogni
il modulo che creerai ne garantisce il suo
esistenza e se vi trovate con
una pletora di moduli di cui alcuni
cambia sempre insieme, allora potrebbe essere
un segno che dovrebbero essere effettivamente
uniti insieme il prossimo principio è
il principio chiuso aperto questo principio
afferma che dovresti essere in grado di estendere
funzionalità senza modificare il
codice sorgente che suona come un ossimoro
come come cambi qualcosa se tu
non posso toccare bene il codice sorgente ci provo
pensarlo come dovrebbe essere il
possibilità di aggiungere nuovo codice senza cambiare
qualsiasi codice esistente quindi ci limiteremo a
ricordati dei nostri post endpoint
quando un utente cerca un po ‘
alloggio insistiamo nella ricerca
preferenze nel nostro database in modo che noi
non memorizzare alcun dato incompleto noi
eseguire una serie di regole di convalida prima
per persistere vogliamo verificare che il
l’ID cliente è valido e che il
il corpo della richiesta ha alcuni campi obbligatori
dobbiamo avere quei campi esistenti con
il nostro principio di responsabilità unica in
bada , abbiamo le regole di validazione
definito e ogni regola è a sé stante
modulo in modo che possano essere testati
indipendentemente abbiamo attraversato tutto
le regole di validazione e se tutto è
buona la richiesta è valida andremo avanti
e continua la nostra riga nel nostro database
e restituire un 201 al nostro cliente ma
se manca qualcosa
dalla richiesta che vogliamo indicare
che il problema era così siamo tornati
a 400 e daremo una ragione per
perché i richiedenti
rifiutato e il cliente può modificare il proprio
richiedi e riprova quindi voglio aggiungere un
nuova regola di convalida al mio servizio così
Creerò un nuovo modulo che contiene
la logica commerciale della nuova regola e
Lo aggiungerò alla mia arguzia, così
che viene eseguito come parte del flusso se
questa regola non funziona, devo essere in grado di farlo
gestiscilo e voglio dirlo al
cliente perché così ho bisogno di aggiungere un errore
caso ma aspetta un minuto l’aperto chiuso
principio ha affermato che dovremmo essere in grado
aggiungere nuovo codice senza effettivamente
modificando qualsiasi codice esistente e qui
stiamo modificando il codice esistente che abbiamo
aggiornato la dichiarazione con e abbiamo avuto
per aggiungere la gestione degli errori in modo che siamo
violando quel principio aperto e chiuso ora
aggiungendo una nuova regola in questo esempio
sembra piuttosto banale in una produzione reale
sistema potresti avere decine o centinaia
di regole e dover configurarle
e testare tutte quelle permutazioni potrebbe essere
abbastanza complicato in modo da quella lista di
le regole crescono che non vogliamo avere
mantenere tutti questi diversi
permutazioni di test e anche per
lo scenario del giorno di sole che dovremmo fare
certo la nostra richiesta è stata impostata in modo che tutto
delle regole che sono state rispettati così
potrebbe essere più conveniente se noi invece
avere una specie di architettura plug-in quella
per esempio nel nostro ambiente di test
potremmo semplicemente inserire una o due regole
e poi in produzione potremmo collegarci
tutte le regole quindi facciamolo
guarda il nostro set originale di regole e io
credo che avremmo potuto dire che in generale
cadere in due categorie quelli
preoccupazione convalida dell’intestazione e
quelli che contengono convalida del
corpo così se creiamo un elenco di intestazione
regole e un elenco di regole del corpo e noi
avvolgere ciascuna di quelle liste in un elisir
modulo possiamo quindi scorrere su quelli
elenca e attraversa le regole così qui
Ho una lista della mia convalida
funzioni I attraversano più di quelle regole
e se qualcuno di loro fallisce un rapporto
errore e dare una ragione per cui
quindi ora se dovessimo aggiungere una nuova regola, lo faremmo
bisogno di aggiungerlo alla lista, ma sono
la logica circostante il codice circostante
in realtà non avrebbe bisogno di cambiarle
chiamare il codice di questo diventa più
semplice perché ha solo bisogno di dare il via
le regole dell’intestazione e le regole del corpo e
i dettagli di ciascuna delle regole sono
nascosto a un livello più basso, così potremmo
dì che a questo livello stiamo ascoltando
apri il principio chiuso perché non lo fa
sapere se sta eseguendo una regola o
un centinaio di regole in modo che cosa deve cambiare
ora se vogliamo aggiungere una nuova convalida
regola dovremmo aggiungere un nuovo modulo
contenente la nuova regola come funzione in
la lista e se pensiamo a questa lista come
configurazione piuttosto che codice che potremmo
Diciamo che stiamo aderendo allo scoperto
principio chiuso perché nessuno dei nostri
altro codice in questo modulo ha bisogno di
cambiare ma c’è sempre trade-off e
i test non diventano davvero più facili
perché se abbiamo un centinaio di regole noi
Devo ancora assicurarmi che il nostro test
i dati sono conformi a tutte quelle regole e
nel nostro ambiente di test saranno tutti
iniettato nelle nostre parole, potremmo volerlo
uno o due in per semplificare le cose così come
queste regole diventano permutazioni diventano
più difficile e la manutenzione potrebbe
diventare un overhead così decisamente un passaggio
nella giusta direzione per restringere
l’area del cambiamento solo per una singola lista
ma uno degli altri inconvenienti è qui
che non ci sono contratti sul posto, quindi noi
non ho alcuna sicurezza in termini di
ciò che queste funzioni stanno per tornare
e il codice circostante è in attesa
che una tupla viene restituita così per
rassodare e rendere questo più sicuro noi
potrebbe effettivamente usare un comportamento di elisir
e questo ci consente di definire un contratto
un po ‘come in Java come si ha
interfaccia e tu definisci un contratto
a quale classe dovrà attenersi
quindi ogni modulo che implementa questo
il comportamento dovrà fornire un
implementazione per le funzioni definite
su quel comportamento così possiamo definirne uno
che ha una funzione valida quindi questo
afferma che tutti i moduli che stanno andando
usare questo comportamento
fornire la propria implementazione del
è un metodo valido che prende una mappa e questa
restituirà sia una tupla contenente
okay e alcuni dati o una tupla contenente
errore e quindi alcuni motivi per cui
quella richiesta ha avuto un errore quindi ora abbiamo bisogno
aggiornare le regole in realtà
attuare il nostro comportamento per farlo noi
solo fornire un’annotazione e poi noi
fornire la funzione che il loro contratto
ha bisogno di così quando stavano usando questi
comportamenti piuttosto che avere una lista di
funzioni che ora possiamo effettivamente avere
una lista di moduli perché sappiamo cosa
una funzionalità è disponibile su questi
moduli perché sono tutti aderenti
lo stesso contratto quindi nel nostro codice quando
noi iteriamo le regole che possiamo effettivamente fare
chiamare in modo sicuro la funzione è valida
perché sappiamo che questo è sul
contratto se ti dimentichi di fornire il tuo
implementazione quindi otterrai un
eccezione che ti dice così l’ultimo passaggio
per rendere questo completamente configurabile sarebbe
trasferire l’elenco dei moduli dalla
codice nei file di configurazione e in questo modo
possiamo impostare diversi elenchi di regole
a seconda del diverso runtime
ambiente così in elisir hai un
file di configurazione diverso per ogni
ambiente così nella nostra configurazione di prova
potrebbe solo fornire una coppia ma dentro
produzione che potremmo fornire a tutti
quindi in fase di runtime guardiamo nella nostra configurazione
in quale serie di regole dovrebbe essere iniettato
e questo ci dà la flessibilità
di usare solo un paio di regole in una
ambiente o quando stiamo gestendo il nostro
unit test e poi tutte le regole quando
stavano facendo funzionare il sistema reale in questo momento
aggiungi una nuova regola che dobbiamo aggiungere una nuova
modulo contenente la nuova logica di business
per la nostra regola è necessario configurare tale
nome del modulo nell’elenco pertinente in
file di configurazione dell’ambiente pertinente
e questo è tutto ciò che dovevamo fare
riuscito a aggiungere con successo nuove regole
senza toccare alcuna fonte esistente
codice quindi stiamo aderendo al
principio aperto-chiuso ancora una volta questo potrebbe
sembra eccessivo per questo esempio ma in
vita reale dove hai rapidamente
cambiando i requisiti aziendali e voi
potrebbe essere necessario per dimostrare le cose rapidamente e
ottenere un feedback più veloce
che avere la possibilità di collegare e
le diverse regole potrebbero essere un
vantaggio quindi il prossimo principio è Lisco
sostituzione in object-oriented
lingue abbiamo il concetto di classi
e le classi possono ereditare il comportamento di
altre classi quindi in questo esempio qui noi
avere una relazione – classe e questo fornisce
un metodo di formattazione e quindi abbiamo a
classe di report di marketing che eredita
questo comportamento oltre ad averne un po ‘
comportamento di per sé questo è il funzionario
definizione di sostituzione di Lascaux e
se non l’hai incontrato prima di me
non proverei nemmeno a capirlo
perché lo scrivono sempre in modo veramente
modo complicato ma essenzialmente lo è
cercando di dire dove hai una variabile
è del tipo base quindi nel nostro caso
nel nostro esempio il report dovresti essere
in grado di passare a una qualsiasi sottoclasse
tipi senza avere un indesiderabile
effetto sul tuo sistema così questo è
probabilmente meglio dimostrato con un piccolo
Snippet Java così qui abbiamo dichiarato
rapporto variabile e questo è un marketing
rapporto e stiamo chiamando formati
andiamo la sostituzione sta dicendo noi
dovrebbe essere in grado di sostituire il formato a
il tipo di rapporto con il marketing
tipo di rapporto e tutto dovrebbe ancora
corri e funziona a causa del
modello di ereditarietà sappiamo che il
il metodo di formattazione è disponibile in più
strato generico che c’è così
tutto verrà compilato ed eseguito ora
programmazione funzionale non lo facciamo davvero
usa l’eredità molto a volte no
ma vediamo come possiamo modellare
qualcosa di simile usando l’elisir che abbiamo
alcune funzionalità di reporting nel nostro
le preferenze dell’utente del servizio vacanze sono
inviato al nostro dipartimento marketing in modo che
pubblicità mirata può essere inviata al nostro
base di clienti
inoltre le preferenze del cliente sono
inviato al nostro dipartimento di data warehouse così
che nel tempo possiamo vedere storico
ricerche e possiamo cercare le tendenze così
in poche parole i dati grezzi in
il database viene tagliato e tagliato a dadini
diversi punti di vista a cui sono poi abituati
creare report diversi
per diverse aree intorno all’azienda
quindi useremo un altro comportamento
per aiutarci avremo ognuno
modulo di report implementa questo formattatore
comportamento che ha un formato alle righe
funzione e quella sarà la logica
che sta formattando i dati grezzi
in particolare per un report specifico quindi noi
possiamo mappare alcuni moduli a questo diagramma noi
avere un modulo di report pubblicitari che
implementa il comportamento del formattatore così
questo significa che il rapporto pubblicitario deve
fornire un formato per l’implementazione delle righe
che formatta i dati appositamente per
il rapporto pubblicitario che abbiamo a
rapporto di data warehouse storico e
ancora una volta che implementa lo stesso comportamento
e fornirà una logica diversa
all’interno del formato per aumentare le specifiche per
questo rapporto storico e poi abbiamo
un generatore di report e questo prende il
dati grezzi e un elenco di argomenti e
mapperà su questi quattro argomenti
formattazione dei dati prima della spedizione
li ai vari dipartimenti così qui
potremmo effettivamente collegare qualsiasi modulo
che implementa il formattatore e questo
il codice verrà eseguito come previsto perché
avrà lo stesso contraente dovrà
una funzione di formato per righe disponibile e
non ci saranno effetti indesiderati quindi
possiamo dire che stiamo aderendo al
Principio di sostituzione di Liskov ma tu
sapere cosa è la vita reale come la nostra vacanza
i siti che decollano davvero hanno guadagnato un
molto trazione e allo stesso tempo
c’è un requisito normativo che è
vieni in modo che abbiamo bisogno di generare un nuovo
rapporto ed è Baliga e legale sono
sempre un po ‘complicati non li hanno mai
non vuoi mai qualcosa che hai già
vogliono qualcosa come quello che hai
ma un po ‘diverso quindi lo affermano
hanno bisogno di un rapporto che abbia lo stesso
formattazione come report dei dati storici
ma ha bisogno di un po ‘più armeggiare con
dobbiamo aggiungere una dichiarazione di non responsabilità un’intestazione e
aggiungi alcuni colori okay in modo che possiamo creare un
generatore di report legali che prenderà
i dati grezzi e un formattatore che abbiamo
hai già un formato dove
formatta i dati come vogliamo e possiamo
basta aggiungere nella dichiarazione di non responsabilità le intestazioni
e i colori, quindi facciamolo, lo faremo
aggiorna il nostro rapporto sui dati storici così
che possiamo riutilizzare la loro funzionalità
già definito nel formato due righe
funzione e quindi possiamo solo aggiungere questi
la nuova presentazione funziona così
quando passiamo questo ora al nostro legale
generatore di report abbiamo un
implementazione per tutte le funzioni
quello che si aspetta formerà due righe
e poi abbiamo appena aggiunto il nuovo
disclaimer e le intestazioni e così via così
possiamo eseguire correttamente questo senza alcuno
problemi e generiamo il nostro legale
rapporto e legale sono felici ma cosa
succede se ora inviamo una pubblicità
formatter al nostro generatore di report legali
il nostro rapporto pubblicitario ha una definizione
per formattare due righe ma non ha
una definizione per l’ aggiunta della dichiarazione di non responsabilità
le intestazioni e i colori perché loro
non sono in realtà sul contratto così di
Naturalmente avremo un’eccezione e
questo è un effetto indesiderato nel
sistema così ora stiamo rompendo il
sostituzione del discorso perché secondo
alla sostituzione di Lisco dovremmo essere in grado
passare in tutto ciò che implementa il
comportamento del formattatore e il sistema dovrebbe
funziona come previsto, quindi dobbiamo pensare a
un po ‘di più sappiamo che vogliamo riutilizzare
la formattazione che si trova nei dati storici
riferire ma dobbiamo fare qualcosa in più
quindi piuttosto che aggiornare l’esistente
segnaliamo creiamo uno nuovo che utilizza
quello esistente quindi ne creiamo uno nuovo
segnala quale implementa l’originale
comportamento formattato in modo che non lo facciamo
interrompere qualsiasi contratto nel formato a
righe funzionano stiamo andando a delegare
fuori e utilizzare il nostro data warehouse esistente
moduli in modo che possiamo sfruttare il
formato per le funzionalità di file che noi
già abbiamo e poi possiamo andare avanti e
aggiungi la presentazione e possiamo nasconderci
questo dietro la funzione di formattazione delle righe
semplicemente fornendo alcuni metodi privati
quindi ora tutti i nostri rapporti in realtà
aderire alla stessa interfaccia, quindi non lo facciamo
ho bisogno di uno speciale
generatore illegale possiamo più
in realtà basta usare lo stesso rapporto
generatore per tutti loro così avvolgendo
un formattatore esistente
siamo stati in grado di estendere la sua funzionalità
senza effettivamente esporlo a nessuno di questi
i clienti chiamanti così in elisir noi
potrei dire che la sostituzione di Liskov potrebbe
essere definito come dove abbiamo il codice
si aspetta un tipo comportamentale assicurarsi che
stai usando solo quelle funzioni
sono definiti sul comportamento così al
livello più generico, ma perché no?
basta aggiornare il formattatore in modo che abbia avuto
queste funzioni di presentazione su di esso come
bene
abbiamo visto come questo abbia potenzialmente senso
per i dati storici rapporto perché alcuni
volte ne aveva bisogno ma per i nostri
la relazione pubblicitaria non è in realtà
rilevante non abbiamo bisogno di aggiungere questi
metodi di livello di presentazione a tutti, ma se
avevamo aggiornato il comportamento che avremmo fatto
sono stati costretti ad aggiornare tutti i nostri
quattro questioni perché avrebbero avuto
necessario aderire al contratto così dentro
il nostro rapporto pubblicitario avremmo avuto
per aggiungere una dichiarazione di non responsabilità aggiungere un’intestazione
e e i colori funzionano ma loro
non avrebbe davvero avuto alcun lavoro da fare
quindi essenzialmente saremmo appena stati
fornendo una definizione vuota e questo è
confondendo per lo sviluppatore perché
dove vedi un contratto di cui hai bisogno
di aderire a te in genere ti aspetti
è necessario fornire un bene
implementazione per quelle funzioni e
che sono necessari ma in questo caso
non sono così di solito è un segno che
il tuo design non è del tutto simile allo stesso modo
se avessimo un sacco e molto di diverso
rapporti che non vorremmo davvero avere
per aggiornarli tutti per avere questi nuovi
funziona solo perché forse uno o due
ne avevano davvero bisogno, quindi se lo avessimo fatto
fatto questo potremmo dire che siamo stati gonfiati
il comportamento al fine di soddisfare una nuova
requisito e, a sua volta, ciò avrebbe avuto
violato il prossimo principio solido che
è la segregazione dell’interfaccia
quindi il principio di segregazione dell’interfaccia
afferma che i clienti non dovrebbero essere forzati
dipendere dai contratti che non hanno
effettivamente utilizzato in object-oriented
programmando ci sono diversi tratti
può cercare nella base di codici che
indica questa violazione in modo tipico
si trova in una classe molto alta
gerarchie dove forse i metodi sono
si sviluppa su diverse responsabilità
o in cose come le interfacce Java dove
si dispone di un sacco di metodi di nuovo
che sono diffusi tra cose diverse
così traducendo questo nel mondo di
elisir potremmo cercare moduli che
avere molte molte funzioni in tutta
diverse responsabilità o di grandi dimensioni
comportamenti abbiamo già discusso perché noi
pensò che non era una buona idea
aggiornare il comportamento del formattatore da includere
quelle funzioni a livello di presentazione e
questo perché non sono rilevanti
tutte le implementazioni quindi facciamolo
lasciare il comportamento formattatore come era
in modo da non rompere nessuno esistente
contratti e invece creiamo a
secondo comportamento che contiene il
il livello di presentazione funziona così avendo
questi divisi ora ci permettono di lasciare il nostro
rapporto pubblicitario da solo perché
implementa già il formattatore
comportamento e non ha bisogno del
livello di presentazione una volta e possiamo
in realtà aggiorna i nostri dati storici
formato per implementare sia perché elisir
consente di implementare tutti i comportamenti di
ti piace finché fornisci un corpo
per tutte le funzioni che sono
atteso così ora quando generiamo il nostro
rapporti possiamo dividerlo in due
passi possiamo eseguire la formattazione
e spedire quei rapporti ma se il
rapporto deve essere presentato anche noi
può farlo attraverso un altro passo e
il codice chiamante può decidere quale passo
è rilevante per quale rapporto così in questo modo
siamo stati in grado di limitare l’extra
funzionalità fino a solo quei rapporti
dove è effettivamente rilevante e lo farai
trova che molti dei solidi
i principi iniziano a sovrapporsi perché di
mantenendo i tuoi comportamenti piccoli e concentrati
in genere rinforzi il loro
anche le singole regole di responsabilità
che ci porta sulle nostre forme
quel principio che è dipendenza
inversione c’erano troppe parole su
Wikipedia per metterli tutti su una diapositiva ma
Ho cercato di rappresentare l’essenza di
è qui e si tratta di mantenere alto il tuo livello
livelli di livello separati dal tuo basso
livelli di livello nel tuo sistema, se tu
ricorda che abbiamo un punto di arrivo che
recupera le preferenze di ricerca dell’utente sotto
il cofano questo si connette a un database per
fare la query e il database è un
sistema esterno usiamo una libreria per aiutare
noi interagiamo con il nostro database e questo
la biblioteca si aspetta che sia una corsa
database in atto che può essere o
eseguire un DB dinamo in un’istanza di
AWS oppure puoi eseguire dynamo DB
localmente e puoi configurare il tuo
config per cercare su localhost e trovare il
database lì quando sto facendo funzionare la mia unità
test in realtà non voglio connettermi
ad una vera istanza AWS e nemmeno voglio
dover orchestrare allevando a
istanza locale di Dynamo che crea un
tabella che inserisce i dati per il test
e poi strappare tutto una volta il mio
il test unitario è finito quindi sostanzialmente in
termini di inversione di dipendenza no
voglio il mio modulo di alto livello che è il mio
ottenere il modulo delle preferenze del cliente
dipende dai dettagli di questa libreria
invece voglio separare questi strati
e darmi la possibilità di collegare a
database falso in modo che quando eseguo la mia unità
test non devo connettermi a nessuno
database in esecuzione a tutti se si richiama un
elisir possiamo configurare diversi
implementazioni in diversi
ambienti così se posso isolare il
codice che si collega al database
Potrei mettere diverse implementazioni in
se sono un pungolo o nei test così
guardando il codice c’è in realtà
solo una linea che fisicamente lo farà
connettersi a dynamo dB quindi sto andando a
estraetelo e poi elaborate un modo
dove posso neanche ricollegarlo per
produzione o utilizzare un’implementazione falsa
per i miei altri ambienti
Alexa ti offre un paio di modi
È possibile raggiungere questo e un modo è quello di
usa la configurazione per sostituire dentro e fuori
a runtime quindi in termini di design per
inversione di dipendenza che voglio avere
diverse implementazioni del
database quindi ho il vero database e
allora ho un database falso e voglio
loro di aderire ad un contratto e
astrazione che userà un comportamento
per di nuovo poi ho il mio alto livello
modulo che è il cliente get
preferenze e voglio che usi il
comportamento
quindi non so se lo sono o no
connettendosi al vero database
sotto o se sto usando solo un
database falso così creo il mio comportamento
che è la mia astrazione che voglio avvolgere
la chiamata della biblioteca in un modulo che
implementa quel comportamento e poi io voglio
per fornire un database falso che sta per
essere un altro modulo che implementa il
stesso comportamento ma quando chiamo il
richiesta Sto solo andando a restituire a
risultato in scatola nello stesso formato di cosa
il vero database tornerebbe
poi nei miei file di configurazione che sto andando a
dichiaro che voglio usare il falso
database e il mio ambiente di test e il mio
database reale nel mio ambiente di produzione
questo è ciò che configuri e poi a
runtime
si può guardare in alto e sarà iniettare in
lì l’implementazione configurata così
è fantastico che in realtà mi aiuti
nel mio ambiente di test prendi il mio in scatola
restituire e va bene se solo io
ho un test ma voglio testarne alcuni
i casi limite voglio testare cosa
succede quando colpisco il database e
non c’è risultato trovato e quello c’è
più risultati e che un
l’eccezione è lanciata e al momento è
sempre solo restituendo lo stesso in scatola
risultato in modo da poter creare una logica nella mia
falso ma l’unico modo in cui posso guidare il
logica viene dell’ingresso nel
funzione e in questo caso è il
ID cliente in modo da poter aggiornare il mio falso a
dire qualcosa di simile se l’ID cliente è
uno e restituito il risultato in scatola se
l’ID cliente è due
un risultato vuoto se si tratta di tre passi uno
eccezione e così via, ma è abbastanza
difficile da mantenere ciò che esprime
il codice base e dal guardare un’unità
test potrei non sapere quale ramo di
quel falso sta per essere eseguito e
col tempo quel falso potrebbe essere abbastanza
complesso e potrebbe non sapere quale
i rami sono effettivamente mai eseguiti e
allora comincio l’unità testando i miei falsi
e la complessità può crescere così mentre
usare i file di configurazione ti dà un bel po ‘
di flessibilità se si dispone di un ricco insieme di
scenari di prova potresti trovare il tuo
i falsi diventano piuttosto complessi di per sé
quindi un’altra opzione a cui potresti pensare
sta usando una libreria di derisione e una di
quelli che ho usato sono chiamati mock e
in questo modo sei in grado di definire il
comportamento del tuo tuo finto proprio lì
nel test unitario dove forse è più
rilevante in modo da utilizzare i mock come dipendenza
lo aggiungi alla tua dipendenza mista
file e manterremo il nostro stesso design per
inversione di dipendenza, ma non lo facciamo
in realtà bisogno di creare il falso
database noi stessi possiamo prendere in giro
fallo per noi in modo che possiamo effettivamente rimuoverlo
la forma di database falso della foto noi
ancora bisogno di avvolgere una vera chiamata al database
aderendo al comportamento che abbiamo definito
vogliamo ancora configurarlo nel nostro
prodotti in modo che il suo tempo di esecuzione
produzione userà il vero database
ma nella nostra configurazione di test dichiareremo
che vogliamo usare una richiesta di simulazione e
questo in realtà può avere qualsiasi nome che ti piace
perché stiamo andando a prendere in giro
crealo per noi e lo facciamo nel nostro
Test Helper, possiamo salvare mock per favore
creami un modulo chiamato mock request
che implementa le loro richieste di database
comportamento in fase di esecuzione vedremo quale
l’implementazione che vogliamo utilizzare affinché funzioni
per i pungoli e nei test usando il falso
uno e nei nostri test unitari che dichiariamo
che vogliamo utilizzare le richieste di finte
che mazze ha creato e poi noi
fornire le nostre aspettative così eccoci qui
dicendo quando quel falso che prende in giro
creato è nascosto e la funzione richiesta
viene invocato e restituisce una tupla
contenente uno stato ok e una lattina
risultato che abbiamo dichiarato altrove
quel file se dimentichi di fornire il
aspettatevi un’eccezione
e questo è un buon feedback e ho anche
ho scoperto che mi ha aiutato a capire come
molti strati attraverso il codice i miei test
sono effettivamente in esecuzione perché a volte
non ti rendi conto che stai per colpire
il database perché sei la tua mente
prova qualcos’altro ma poi lo farai
ottieni un’eccezione come questa che ricorda
tu oh sì, questo flusso sta andando davvero
colpire il database quindi c’è sicuramente
somiglianze tra creare il tuo
config e i tuoi falsi e utilizzo
qualcosa come mock per aiutarti ma io
pensare uno dei principali vantaggi di
usando la libreria di derisione sei tu
definire il comportamento di ritorno proprio lì
nei tuoi test quindi come sviluppatore quando
stai guardando attraverso i casi di test
è molto più chiaro e cosa sta succedendo
capita quando queste dipendenze vengono colpite
e non è necessario andare a un file falso
da qualche altra parte sul tuo albero dei file e prova
e capire quale ramo di quello
i falsi stanno per essere eseguiti l’unico
un leggero margine disordinato è che i mazzi si mescolano
sputerà un avvertimento perché lo sei
riferendosi a un modulo che non lo fa
esiste fisicamente sul tuo albero dei file
perché il mock lo ha creato sul
Vola per te ma penso che i vantaggi
superano quello in termini di dipendenza
inversione che ha separato il nostro
moduli di alto livello dal nostro dettaglio
dei nostri moduli di basso livello che siamo stati in grado
per entrare e uscire diversi
implementazioni che ha fornito
una maggiore flessibilità per i test può farlo
scrivi bene l’elisir solido che abbiamo appena fatto
abbiamo applicato ogni singolo solido
principio alla nostra base di codici di elisir e
tutto funziona ancora bene penso che il
la vera domanda è questa idiomatica
elisir o abbiamo appena finito con a
base di codice funzionale che assomiglia
qualcosa come il codice Java sono queste regole
le giuste regole da applicare al nostro
paesaggio funzionale
Intendo le caratteristiche di un oggetto
linguaggio di programmazione orientato sono
diverso da quello funzionale ma
tra l’ altro in te funzionale
tendono a passare i dati intorno alla maggior parte di
il tempo mentre un oh stai reagendo
ai messaggi inviati tra
oggetti diversi quindi penso al solido
i principi ti aiutano sicuramente
ma potremmo aver bisogno di adattare alcuni di loro
leggermente per allinearsi con i tratti del
linguaggi di programmazione funzionale con
manutenibilità in mente
sembra utile aderire al
avere un principio di responsabilità unica
le piccole funzioni focalizzate sono altrettanto buone
elisir come in qualsiasi programmazione
linguaggio oh o funzioni funzionali sono
i mattoni di un funzionale
la lingua in modo da avere piccole funzioni saranno
portare a un potenziale riutilizzo, se lo sei
li avvengono insieme passandoli dentro
e così fuori dal è il mio punto di vista s
completamente implementato in un linguaggio funzionale
per quanto riguarda l’ apertura / chiusura sembra a basso rischio
essere in grado di aggiungere al tuo codice base
senza toccare alcun codice esistente
perché questo ridurrà ogni nuovo test
sforzi in elisir abbiamo un ordine elevato
funzioni in modo che possiamo passare le funzioni in
altre funzioni per cui potresti discuterne
nei linguaggi funzionali è in realtà
più facile aderire a quello aperto-chiuso
principio perché puoi solo passare a
nuova funzione in qualche codice esistente
senza toccarlo quindi penso
aprire / chiudere è un buon obiettivo per cui lottare
per quanto riguarda la sostituzione di Lisco, abbiamo visto come
nel nostro mondo questo tende a sfruttare il
modello di ereditarietà che in realtà non lo facciamo
usa molto nel mondo funzionale così
forse è questo che dovremmo ridefinire
leggermente una delle cose funzionali
i programmatori si impegnano per la purezza e
funzioni pure sono deterministici hanno
avere un input e un output e dati
lo stesso input che darà sempre
indietro lo stesso output senza nessun altro
effetti collaterali quindi abbiamo una funzione pura
qui che aggiunge semplicemente due numeri
insieme possiamo usarlo in una funzione
chiamato numero fortunato e possiamo derivare
quale sarà l’uscita del numero fortunato
e in questo caso l’out
sta andando sempre di essere il numero sette
quindi se ho passato attraverso il codebase e
sostituito ogni volta che ho chiamato fortunato
numero con il valore sette il mio programma
dovrebbe ancora funzionare esattamente com’era
perché il risultato della valutazione
espressione sta per avere lo stesso
valore matematico come codice di partenza
e questo è noto come referenziale
trasparenza quindi vorrei proporci
modificare la definizione di Lascaux
sostituzione e sostituirlo con
trasparenza referenziale come a
modello di sostituzione e che sarà più
in linea con il funzionale
caratteristiche nella nostra programmazione noi
vide che la segregazione interfaccia è stata
su come mantenere le tue interfacce piccole e
conciso e abbiamo fatto lo stesso con il nostro
comportamenti e nell’elisir
documentazione in realtà afferma che se
devi pensare a un comportamento
così come è simile a un’interfaccia Java
Penso che ciò confermi il mio punto di vista
dovremmo applicando l’interfaccia
principio di separazione delle interfacce al nostro
comportamenti elisir e poi abbiamo visto D e
abbiamo visto come creare un’astrazione
tra i nostri strati di alto livello e il nostro
strati di basso livello permesso scambiare in
e fuori diverse implementazioni e
che ha particolarmente aiutato durante i test
con sistemi esterni così in futuro
data forse abbiamo bisogno di lavorare in alcuni di
questi altri tratti linguaggi funzionali
sono linguaggi funzionali immutabili
favorire la ricorsione oltre l’imperativo
looping e in elisir abbiamo schema
corrispondendo così nel tempo che possiamo costruirne alcuni
di queste cose in altre ancora
principi che sono rilevanti per il nostro
mondo funzionale in modo da tornare al
titolo del discorso molti di quelli che
considerarsi un funzionale
programmatore tendono a spazzare via il
gli insegnamenti della comunità così andando
all’estremo ed effettivamente costringendo
questi principi di oo sul mio codice di elisir
base in realtà ho trovato molti di loro realizzati
senso e il risultato è stato più conciso
codice più mirato che è stato più facile
test e indipendentemente da ciò che consideriamo
per essere codice idiomatico possiamo probabilmente tutto
d’accordo che dovremmo scrivere il codice
quello
facile da aggiornare e facile da mantenere
gli straordinari è così unica responsabilità
sicuramente applicabile nel funzionale
mondo finito
aprire / chiudere è un buon obiettivo per cui lottare
abbiamo sostituito L con Artie per referenziale
trasparenza per riconoscere la purezza
della lingua possiamo applicare il
principio di segregazione dell’integrazione al nostro
Comportamenti di Alexa e possiamo usare
iniezione di dipendenza per aiutare con il nostro
testare quindi forse la base per
potrebbero essere i principi di progettazione in elisir
ordinato vi ringrazio molto
[Applausi]

Please follow and like us: