
(musica rilassante)
Oggi parleremo di emergenti
buone pratiche in Swift.
Prima di iniziare voglio iniziare con una storia.
La scorsa estate è stato annunciato Swift e poi rilasciato
ed ero eccitato, perché non mi piaceva
Objective-C.
Sono andato in giro a parlare di Swift, e in particolare
su come risolvere problemi familiari in modi nuovi
perché abbiamo questa nuova lingua.
Sarebbe un peccato non approfittarne
delle nuove cose che Swift può fare.
Stavo dicendo a tutti di non trattare Swift come Objective-C
ed è perché ero terrorizzato che eravamo solo
andando a risolvere i problemi nello stesso modo che abbiamo sempre
li ha risolti con Objective-C, ma usando la sintassi Swift.
Questo non mi piaceva perché lo ero
così entusiasta di Swift che l’idea di non prendere
pieno vantaggio delle nuove novità che Swift può fare
mi dà solo i brividi
Ma è risultato che tutto andava bene.
La community e Apple hanno superato le mie aspettative
in termini di ciò che avevo sperato.
Abbiamo abbracciato Swift e usato le sue capacità per
esplorare i nuovi modi in cui possiamo risolvere il familiare
problemi a cui siamo abituati.
Problemi che esistono su iOS indipendentemente dalla lingua
usate.
Abbiamo effettivamente dato un’occhiata e trovato nuovi modi
che non avevamo idea. Nessuno sapeva come fare prima
e l’abbiamo capito.
Quelli sono diventati le migliori pratiche.
Come parliamo delle migliori pratiche in Swift?
Questa non è una lista di un discorso.
Non ho intenzione di darti le 13 migliori pratiche
in Swift, il numero quattro ti farà impazzire.
Non è quello che sono qui per fare.
Sono qui per due motivi:
1) Che aspetto hanno le migliori pratiche?
2) Come trovarne di nuovi?
Penso che quelle siano domande interessanti
Ho intenzione di menzionare alcuni argomenti tecnici
e ci sarà del codice sulle diapositive,
ma principalmente questo è un discorso per cercare di innescare tutti noi
cercare modi interessanti
per risolvere problemi familiari.
Più importante di una lista è il processo
di come ci arriviamo.
Per scoprire quel processo e discuterlo
stiamo andando a discutere di cinque cose.
1) Dai un’occhiata alla storia
della comunità iOS.
Siamo stati in una situazione simile
prima. So che questa è la prima volta che Swift è mai stato fuori
ma abbiamo visto cambiamenti come Swift venire prima.
2) Parla dell’apprendimento (e come dovresti farlo
sempre, non solo quando Xcode è in un periodo beta).
3) Non buttare mai le idee
(sono molto preziosi).
4) Sforzati di pensare
(è così che ti vengono in mente le nuove migliori pratiche).
5) Astrazione.
(Sono eccitato.
Questo sembra familiare).
Ci siamo già trovati in una situazione simile a Swift.
(Prima di entrare esattamente in quello che avevo bisogno di dissipare
un malinteso comune).
(Probabilmente hai già sentito questa espressione prima:
“Coloro che non studiano la storia sono condannati a ripeterlo”)
(destra?)
(Questo è stato detto da molte persone, ho cercato di trovare
una citazione originale per questo per scoprire chi l’ha detto per primo,
non potrei farlo).
(È stato detto per almeno 300 anni,
probabilmente più lungo di quello;
è deprimente).
Pensaci, “Coloro che non studiano il passato
“sono condannato a ripeterlo.”
Chi non conosce la storia è condannato a ripeterlo:
quello è triste.
Ciò implica che la storia ha solo degli errori
e quella storia che si ripete è necessariamente una brutta cosa.
Quello non è vero.
Possiamo pensare a cose nella storia recente
o ancora più tempo fa erano buone idee, idee che noi
voglio continuare a fare o idee che vorremmo ripetere.
Non è giusto dire che quelli che non lo sanno
la storia è destinata a ripeterla, perché la si ripete
non è necessariamente una brutta cosa
Una mia opinione sarebbe più accurata,
“Chi non capisce il passato non può fare
“decisioni informate sul presente”.
(Storia).
(Posso vedere una dimostrazione delle mani di tutti coloro che hanno sviluppato per
iOS 5 o precedenti?)
(freddo).
Quello che sto per mostrarti potrebbe suscitare dei ricordi
che preferiresti non ricordare.
Per tutti gli altri nella stanza la seguente diapositiva
può sembrare scioccante. Prima di iOS 5 non avevamo
letterali oggetto; questo è il modo in cui abbiamo creato gli array,
dizionari,
e NSNumbers.
(Terribile)
Gli array hanno questo arrayWithObjects,
a proposito, questa è la sintassi a mano corta.
Hai questo elenco di cose terminato nil
dictionaryWithObjectsAndKeys
e numberWithInt, numberwithBool, numberWithFloat,
numberWithLong.
Era noioso e se lo fossi
facendo questo prima di ARC è ancora peggio.
Alcuni di voi avranno notato, ma in realtà lo sono
un errore su questa diapositiva perché dictionaryWithObjectsAndKeys
gli oggetti vengono prima; la chiave è “non io”
e il valore è “Chi lo farebbe?”, che è al contrario.
Ho fatto questo errore alcune volte.
(Sospira)
Sono così felice che non dobbiamo più farlo.
(Ora, lo facciamo).
Abbiamo letterali oggetto, gli array sono creati con
un @ e poi parentesi quadre,
dizionari @ parentesi graffe,
NSNumbers sono creati utilizzando
espressioni in scatola (metti @ l’espressione che viene
dopo viene valutato come un numero).
Questo è un enorme miglioramento.
Sono migliori
Universalmente meglio.
Non c’è una ragione per cui non lo faresti
voglio usare oggetti letterali. (Non ho
stato in grado di pensare a uno).
Sono stati adottati dalla comunità quasi immediatamente
tutti passarono a questi perché non c’era ragione
non a e Xcode aveva una funzione integrata
dove lo farebbe per te.
L’uso di letterali oggetto è diventato ciò che potreste chiamare
una buona pratica.
Cos’altro è uscito
un anno prima degli oggetti letterali?
(Qualcuno ha una supposizione di quello che sto per dire?)
Blocchi.
I blocchi sono usciti nel 2010 per iOS 4.
I blocchi erano fantastici, ero eccitato per i blocchi.
Introdotto in iOS 4, adottato lentamente ma sicuramente.
I blocchi sono eccitanti perché richiedono
un nuovo modo di pensare.
Prima c’era il codice eseguibile a cui si poteva fare riferimento
come dati, non potresti risolvere i problemi in certi modi.
Sei stato limitato dalla lingua.
Quando sono usciti i blocchi, lo hanno fatto
una strana sintassi ed era difficile anche adottarli,
ma anche gli sviluppatori iOS erano abituati a risolvere i problemi
senza di loro.
Eravamo abituati a risolvere problemi con i protocolli,
e delega, o azione mirata, o un numero qualsiasi di modi.
L’utilizzo dei blocchi è diventato una best practice?
Sta usando
una dichiarazione se una best practice?
I blocchi sono solo sintassi.
Consentono altre buone pratiche.
La chiave qui sta usando i blocchi
e dicendo: “Oh, usa un blocco perché è meglio
di una delegazione o un’azione mirata, “
(non il punto).
Il punto è con i blocchi che possiamo fare cose interessanti.
Possiamo fare la programmazione funzionale del reattore,
oppure possiamo eseguire un blocco di codice in un contesto,
per esempio, un’animazione.
Prima, se volessi animare qualcosa, lo faresti
chiama un metodo che dice “Sto iniziando l’animazione”
e poi cambieresti le cose, e poi l’avresti fatto
meglio chiamare un metodo alla fine che dice,
“E ora l’animazione è finita.”
(Questo è strano).
Se dovevi essere avvisato di quando quell’animazione
era completo, è molto lavoro.
Potremmo anche richiamare quando
è stata consegnata una risposta di rete asincrona.
Operazioni di raccolta, ora possiamo enumerare
una collezione (ad esempio una serie di cose), o potremmo mapparla
in una serie di qualcos’altro.
Nuove idee al momento.
Anche alcuni di loro sono ancora nuovi per iOS.
Ma sono abilitati solo da blocchi.
Queste potrebbero essere le migliori pratiche. Ma blocchi? No.
Il mio punto è: abbiamo abbracciato il cambiamento.
Abbiamo i blocchi e siamo come,
“Facciamo qualcosa con loro.”
Ci sono voluti cinque anni per arrivare dove siamo ora,
ma sono orgoglioso ed emozionato
che abbiamo realizzato come una comunità in quel tempo.
Abbiamo una storia di prendere la nuova tecnologia
che Apple ha fornito lo sviluppo iOS
e facendo cose incredibili con esso.
Questo ci porta a Swift 2.
Swift 2 è la seconda versione della programmazione Apple
lingua, prima annunciata e rilasciata lo scorso anno.
(Emozionante, ero entusiasta di Swift).
(Più uso Swift 2 più mi piace).
Swift 2 include una nuova sintassi.
La nuova sintassi ci consente di fare cose nuove (come il nuovo blocco
la sintassi ci permette di fare cose nuove con i blocchi).
Ma la sintassi è solo uno strumento.
Come i blocchi, la nuova sintassi di Swift non è qualcosa
puoi classificarti come una buona pratica (perché non è così
ha senso).
Cose come dichiarazioni di guardie o dichiarazioni di differimento,
o lanciando con nuova gestione dell’aria.
(urlando in sottofondo)
(ride)
Queste sono sintassi, ma non c’è
una buona pratica di lancio di qualcosa
(ad es. l’uso del differimento non è una buona pratica).
Una domanda che potresti chiedere è: “Devo usare la guardia?”
(Ma questa non è la domanda giusta, vero?)
La domanda giusta è: “Cosa posso fare con la guardia?”
Ora che ho questa nuova funzionalità e questa nuova sintassi
cosa posso fare con esso?
(una domanda molto più interessante).
Diamo un’occhiata ad alcuni esempi.
Prima di tutto, abbiamo la piramide del destino.
(chiamato perché ha questo triangolo o piramide
arrivando da sinistra, strisciando verso destra).
Sono sicuro che hai scritto tutto il codice in questo modo (ne sono sicuro).
Scrivere codice come questo è facile (ma scrivere codice
è sempre facile).
La parte difficile è leggerlo.
Questo codice (in particolare con la piramide di Doom)
lo rende ancora più difficile di quanto non debba essere.
Istruzioni if / let composte da Swift 2 interstotto
e dove clausole.
Abbiamo qualcosa di simile ora.
Questo è un codice semanticamente identico, ne stiamo vincendo due
variabili, due variabili opzionali e abbiamo una clausola where
che ovvia alla necessità di una delle dichiarazioni if.
Diamo un’occhiata a un altro esempio.
Mutabilità, questo è molto codice Objective-C
(questo era ciò di cui avevo paura quando Swift uscì).
Avevo paura che le persone scrivessero questo Swift.
Questo è Obective-C nella sintassi Swift e sembra terribile.
(Non ho intenzione di andare oltre quello che fa,
perché non importa
è terribile).
Quello che vogliamo scrivere è qualcosa del genere.
Questa è la stessa funzione, richiede una serie di stringhe,
e prende un prefisso e ti restituisce uno di quelli
stringhe che gli hai dato che iniziano con il prefisso
(questo è tutto ciò che fa).
Meno digitando, più espressivo.
Forse è facile da scrivere,
ma è più facile da leggere.
È più espressivo.
Un’altra cosa di cui voglio parlare è il curry.
(Questa è una di quelle strane parole che potresti aver sentito
e potresti averlo evitato perché alcuni di questi mi piacciono
i guru della programmazione funzionale sono cretini
e lo usano molto).
In realtà è uno strumento utile;
non è complicato come potresti pensare.
Il currying è utile quando hai una funzione,
e un’altra funzione, … e fanno quasi la stessa cosa.
(utile per fornire
personalizzazione a una funzione).
Diamo un’occhiata a un esempio.
Ho una funzione chiamata containsAtSign.
Prende una stringa, restituisce un valore booleano e restituisce true
se quella stringa contiene un segno di segno (abbastanza diretto).
Ora hai una serie di stringhe chiamate input,
li filtrate in base a quelli che contengono un segno.
Perché abbiamo una funzione (le funzioni sono identiche
semanticamente alle chiusure e alla funzione filtro
prende una chiusura che va da qualunque cosa ci sia nella matrice
a un booleano), possiamo passare un riferimento alla funzione
direttamente nella chiusura del filtro.
(Questo è bello, è fantastico, ma può essere anche meglio).
Diamo un’occhiata al curry.
Ora, invece di una funzione contiene Attign che abbiamo
una funzione contiene.
Prende una sottostringa e restituisce una chiusura.
Quella chiusura va da una stringa a una booleana.
Puoi vedere la chiusura che stiamo tornando
all’interno della funzione prende una cosa chiamata stringa
restituisce un booleano e fa la stessa identica cosa, eccetto
ora invece di un segno letterale stiamo usando la sottostringa
parametro passato nella funzione originale. Noi possiamo
puoi chiamarlo così
Invece di avere una funzione per contiene AtSign,
una funzione per containsPercentSign, una funzione
per contieneDollarSign abbiamo solo una funzione contiene,
diamo un po ‘di personalizzazione di cui ha bisogno
e fa il resto per noi.
Questo è potente ed è così importante per Swift
sviluppatori di Apple. Non intendo, “I am a Swift
“sviluppatore”, le persone che sviluppano Swift,
che hanno introdotto uno zucchero sintattico per questo.
Questa è un’espressione semanticamente identica.
Passa da una sottostringa e ti restituisce una chiusura
che va da stringa a bool (sembra divertente
all’inizio, ma ti sto dicendo la prima o la seconda volta
lo fai ci si abitua velocemente
ed è così divertente).
Un’altra cosa interessante che Swift ci ha lasciato fare,
Swift 1 pari, valori associati alle enumerazioni.
Si crea un enum a cui si attribuisce un valore associato
e si estrae quel valore attraverso una dichiarazione del caso.
In Swift 1, le dichiarazioni di un caso erano disponibili solo all’interno
di un blocco interruttore.
Scriveresti codice come questo.
Hai un enum in cima, ha un successo e un fallimento.
Se fallisce vorremmo sapere perché.
Abbiamo un valore associato, una ragione.
È una stringa che possiamo presentare all’utente
sul perché qualcosa non ha funzionato
Di ‘, c’è una funzione chiamata doThing, restituisce
uno di questi risultati se è un successo, quindi stampiamo
(tempo di festa); se non lo è, possiamo estrarlo
la ragione del caso e stampala anche tu.
Questo è stato grandioso, ma Swift 2 è diventato ancora migliore perché
ci permette di prendere le dichiarazioni del caso al di fuori degli interruttori.
Se non ci interessa il caso di successo, se ci interessa solo
se qualcosa è andato storto possiamo scrivere un codice come questo.
Possiamo dire se è un fallimento quindi estrarre la ragione.
Di nuovo, è una sintassi non familiare, ma non lo è
sintassi complicata.
Questo è qualcosa che possiamo adottare facilmente.
È una buona pratica?
No, solo sintassi.
Cosa importa che possiamo usare le dichiarazioni dei casi
al di fuori delle dichiarazioni switch?
è più facile da fare (che è bello).
Potrebbe consentirci di fare le cose più facilmente o rapidamente.
Ciò che conta sono le idee.
Swift 2 introduce una nuova sintassi che ci consente di fare
cose nuove, e dobbiamo cercare il nuovo
cose che ci lascia fare.
Ad esempio, sono sicuro che molti di voi ne hanno sentito parlare
parola d’ordine che va in giro “programmazione orientata al protocollo”.
Cosa significa?
è un’idea interessante che Apple ha ideato
attorno all’utilizzo di protocolli anziché gerarchie di classi
contenere informazioni (interessanti).
Diventerà la migliore pratica?
Può essere. credo
sembra bello
Sfortunatamente, non ho tempo di entrare in questo momento,
Ti incoraggio solo a guardare il video del WWDC.
Apple ha idee interessanti su ciò che una buona pratica
potrebbe sembrare in Swift.
Scommetto che anche altre persone hanno idee. Andiamo a chiedere a loro.
Ci sono altre comunità là fuori oltre a iOS,
oltre a Objective-C e Swift.
Apple ha chiaramente preso le mosse da altre programmazioni
lingue (Ruby, JavaScript e Scala).
Ci sono tonnellate di comunità là fuori
che hanno sintassi simile e capacità simili a Swift.
Mi chiedo quali soluzioni e quali migliori pratiche
lavoro per loro, e perché?
Le soluzioni usano qualcosa che potremmo usare?
Sono le soluzioni che scelgono di non usare
qualcosa che è appropriato per noi?
Dovremmo andare a chiedere loro, o meglio ancora dovremmo
uscire e imparare Python per un fine settimana,
è stato sulla mia lista delle cose da fare per un anno,
solo per vedere cosa fanno e vedere se alcune di quelle idee
può essere portato a Swift.
Come fai a sapere se qualcosa è solo un pezzo di sintassi
o se è un’idea che può diventare una buona pratica.
Non puoi.
Ti ho mentito, è una dicotomia molto falsa.
non c’è niente di giusto o sbagliato, non c’è nulla che dice
Questa è la sintassi, ma questa è un’idea.
è la dichiarazione if / else che ho menzionato prima.
Usare una dichiarazione if è una buona pratica o è sintassi?
Sono entrambi.
Come faresti le cose senza dichiarazioni?
Quello che sto cercando di dire è: abbiamo
andare a provare cose.
Devi provare le cose e vedere, forse funzioneranno
forse non lo faranno, ma non lo sapremo fino a quando non ci proveremo.
Il che ci porta a “Non buttare via idee”.
Swift è stato rilasciato e l’ho trattato
come oggetti letterali invece di blocchi.
L’ho trattato come qualcosa che dovremmo usare sempre
perché è universalmente migliore e ho buttato via
le idee che aveva l’Objective-C.
Alcune di queste idee meritano di essere tenute, per esempio, Swift
non ha ancora una sostituzione per l’osservazione del valore chiave.
Questo è qualcosa che dobbiamo ancora usare
il runtime Objective-C per.
Anche le idee più vecchie hanno valore.
Anche se una comunità, forse c’è qualcosa di interessante
in Cobalto sarebbe fantastico da implementare in Swift.
Non lo so, perché non ho imparato il cobalto,
Non lo farò, ma sai che vale qualcosa
esplorare e vale la pena riflettere.
La tragedia è che gli sviluppatori di iOS buttano via le cose
tutto il tempo.
In generale, gli sviluppatori lo fanno, ma gli sviluppatori iOS
fallo molto
Perché?
Alla fine ci arriveremo, ma voglio prenderti
attraverso un modello che ho notato nel mio
carriera (e forse l’hai notato nel tuo
o anche altri).
Abbiamo un principiante, non hanno mai programmato prima
e stanno imparando iOS.
Imparano qualcosa (ad es. Objective-C)
e sono cattivi (perché sono principianti)
e i principianti sono cattivi alle cose
(è così che impariamo: essere cattivi e migliorare).
Danno la colpa alla loro frustrazione
sulla cosa, lo assumono perché sono frustrati
con esso e sono cattivi, che deve essere cattivo.
Ma, ottengono più esperienza. Imparano l’obiettivo-C
e iOS, e poi Swift esce.
Imparare la nuova cosa è più facile
che imparare la vecchia cosa.
Suppongono che sia perché la nuova cosa è migliore,
ma in realtà è anche perché loro hanno
più esperienza ed è più facile imparare le cose.
Hanno mescolato queste due idee (hanno attraversato fili
nel loro cervello avevano una cosa vecchia che era difficile
per imparare perché erano alle prime armi, hanno un nuovo
cosa che è facile da imparare in parte perché hanno
più esperienza).
Questo è il motivo per cui le nuove idee sono allettanti.
Ecco perché le nuove e brillanti API che escono ogni anno
sono eccitanti mentre i vecchi sono così terrificanti
e lordo.
Diamo la colpa alla versione precedente di iOS.
È uno scherzo nella nostra comunità:
non vediamo l’ora di rilasciare il supporto per iOS 9,
non posso aspettare per iOS X.
iOS è in continua evoluzione; Apple ci fornisce sempre
con le nuove API. Ciò significa che c’è una costante
fornitura di vecchie API per farci arrabbiare
e per noi la colpa.
Non penso che lo stiano facendo apposta;
Penso che Apple stia facendo del suo meglio per darci API
che ci consente di creare applicazioni interessanti,
perché questo li renderà soldi.
Questo è un effetto collaterale, non qualcosa
dobbiamo vergognarci;
è qualcosa che sarebbe bello riconoscere
e renditi conto che
se ci vediamo noi stessi a fare questo
forse fai un passo indietro e pensa a iOS 8
o 7, non è così male.
(Voglio prendere una traccia laterale.
Questo è qualcosa che ho pensato per molto tempo).
Voglio parlare del refactoring.
(Questo è un termine che sento sempre, persone su Twitter
refactoring del controller di visualizzazione o refactoring di un oggetto
in alcuni oggetti più piccoli, forse parlano di
refactoring di un intero progetto nel fine settimana).
(Continua ad usare quella parola, non penso che tu sappia cosa significa,
“Non penso significhi cosa pensi che significhi.”)
Cosa non è un refactoring?
Se stai aggiungendo nuove funzionalità
quello non è un refactoring.
Se stai modificando l’interfaccia pubblica per il tuo tipo,
quello non è un refactoring.
Un refactoring non modifica il comportamento di un tipo.
Se fosse abituato a fare qualcosa e non lo fosse più,
o se non lo fosse e ora lo fa non è un refactoring.
questa è una riscrittura.
Questo è un test molto semplice.
Devi cambiare un test unitario.
Se lo fai, allora è una riscrittura, se non lo fai
allora stai effettivamente rifacendo qualcosa.
Perché questo importa?
Perché le riscritture sono cattive e questo non sono io
(qui nella parte anteriore della stanza, a chi importa
cosa penso).
Qualcuno molto più intelligente di me ha detto questo.
Ho letto questo articolo all’inizio della mia carriera e lo ha avuto
un grande impatto su di me.
Joel Spolsky ha scritto questo: Cose che non dovresti mai fare,
Parte 1: dedicata al software di riscrittura.
Non riscrivere mai il software.
Ora, conceduto questo post del blog stava discutendo
Netscape (un’intera applicazione,
non un controller di visualizzazione).
L’idea che non dovresti mai riscrivere
un controller di visualizzazione non trattiene l’acqua.
Ma, che cos’è un’applicazione ma solo una collezione
controller di vista?
Se non dovresti mai riscrivere le applicazioni,
forse dovremmo essere più attenti alla riscrittura
i nostri controller di visualizzazione.
Dovremmo favorire i cambiamenti incrementali.
Non penso che quel codice sia necessariamente prezioso.
Penso che il codice sia abbastanza inutile, e
il codice che scrivo ora non avrà
qualsiasi valore in un anno o dieci anni anche.
Lanciare il codice e sostituirlo con qualcosa
nuovo di zecca è pericoloso, perché ti manca il contesto
come quel codice interagisce con il resto del codice.
Ecco perché riscrivere è terribile, perché ci vorrà sempre
più di quanto pensi e farai sempre degli errori
che non prevedi.
Se non dovessimo buttare via le idee
o codice, le due cose che dovremmo
mai buttare via sono codice e idee.
Forse c’è qualcosa di interessante in Obejctive-C
che ancora non lo so, ma dovrei imparare in ordine
per farlo in Swift o portare l’idea a Swift.
Forse il mio progetto che è in Objective-C può rimanere dentro
È possibile scrivere Objective-C e qualsiasi nuova classe che aggiungo
in Swift.
Non devo buttare via tutto solo per abbracciarlo
la nuova cosa.
(Questo è il numero uno).
Parliamo dei test unitari.
Il test delle unità ti aiuterà a cambiare meglio il tuo codice.
Questi cambiamenti incrementali che ti sto chiedendo di fare
lo fai con i test unitari.
Voglio parlare di cosa significa.
Test unitario, argomento controverso
in iOS, non così controverso letteralmente da nessun’altra parte.
Siamo le uniche persone che hanno un
grosso problema con i test unitari.
I singoli sviluppatori sanno che le comunità
non mi piace, ma come iOS è allergico ad esso,
almeno questo è il modo in cui agiamo.
Ci arriveremo più tardi.
Innanzitutto, voglio presumere che i test unitari
è una buona idea
Se non sei d’accordo, parcheggia quella convinzione
e supponiamo che io abbia ragione solo per questa diapositiva,
e quello dopo, e quello dopo.
Non mi interessa molto dei test.
C’è questa idea “Non ho mai preso
“un bug a causa di un test unitario – test dell’unità
“non deve essere così prezioso”
Se l’unico valore che vedi
nei test unitari sono i test effettivi, quindi lo sei
manca il punto.
Mi interessa di più scrivere il test a causa del modo
quel test di scrittura cambia il modo in cui scrivo il codice.
Scrivere prove mi costringe a pensare a quello che sto facendo,
che è un po ‘importante, specialmente nel contesto
di come trovare nuove migliori pratiche.
Non possiamo trovare nuove migliori pratiche se non stiamo pensando
su di loro.
(ha senso, giusto?)
I test ci costringono a pensare così forse ai test unitari
ci aiuterà a scoprire le migliori pratiche.
Uno dei maggiori vantaggi dei test unitari
è che limita la portata del tuo oggetto
perché devi pensarci.
Se hai un oggetto che è complesso
e fa molte cose che è molto difficile da testare
e tu hai più probabilità di creare diversi oggetti più piccoli
ognuno fa una cosa individualmente, ma le fa bene.
È meglio perché ora hai più oggetti coesivi
quello fa solo una cosa e tu non hai un comportamento
che è accoppiato l’un l’altro.
Parte dell’oggetto dipende da quest’altra parte
ma dipende anche da questo. Dipende
come prima. Non hai quello
perché tutto è separato in singoli componenti.
Come limiti l’ambito?
Il modo migliore è controllare la tua interfaccia pubblica
e lo fai in congiunzione con qualcosa chiamato
iniezione di dipendenza che è la parola più spaventosa
nello sviluppo del software.
Iniezione di dipendenza?
(Non voglio farlo, non volevo nemmeno alzare lo sguardo
cosa significava).
L’ho cercato, sono andato su Wikipedia
ed è complicato
(non è, credimi, Wikipedia è proprio come,
se non sapessi cosa fosse un computer e te ne sei andato
a WIkipedia e ti ha detto che un computer è una macchina
di logica formale che processa input e blah, blah,
blah, blah, blah.
Sarebbe confuso, vero?)
Lo stesso con l’iniezione di dipendenza, non è così complicato
di un argomento.
L’iniezione di dipendenza è una parola di cinque euro
per un’idea da cinque centesimi.
(Ward sta ridendo perché usa molto questa espressione).
L’idea dell’iniezione di dipendenza,
la tua cosa non dovrebbe creare le cose di cui ha bisogno.
È così.
Lascia che ti ripeta: la cosa che stai facendo
non dovrebbe di per sé creare le altre cose di cui ha bisogno
farlo è un lavoro.
Diamo un’occhiata ad alcuni esempi.
Questo è quello che direi piuttosto standard
iOs visualizza il controller.
Ha un controller di rete e se hai caricato
recupera roba dalla rete.
Una volta fatto, un blocco di completamento
è invocato e mostra quella roba.
Molto semplice, non c’è niente di sbagliato
con questo controller di visualizzazione.
Ho scritto questo controller di visualizzazione molte volte.
Immagino che la maggior parte di voi abbia anche lei.
Come appare diverso con l’iniezione di dipendenza?
Guarda attentamente le diapositive;
vedi se riesci a capire la differenza.
(qualcuno manca?)
(è proprio lì).
Non stiamo più creando il controller di rete.
Invece, abbiamo un controller di rete,
è variabile perché dobbiamo impostarlo
a qualcosa più tardi.
È un controller di rete opzionale e ora quando
viewDidLoad è chiamato chiediamo al nostro controller di rete
per prendere roba. Quando è fatto invoca
il nostro blocco di completamento e mostriamo quella roba.
Questo è esattamente lo stesso, niente nel resto
della nostra classe è cambiato.
L’unica cosa che viene cambiata è la linea che definisce
il controller di rete.
Ci affidiamo a qualcun altro per creare la rete
controller per noi e darlo a noi.
Potrebbe essere un’altra parte della nostra app, magari in preparazione
per Segue.
Il controller di visualizzazione prima di noi ha creato una rete
controller per noi, o forse è passato in un riferimento
a quello che aveva.
Forse è un test unitario.
(Questa è la parte eccitante, e ci arriveremo
cosa significa in seguito).
L’iniezione di dipendenza non è così difficile.
I protocolli funzionano bene per questo.
Diamo un’occhiata a un ipotetico controller di rete
protocollo.
Ha una funzione, fetchStuff.
Accetta un blocco di completamento che chiama
quando fa il recupero.
Diamo un’occhiata a un controller di rete API.
Questa è una classe specifica conforme al protcol.
Ha la funzione fetchStuff.
(Non l’ho ancora implementato, ma puoi ottenere
l’idea di cosa farò).
Sto andando alla rete, fetchStuff,
e quindi invoca il blocco di completamento.
(Nel mio test unitario avrei qualcosa di simile.)
Un controller di rete di prova è conforme allo stesso protocollo.
Invece di andare a prendere dalla rete
usa i dati stubbed che conosco in anticipo
e invoca immediatamente il blocco di completamento.
Ora, posso configurare il controller di test, passarlo
il controller della vista e chiedi al controller della vista
fare qualcosa e testarlo è un comportamento.
Ho un protocollo (e
fa tutto), non mi interessa
ai fini dei test unitari.
Lo testerò in modo indipendente più tardi.
Ho un protocollo e sono conforme a tale protocollo
nella mia simulazione, questo controller di rete di test.
Faccio qualcosa che so cosa farà
in anticipo e so come mi aspetto la vista
controller per reagire.
Quindi, cerco di fare in modo che quella reazione
è quello che mi aspetto.
(Questa è tutta l’iniezione di dipendenza è).
L’uso di protocolli ti aiuta a limitare l’ambito
(perché hai un contratto chiaramente definito
su cosa dovrebbe fare il tuo oggetto individuale).
L’aggiunta di un metodo al protocollo diventa ora
una decisione.
Non hai accesso all’intero elenco di funzioni,
anche quelli interni che non dovrebbero sapere.
Se non è nel protocollo, non puoi chiamarlo
(affare).
Se vuoi chiamarlo devi prendere una decisione
per aggiungerlo al protocollo (va bene,
a volte ha senso).
L’iniezione di dipendenza è più utile di questo.
Parliamo di stato condiviso e singleton.
(Non so quale sia la reazione di Sal
sarà).
I singleton non sono poi così male,
se usi l’iniezione di dipendenza.
Diciamo che abbiamo questa funzione chiamata loadAppSetup.
(qualcosa che chiami quando l’app si avvia).
È responsabilità controllare e vedere,
“Ho lanciato prima?
“Se non ho lanciato prima di mostrare
“l’utente qualcosa”, forse un login sullo schermo
(che importa?)
Afferra qualcosa da NSUserDefaults
standardUserDefaults; se non è ancora successo
quindi chiama qualche funzione.
Come lo verificheresti?
Non ne ho idea.
Stai per eliminare lo standard UserDefault
e quindi impostarli per il test specifico.
Quindi, assicurati di eliminarli
in seguito (quindi non inquina il prossimo test che si esegue).
(sembra molto lavoro).
Iniezione di dipendenza ci dovrebbe iniettare
le impostazioni predefinite nella funzione (che è).
Questa è ora una funzione di facile utilizzo per le dipendenze.
Non essere un ideologo.
Non ha sempre senso fare le cose.
A volte hai bisogno di infrangere le regole e qualche volta
hai bisogno di imbrogliare.
A volte devi piegare le regole,
e a volte è necessario ignorarli del tutto.
Questo è come barare con quella funzione.
Direi, “stessa cosa, ma ho intenzione di fornire
“un valore di parametro predefinito di standardUnitDefaults.”
Ora, se non specificherò un parametro, verrà ripiegato
agli standardUserDefaults.
(È fantastico per la mia applicazione
perché è meno digitante per me).
Nei miei test unitari posso creare le mie impostazioni predefinite personali
che non sono quelli standard (non condivisi
con qualcun altro).
Posso iniettarli dentro
Ecco come appare loadAppSetup. Niente ha
cambiato dal resto della prospettiva dell’applicazione,
ma nei test unitari ora possiamo iniettarlo
e i nostri test diventano più semplici e diventano
isolato (che è quello che vuoi nei test).
Torniamo all’esempio del nostro controller di visualizzazione.
Usando lo stesso cheat potrei avere il controller di rete
proprietà impostata sul controller di rete dell’API,
ma in questo caso è fondamentale che io sia così
specificando che è conforme al protocollo.
Il controller di visualizzazione non ha ancora accesso
al controller di rete API effettivo.
Ha solo accesso al protocollo
(esattamente quello che vogliamo).
Nient’altro nel controller della vista è cambiato.
Potresti testarlo ora
creando il controller della vista, creando uno stub
o versione derisoria del protocollo del controller di rete
e iniettandolo dentro
Finché lo si inserisce prima che la vista sia caricata
quindi puoi testare il tuo controller (facile).
C’è questa sorprendente citazione di Mackenzie King,
primo ministro del Canada negli anni ’40.
Ha detto: “TDD se necessario, ma non necessariamente TDD”.
La gente lo ha paragonato a Winston Churchill del Canada
(che mi piace molto perché il suo stile di gestione
stava dicendo cose che erano così imperscrutabili
che non potevi essere in disaccordo con lui).
(Ovviamente, questo è quello che sto cercando di fare adesso).
Esaminiamo i test unitari.
Non testare le funzioni private, anche iniziare a segnare
le tue funzioni come private. Di default
sono interni, il che significa che puoi chiamarli
e non dovresti chiamarli.
Evitare di riscrivere, ove possibile,
e non testare la tua implementazione.
Ricorda che l’obiettivo del test unitario è quello di testare il comportamento
dell’interfaccia pubblica.
In un mondo ideale ogni oggetto ne avrebbe solo uno
funzione pubblica.
(Non viviamo in un mondo ideale, ma immaginiamo).
La scorsa settimana Justin Sirls ha avuto questo fantastico post
sull’utilizzo di mock parziali.
Un finto parziale è qualcosa di reale,
ma anche falso.
Nel nostro esempio non potremmo farlo perché abbiamo usato i protocolli;
diciamo che in base ai protocolli abbiamo usato la sottoclasse,
ma abbiamo solo sovrascritto alcuni dei metodi,
alcune delle funzioni.
Alcuni dei comportamenti sono reali e alcuni sono falsi.
(Lo confronta con le auto di prova.
Il collaudo delle unità è come testare la sicurezza delle auto.
Una finta sarebbe a
manichino di crash test, come lo chiami tu.
A quelli piacciono le persone con un po ‘di giallo
e cerchi neri, e sai, misurano la forza
che provano quando una macchina si schianta.
Questo è il nostro doppio, quelli sono utili).
(Un finto finto è qualcuno che indossa un costume di Halloween
sembra un manichino da crash di test.
Com’è utile per testare la sicurezza dell’auto?)
(Probabilmente non vuoi mandarli a sbattere contro un muro
e vedere se sopravvivono).
(Sarebbe molto meglio usare un pieno,
vero e proprio crash test di prova).
Perché gli sviluppatori di iOS non amano testare?
Penso che si tratti di questo:
non è familiare e nessuno ci obbliga a farlo
(una sciocca ragione per non fare qualcosa).
(Andare dal dottore non è familiare
e non mi piace farlo e mia madre non ha forzato
io per andare dal dottore tra 10 anni.
Forse dovrei andare dal dottore
se mi sento male anche se non mi piace.
è la stessa cosa con il test delle unità).
È buono per noi, anche se ci si sente
strano all’inizio.
(Non potrei inventare una metafora migliore, mi dispiace).
(ride)
I test mi hanno reso uno sviluppatore migliore
(Penso che ti renderà anche uno sviluppatore migliore
se lo provi).
Voglio fare il codice che è facile
per mantenere, che è facile da espandere in seguito,
e di cui sono orgoglioso.
Il test unitario mi aiuta a fare queste tre cose.
Ultima sezione del discorso, astrazione.
(“questo è già stato un discorso astratto,
“e ora parlerà di astrazione”).
Ho lavorato in un’azienda che ha detto questo,
“Se stai ripetendo due o più righe di codice,
“allora stai sbagliando, devi trovare
“un’astrazione e farlo in un modo migliore”.
(Che cosa?)
Creare un’etichetta e quindi aggiungerla alla mia vista
questo è due righe di codice.
“Estratto.”
(All’inizio era difficile da fare
ma dopo un giorno o due mi è piaciuto).
(Dopo alcune settimane sono tornato al mio vecchio progetto
e pensavo fossero banane, guarda tutto questo
codice duplicato, sto aggiungendo un’etichetta qui, e qui,
e qui, e qui).
(Era terribile, non mi piaceva.
E ora, provo a prenderlo a cuore.
Non lo faccio sempre, ma è qualcosa
Sto sempre cercando).
Stai già imparando nuova sintassi con Swift 2.
Cerchiamo nuove astrazioni lungo la strada.
Proviamo nuove cose.
Non tutte le idee funzioneranno, infatti,
molti di loro non lo faranno, ma dovresti farlo comunque.
La sperimentazione è personale
e benefici professionali.
È soddisfacente giocare con una cosa nuova.
Questo è il motivo per cui tutti scarichiamo i beta
di Xcode e prova a costruire cose con loro.
(è divertente provare nuove cose).
Facciamolo anche con le astrazioni.
È anche lo sviluppo professionale:
se troviamo qualcosa di nuovo che funzioni,
possiamo costruire un codice migliore
è meglio per i nostri datori di lavoro.
Questo è il caso che dovresti fare al tuo capo
quando lo è, “Perché stai scaricando la versione beta di Xcode?”
(è così che lo fai.
Una buona idea).
(Avevo un altro punto, ma l’ho dimenticato.
Anche se provi qualcosa e non funziona,
questo è il punto, ricordavo).
Anche se provi qualcosa e non funziona
capisci ancora quella soluzione.
(Prova la tecnica e ti scoppia in faccia).
Ora sai che non dovresti usare quella tecnica,
ma forse quella tecnica sarebbe preziosa
in un altro scenario, un’altra soluzione, un altro problema
altrove.
Quando provi qualcosa forse non funziona
ma tu impari ancora qualcosa.
Secondo me, è il caso dell’idea
che non esiste un esperimento fallito.
Se provi qualcosa e non funziona,
se hai un’idea e si scopre che hai torto,
hai ancora imparato qualcosa.
In questo modo è un successo.
Alcuni dicono che non c’è sempre tempo
sperimentare.
Hai tempo di crunch, ce l’hai
rilasciare il codice in pochissimo tempo.
(succede, ma è importante provare a sperimentare
quando puoi).
Quando non puoi più, ti ricadrà
a un diverso livello di astrazione.
(questo è un livello migliore di astrazione
di quando hai iniziato).
(Ho fatto un grafico.
Puntatore laser).
Puoi vedere l’inizio a questo discorso proprio ora.
Ti sto incoraggiando a sperimentare e provare nuove cose.
Stai per scrivere
test unitari lungo la strada.
(Stai migliorando molto),
Stai lavorando ad alto livello di astrazione
(è fantastico9.
È tempo di crunch, hai una scadenza,
devi spedire all’App Store.
Non hai tempo per scrivere i test unitari,
non hai tempo per esplorare, non hai tempo
provare nuove cose.
(Oh guarda!
tu sei lì, più in alto di dove
eri quando hai iniziato).
Puoi tornare a una posizione successiva.
Non è necessario scrivere sempre un test delle unità.
Non devi testare sempre, non devi
sperimentare sempre.
Ma quando sei abituato a sperimentare
e sei abituato a testare diventa più facile
in modo che tu possa farlo, puoi sperimentare
e continua a sperimentare e testare quando non lo fai
avere tanto tempo
Quando hai finito il tempo di crunch
puoi tornare indietro e farlo ancora un po ‘.
C’è sempre l’opportunità di imparare.
Dovremmo approfittare di queste opportunità.
Concludiamo
Abbiamo una storia, come comunità e come industria,
La community iOS ha una storia di esplorazione
nuove tecnologie: prendere qualcosa che è bello e nuovo
e costruendo cose incredibili con esso.
Lo abbiamo fatto con Objective-C,
con Swift (penso che continueremo a farlo).
Ora non è il momento di smettere di cercare nuove e fresche soluzioni.
L’apprendimento non è solo per quando Xcode è in beta.
(Solo perché Xcode 7 è fuori, Swift 2 è stabile …)
(ride)
(finito, finito).
Solo perché Swift 2 è finito, non significa che tu
non dovrebbe più cercare cose nuove e interessanti
puoi farcela.
Le idee sono più preziose del codice, ma nessuna delle due
di loro dovrebbero essere gettati via (gettando via
il codice è pericoloso).
Test di unità efficaci semplificano il cambiamento del codice
in modo incrementale.
Infine, se puoi operare al più alto livello
di astrazione puoi in qualsiasi momento
allora quando non puoi operare a quel livello alto
puoi ricorrere a qualcosa che è ancora meglio
di dove eri.
(questo è stato un discorso divertente per me per la ricerca
e pensa.
Ripensandoci
la mia carriera e alcune delle decisioni che ho preso.
Ho fatto degli errori e cose che avrei fatto
diversamente ora con il senno di poi, ma non me ne pento
uno qualsiasi degli errori che ho fatto perché ognuno di loro
mi ha aiutato ad imparare.
Finché penso all’errore in seguito
e imparare da esso, quindi non è una cosa negativa).
Il nostro obiettivo come sviluppatori di software non dovrebbe essere
non commettere mai errori
Il nostro obiettivo come sviluppatori di software dovrebbe essere quello di provare
e fare errori migliori domani.
Grazie mille.
(applausi)
– [Voiceover] Un paio di domande dal pubblico,
iniziare in fondo penso.
In MVVM, dovrebbe visualizzare i controller comunicare
con modelli di vista attraverso un protocollo, o sapere
il tipo concreto con cui hanno a che fare?
– Adoro come ho questa reputazione come MVVM,
come se non li menzionassi affatto,
sì, ed è come, “Oh una domanda su MVVMs.”
MVVM, recentemente ho convertito una gran parte della nostra base di codice,
questo è codice di base Swift per Model View ViewModel
e ho trovato i protocolli molto migliori,
perché mi ha aiutato a evitare la simulazione di una situazione parziale.
Se lo stub del test, come la sottoclasse che avresti,
non posso scegliere di non scavalcare qualcosa perché,
non c’è nulla da scavalcare, allora è meglio.
Non è possibile ricorrere accidentalmente a prestazioni reali
una richiesta di rete nei test dell’unità.
protocolli sicuramente, fino in fondo.
– [Voiceover] Giusto, e se non possiamo passare in oggetti
come passare un oggetto al controller della vista
ViewModel?
– Giusto, quindi questa è una domanda comune
chi crea il viewmodel?
è il controller di visualizzazione?
È il controller di visualizzazione che ha presentato questo?
È difficile e scende
alle preferenze personali.
Lo sto ancora cercando di capire.
A mio parere, mi piace il viewmodel che viene creato
dal controller della vista in un pigro blocco di chiusura.
E poi, se viene eseguito un test, allora può scavalcare
quella proprietà in modo che il viewmodel reale non venga mai creato,
in modo che il controller della vista usi sempre solo il test
guarda i modelli nei test unitari.
Il viewmodel stesso da creare
puoi averlo creato da un diverso modello di vista,
oppure puoi averlo creato dal controller della vista
questo è presentare questo.
Non importa; Ti incoraggio a sperimentare
e vedi cosa ti piace di più.
– [Voiceover] se avvii un nuovo progetto iOS
domani lo scriverai in Swift of Objective-C?
L’unica ragione per cui posso pensare di scegliere Objective-C
starebbe avendo un team di sviluppatori senza Swift
esperienza e una scadenza stretta.
Puoi pensare ad altri motivi?
– Sarebbe un grande,
Lo scriverei in Swift, prima di tutto, anche se lo avessi
una scadenza ravvicinata, ma ho fatto l’errore l’anno scorso
e non ha funzionato bene.
forse non ascoltarmi.
Parlane con la tua squadra, capisci
quanto sono familiari con Swift e quanto sono eccitati
devono imparare Swift.
Prendi una decisione insieme.
Non posso dirvi cosa fare perché non lo so
cosa è meglio per la tua squadra.
Non conosco le diverse priorità che hai,
e non conosco i diversi vincoli
in cui lavori.
se comunichi tra loro e capisci
cosa funzionerà meglio per tutti voi come squadra
questa è la soluzione migliore.
– [Voiceover] cosa ha fatto parentesi quadre
fare per offenderti così tanto?
– Le parentesi quadre non hanno fatto nulla per offendermi.
Sono abbastanza sicuro di sapere chi ha fatto quella domanda.
(ride) Esattamente.
Non odio le parentesi quadre.
Non odio i punti e virgola, non odio nessuno,
o niente.
Cerco di essere accomodante ora.
Ero arrabbiato.
Parentesi quadre
fanno alcuni tipi di programmazione,
come la programmazione reattiva funzionale
più prolisso di quanto debbano essere,
questo è quello che direi è il caso contro parentesi quadre.
– [Voiceover] Giusto, e naturalmente questi sono
anonimo quando il Canada sta per atterrare su Marte?
– Terra su Marte?
Abbiamo inventato il braccio spaziale,
il Canadarm.
A dire il vero, è in realtà quello che viene chiamato.
Era popolare nei giorni dello space shuttle
ed era come un braccio multi-articolato che poteva piacere
ruotare e afferrare come telescopi spaziali e cose
e piace fare cose con esso.
Grazie per averlo verificato.
Non so quando atterreremo su Marte,
ma so che se lo faremo sarà per il beneficio
di tutta l’umanità, come il nostro oratore principale stamattina
discusso, e non solo per il beneficio di una nazione.
(ride)
– [Voiceover] Altre domande dal pubblico?
– [Voce fuori campo] Ne ho uno perché hai parlato
facendo molti esperimenti, e alcuni di loro, ovviamente,
essere cattivo … – Nessun cattivo esperimento.
– [Voiceover] fine della produzione e qualcuno
li deve mantenere per molto tempo in seguito.
Se tutti stanno sperimentando tutto il tempo
allora ti divertirai a scrivere codice che penso.
– questo è vero.
Suppongo che avrei dovuto stipularlo se un esperimento
non funziona nel modo in cui pensi che dovresti
buttarlo via, o almeno non fonderlo in master.
Le idee sono–
– [Voiceover] di cui stiamo parlando, credo, funzionalità
fotogrammi esperimenti, non come facciamo cose strane
e vedi cosa succede
– Esattamente sono come gli spaghetti contro il muro
approccio, o qualcosa del genere.
Idealmente, lavoreresti agli esperimenti in
un parco giochi, non in un’applicazione di produzione.
È lì che lo faccio, quindi.
– [Voiceover] Ash. – Come va?
– [Voce fuori campo] Bene, com’è stato il tuo discorso per te?
– Un po ‘stanco. (ride)
– [Voiceover] semplicemente facile allora.
c’è stata una diapositiva eccitante in cui hai detto,
“a causa dell’iniezione di dipendenza
“Sono in grado di scrivere test per il mio codice, scrivo anche il mio codice
in un modo migliore. “
Non sono sicuro che lo dica parola per parola,
ma il … – questo è l’essenza generale.
– [Voiceover] E poi, come hai imbrogliato e solo in realtà
non ha cambiato il tuo codice attuale.
Ero un po ‘deluso, quindi puoi commentare?
– Certo, sì, quindi non ho cambiato il codice
perché l’intera classe era come otto linee e non c’è
non molto da cambiare.
Stavo cercando di mostrare quanto fosse semplice
fare un’iniezione di dipendenza e questo è un po ‘
un imbroglio, ma mi concentravo sulla pedagogia
esempio di insegnarti come fare l’iniezione di dipendenza
e non al momento come scrivere un codice migliore
con test unitari.
In quel caso specifico non sarebbe il
visualizzare controller necessariamente che sarebbe stato cambiato.
è il controller di rete, la cosa che fa
la richiesta di rete.
Se il controller della vista può accedervi solo attraverso
il protocollo chiaramente definito, quindi è meno probabile
chiamare le funzioni interne che non dovrebbe
essere consapevoli e in questo modo si ha un accoppiamento molto lento.
Il controller di visualizzazione e il controller di rete
non si conoscono l’un l’altro, se non attraverso esplicitamente
modi definiti e limitati.
Non fanno cose come il controller di rete
non è in grado di aggiungere una sottoview.
Il controller della vista non è in grado di analizzare JSON.
Queste sono due diverse preoccupazioni separate
e dovrebbero essere in classi separate
e la loro comunicazione reciproca dovrebbe essere
molto ristretto.
Penso che forse in una versione futura di questo discorso
forse uno che è invece di chiamarlo come,
“Fondere le migliori pratiche”, cosa succede se ho effettivamente un discorso
sui test unitari, forse vorrei approfondire questo argomento.
Grazie.
Dovrei ricordarti di valutare questa sessione.
Grazie ancora a tutti, sei stato un grande pubblico.
(applausi)
Oggi parleremo di emergenti
buone pratiche in Swift.
Prima di iniziare voglio iniziare con una storia.
La scorsa estate è stato annunciato Swift e poi rilasciato
ed ero eccitato, perché non mi piaceva
Objective-C.
Sono andato in giro a parlare di Swift, e in particolare
su come risolvere problemi familiari in modi nuovi
perché abbiamo questa nuova lingua.
Sarebbe un peccato non approfittarne
delle nuove cose che Swift può fare.
Stavo dicendo a tutti di non trattare Swift come Objective-C
ed è perché ero terrorizzato che eravamo solo
andando a risolvere i problemi nello stesso modo che abbiamo sempre
li ha risolti con Objective-C, ma usando la sintassi Swift.
Questo non mi piaceva perché lo ero
così entusiasta di Swift che l’idea di non prendere
pieno vantaggio delle nuove novità che Swift può fare
mi dà solo i brividi
Ma è risultato che tutto andava bene.
La community e Apple hanno superato le mie aspettative
in termini di ciò che avevo sperato.
Abbiamo abbracciato Swift e usato le sue capacità per
esplorare i nuovi modi in cui possiamo risolvere il familiare
problemi a cui siamo abituati.
Problemi che esistono su iOS indipendentemente dalla lingua
usate.
Abbiamo effettivamente dato un’occhiata e trovato nuovi modi
che non avevamo idea. Nessuno sapeva come fare prima
e l’abbiamo capito.
Quelli sono diventati le migliori pratiche.
Come parliamo delle migliori pratiche in Swift?
Questa non è una lista di un discorso.
Non ho intenzione di darti le 13 migliori pratiche
in Swift, il numero quattro ti farà impazzire.
Non è quello che sono qui per fare.
Sono qui per due motivi:
1) Che aspetto hanno le migliori pratiche?
2) Come trovarne di nuovi?
Penso che quelle siano domande interessanti
Ho intenzione di menzionare alcuni argomenti tecnici
e ci sarà del codice sulle diapositive,
ma principalmente questo è un discorso per cercare di innescare tutti noi
cercare modi interessanti
per risolvere problemi familiari.
Più importante di una lista è il processo
di come ci arriviamo.
Per scoprire quel processo e discuterlo
stiamo andando a discutere di cinque cose.
1) Dai un’occhiata alla storia
della comunità iOS.
Siamo stati in una situazione simile
prima. So che questa è la prima volta che Swift è mai stato fuori
ma abbiamo visto cambiamenti come Swift venire prima.
2) Parla dell’apprendimento (e come dovresti farlo
sempre, non solo quando Xcode è in un periodo beta).
3) Non buttare mai le idee
(sono molto preziosi).
4) Sforzati di pensare
(è così che ti vengono in mente le nuove migliori pratiche).
5) Astrazione.
(Sono eccitato.
Questo sembra familiare).
Ci siamo già trovati in una situazione simile a Swift.
(Prima di entrare esattamente in quello che avevo bisogno di dissipare
un malinteso comune).
(Probabilmente hai già sentito questa espressione prima:
“Coloro che non studiano la storia sono condannati a ripeterlo”)
(destra?)
(Questo è stato detto da molte persone, ho cercato di trovare
una citazione originale per questo per scoprire chi l’ha detto per primo,
non potrei farlo).
(È stato detto per almeno 300 anni,
probabilmente più lungo di quello;
è deprimente).
Pensaci, “Coloro che non studiano il passato
“sono condannato a ripeterlo.”
Chi non conosce la storia è condannato a ripeterlo:
quello è triste.
Ciò implica che la storia ha solo degli errori
e quella storia che si ripete è necessariamente una brutta cosa.
Quello non è vero.
Possiamo pensare a cose nella storia recente
o ancora più tempo fa erano buone idee, idee che noi
voglio continuare a fare o idee che vorremmo ripetere.
Non è giusto dire che quelli che non lo sanno
la storia è destinata a ripeterla, perché la si ripete
non è necessariamente una brutta cosa
Una mia opinione sarebbe più accurata,
“Chi non capisce il passato non può fare
“decisioni informate sul presente”.
(Storia).
(Posso vedere una dimostrazione delle mani di tutti coloro che hanno sviluppato per
iOS 5 o precedenti?)
(freddo).
Quello che sto per mostrarti potrebbe suscitare dei ricordi
che preferiresti non ricordare.
Per tutti gli altri nella stanza la seguente diapositiva
può sembrare scioccante. Prima di iOS 5 non avevamo
letterali oggetto; questo è il modo in cui abbiamo creato gli array,
dizionari,
e NSNumbers.
(Terribile)
Gli array hanno questo arrayWithObjects,
a proposito, questa è la sintassi a mano corta.
Hai questo elenco di cose terminato nil
dictionaryWithObjectsAndKeys
e numberWithInt, numberwithBool, numberWithFloat,
numberWithLong.
Era noioso e se lo fossi
facendo questo prima di ARC è ancora peggio.
Alcuni di voi avranno notato, ma in realtà lo sono
un errore su questa diapositiva perché dictionaryWithObjectsAndKeys
gli oggetti vengono prima; la chiave è “non io”
e il valore è “Chi lo farebbe?”, che è al contrario.
Ho fatto questo errore alcune volte.
(Sospira)
Sono così felice che non dobbiamo più farlo.
(Ora, lo facciamo).
Abbiamo letterali oggetto, gli array sono creati con
un @ e poi parentesi quadre,
dizionari @ parentesi graffe,
NSNumbers sono creati utilizzando
espressioni in scatola (metti @ l’espressione che viene
dopo viene valutato come un numero).
Questo è un enorme miglioramento.
Sono migliori
Universalmente meglio.
Non c’è una ragione per cui non lo faresti
voglio usare oggetti letterali. (Non ho
stato in grado di pensare a uno).
Sono stati adottati dalla comunità quasi immediatamente
tutti passarono a questi perché non c’era ragione
non a e Xcode aveva una funzione integrata
dove lo farebbe per te.
L’uso di letterali oggetto è diventato ciò che potreste chiamare
una buona pratica.
Cos’altro è uscito
un anno prima degli oggetti letterali?
(Qualcuno ha una supposizione di quello che sto per dire?)
Blocchi.
I blocchi sono usciti nel 2010 per iOS 4.
I blocchi erano fantastici, ero eccitato per i blocchi.
Introdotto in iOS 4, adottato lentamente ma sicuramente.
I blocchi sono eccitanti perché richiedono
un nuovo modo di pensare.
Prima c’era il codice eseguibile a cui si poteva fare riferimento
come dati, non potresti risolvere i problemi in certi modi.
Sei stato limitato dalla lingua.
Quando sono usciti i blocchi, lo hanno fatto
una strana sintassi ed era difficile anche adottarli,
ma anche gli sviluppatori iOS erano abituati a risolvere i problemi
senza di loro.
Eravamo abituati a risolvere problemi con i protocolli,
e delega, o azione mirata, o un numero qualsiasi di modi.
L’utilizzo dei blocchi è diventato una best practice?
Sta usando
una dichiarazione se una best practice?
I blocchi sono solo sintassi.
Consentono altre buone pratiche.
La chiave qui sta usando i blocchi
e dicendo: “Oh, usa un blocco perché è meglio
di una delegazione o un’azione mirata, “
(non il punto).
Il punto è con i blocchi che possiamo fare cose interessanti.
Possiamo fare la programmazione funzionale del reattore,
oppure possiamo eseguire un blocco di codice in un contesto,
per esempio, un’animazione.
Prima, se volessi animare qualcosa, lo faresti
chiama un metodo che dice “Sto iniziando l’animazione”
e poi cambieresti le cose, e poi l’avresti fatto
meglio chiamare un metodo alla fine che dice,
“E ora l’animazione è finita.”
(Questo è strano).
Se dovevi essere avvisato di quando quell’animazione
era completo, è molto lavoro.
Potremmo anche richiamare quando
è stata consegnata una risposta di rete asincrona.
Operazioni di raccolta, ora possiamo enumerare
una collezione (ad esempio una serie di cose), o potremmo mapparla
in una serie di qualcos’altro.
Nuove idee al momento.
Anche alcuni di loro sono ancora nuovi per iOS.
Ma sono abilitati solo da blocchi.
Queste potrebbero essere le migliori pratiche. Ma blocchi? No.
Il mio punto è: abbiamo abbracciato il cambiamento.
Abbiamo i blocchi e siamo come,
“Facciamo qualcosa con loro.”
Ci sono voluti cinque anni per arrivare dove siamo ora,
ma sono orgoglioso ed emozionato
che abbiamo realizzato come una comunità in quel tempo.
Abbiamo una storia di prendere la nuova tecnologia
che Apple ha fornito lo sviluppo iOS
e facendo cose incredibili con esso.
Questo ci porta a Swift 2.
Swift 2 è la seconda versione della programmazione Apple
lingua, prima annunciata e rilasciata lo scorso anno.
(Emozionante, ero entusiasta di Swift).
(Più uso Swift 2 più mi piace).
Swift 2 include una nuova sintassi.
La nuova sintassi ci consente di fare cose nuove (come il nuovo blocco
la sintassi ci permette di fare cose nuove con i blocchi).
Ma la sintassi è solo uno strumento.
Come i blocchi, la nuova sintassi di Swift non è qualcosa
puoi classificarti come una buona pratica (perché non è così
ha senso).
Cose come dichiarazioni di guardie o dichiarazioni di differimento,
o lanciando con nuova gestione dell’aria.
(urlando in sottofondo)
(ride)
Queste sono sintassi, ma non c’è
una buona pratica di lancio di qualcosa
(ad es. l’uso del differimento non è una buona pratica).
Una domanda che potresti chiedere è: “Devo usare la guardia?”
(Ma questa non è la domanda giusta, vero?)
La domanda giusta è: “Cosa posso fare con la guardia?”
Ora che ho questa nuova funzionalità e questa nuova sintassi
cosa posso fare con esso?
(una domanda molto più interessante).
Diamo un’occhiata ad alcuni esempi.
Prima di tutto, abbiamo la piramide del destino.
(chiamato perché ha questo triangolo o piramide
arrivando da sinistra, strisciando verso destra).
Sono sicuro che hai scritto tutto il codice in questo modo (ne sono sicuro).
Scrivere codice come questo è facile (ma scrivere codice
è sempre facile).
La parte difficile è leggerlo.
Questo codice (in particolare con la piramide di Doom)
lo rende ancora più difficile di quanto non debba essere.
Istruzioni if / let composte da Swift 2 interstotto
e dove clausole.
Abbiamo qualcosa di simile ora.
Questo è un codice semanticamente identico, ne stiamo vincendo due
variabili, due variabili opzionali e abbiamo una clausola where
che ovvia alla necessità di una delle dichiarazioni if.
Diamo un’occhiata a un altro esempio.
Mutabilità, questo è molto codice Objective-C
(questo era ciò di cui avevo paura quando Swift uscì).
Avevo paura che le persone scrivessero questo Swift.
Questo è Obective-C nella sintassi Swift e sembra terribile.
(Non ho intenzione di andare oltre quello che fa,
perché non importa
è terribile).
Quello che vogliamo scrivere è qualcosa del genere.
Questa è la stessa funzione, richiede una serie di stringhe,
e prende un prefisso e ti restituisce uno di quelli
stringhe che gli hai dato che iniziano con il prefisso
(questo è tutto ciò che fa).
Meno digitando, più espressivo.
Forse è facile da scrivere,
ma è più facile da leggere.
È più espressivo.
Un’altra cosa di cui voglio parlare è il curry.
(Questa è una di quelle strane parole che potresti aver sentito
e potresti averlo evitato perché alcuni di questi mi piacciono
i guru della programmazione funzionale sono cretini
e lo usano molto).
In realtà è uno strumento utile;
non è complicato come potresti pensare.
Il currying è utile quando hai una funzione,
e un’altra funzione, … e fanno quasi la stessa cosa.
(utile per fornire
personalizzazione a una funzione).
Diamo un’occhiata a un esempio.
Ho una funzione chiamata containsAtSign.
Prende una stringa, restituisce un valore booleano e restituisce true
se quella stringa contiene un segno di segno (abbastanza diretto).
Ora hai una serie di stringhe chiamate input,
li filtrate in base a quelli che contengono un segno.
Perché abbiamo una funzione (le funzioni sono identiche
semanticamente alle chiusure e alla funzione filtro
prende una chiusura che va da qualunque cosa ci sia nella matrice
a un booleano), possiamo passare un riferimento alla funzione
direttamente nella chiusura del filtro.
(Questo è bello, è fantastico, ma può essere anche meglio).
Diamo un’occhiata al curry.
Ora, invece di una funzione contiene Attign che abbiamo
una funzione contiene.
Prende una sottostringa e restituisce una chiusura.
Quella chiusura va da una stringa a una booleana.
Puoi vedere la chiusura che stiamo tornando
all’interno della funzione prende una cosa chiamata stringa
restituisce un booleano e fa la stessa identica cosa, eccetto
ora invece di un segno letterale stiamo usando la sottostringa
parametro passato nella funzione originale. Noi possiamo
puoi chiamarlo così
Invece di avere una funzione per contiene AtSign,
una funzione per containsPercentSign, una funzione
per contieneDollarSign abbiamo solo una funzione contiene,
diamo un po ‘di personalizzazione di cui ha bisogno
e fa il resto per noi.
Questo è potente ed è così importante per Swift
sviluppatori di Apple. Non intendo, “I am a Swift
“sviluppatore”, le persone che sviluppano Swift,
che hanno introdotto uno zucchero sintattico per questo.
Questa è un’espressione semanticamente identica.
Passa da una sottostringa e ti restituisce una chiusura
che va da stringa a bool (sembra divertente
all’inizio, ma ti sto dicendo la prima o la seconda volta
lo fai ci si abitua velocemente
ed è così divertente).
Un’altra cosa interessante che Swift ci ha lasciato fare,
Swift 1 pari, valori associati alle enumerazioni.
Si crea un enum a cui si attribuisce un valore associato
e si estrae quel valore attraverso una dichiarazione del caso.
In Swift 1, le dichiarazioni di un caso erano disponibili solo all’interno
di un blocco interruttore.
Scriveresti codice come questo.
Hai un enum in cima, ha un successo e un fallimento.
Se fallisce vorremmo sapere perché.
Abbiamo un valore associato, una ragione.
È una stringa che possiamo presentare all’utente
sul perché qualcosa non ha funzionato
Di ‘, c’è una funzione chiamata doThing, restituisce
uno di questi risultati se è un successo, quindi stampiamo
(tempo di festa); se non lo è, possiamo estrarlo
la ragione del caso e stampala anche tu.
Questo è stato grandioso, ma Swift 2 è diventato ancora migliore perché
ci permette di prendere le dichiarazioni del caso al di fuori degli interruttori.
Se non ci interessa il caso di successo, se ci interessa solo
se qualcosa è andato storto possiamo scrivere un codice come questo.
Possiamo dire se è un fallimento quindi estrarre la ragione.
Di nuovo, è una sintassi non familiare, ma non lo è
sintassi complicata.
Questo è qualcosa che possiamo adottare facilmente.
È una buona pratica?
No, solo sintassi.
Cosa importa che possiamo usare le dichiarazioni dei casi
al di fuori delle dichiarazioni switch?
è più facile da fare (che è bello).
Potrebbe consentirci di fare le cose più facilmente o rapidamente.
Ciò che conta sono le idee.
Swift 2 introduce una nuova sintassi che ci consente di fare
cose nuove, e dobbiamo cercare il nuovo
cose che ci lascia fare.
Ad esempio, sono sicuro che molti di voi ne hanno sentito parlare
parola d’ordine che va in giro “programmazione orientata al protocollo”.
Cosa significa?
è un’idea interessante che Apple ha ideato
attorno all’utilizzo di protocolli anziché gerarchie di classi
contenere informazioni (interessanti).
Diventerà la migliore pratica?
Può essere. credo
sembra bello
Sfortunatamente, non ho tempo di entrare in questo momento,
Ti incoraggio solo a guardare il video del WWDC.
Apple ha idee interessanti su ciò che una buona pratica
potrebbe sembrare in Swift.
Scommetto che anche altre persone hanno idee. Andiamo a chiedere a loro.
Ci sono altre comunità là fuori oltre a iOS,
oltre a Objective-C e Swift.
Apple ha chiaramente preso le mosse da altre programmazioni
lingue (Ruby, JavaScript e Scala).
Ci sono tonnellate di comunità là fuori
che hanno sintassi simile e capacità simili a Swift.
Mi chiedo quali soluzioni e quali migliori pratiche
lavoro per loro, e perché?
Le soluzioni usano qualcosa che potremmo usare?
Sono le soluzioni che scelgono di non usare
qualcosa che è appropriato per noi?
Dovremmo andare a chiedere loro, o meglio ancora dovremmo
uscire e imparare Python per un fine settimana,
è stato sulla mia lista delle cose da fare per un anno,
solo per vedere cosa fanno e vedere se alcune di quelle idee
può essere portato a Swift.
Come fai a sapere se qualcosa è solo un pezzo di sintassi
o se è un’idea che può diventare una buona pratica.
Non puoi.
Ti ho mentito, è una dicotomia molto falsa.
non c’è niente di giusto o sbagliato, non c’è nulla che dice
Questa è la sintassi, ma questa è un’idea.
è la dichiarazione if / else che ho menzionato prima.
Usare una dichiarazione if è una buona pratica o è sintassi?
Sono entrambi.
Come faresti le cose senza dichiarazioni?
Quello che sto cercando di dire è: abbiamo
andare a provare cose.
Devi provare le cose e vedere, forse funzioneranno
forse non lo faranno, ma non lo sapremo fino a quando non ci proveremo.
Il che ci porta a “Non buttare via idee”.
Swift è stato rilasciato e l’ho trattato
come oggetti letterali invece di blocchi.
L’ho trattato come qualcosa che dovremmo usare sempre
perché è universalmente migliore e ho buttato via
le idee che aveva l’Objective-C.
Alcune di queste idee meritano di essere tenute, per esempio, Swift
non ha ancora una sostituzione per l’osservazione del valore chiave.
Questo è qualcosa che dobbiamo ancora usare
il runtime Objective-C per.
Anche le idee più vecchie hanno valore.
Anche se una comunità, forse c’è qualcosa di interessante
in Cobalto sarebbe fantastico da implementare in Swift.
Non lo so, perché non ho imparato il cobalto,
Non lo farò, ma sai che vale qualcosa
esplorare e vale la pena riflettere.
La tragedia è che gli sviluppatori di iOS buttano via le cose
tutto il tempo.
In generale, gli sviluppatori lo fanno, ma gli sviluppatori iOS
fallo molto
Perché?
Alla fine ci arriveremo, ma voglio prenderti
attraverso un modello che ho notato nel mio
carriera (e forse l’hai notato nel tuo
o anche altri).
Abbiamo un principiante, non hanno mai programmato prima
e stanno imparando iOS.
Imparano qualcosa (ad es. Objective-C)
e sono cattivi (perché sono principianti)
e i principianti sono cattivi alle cose
(è così che impariamo: essere cattivi e migliorare).
Danno la colpa alla loro frustrazione
sulla cosa, lo assumono perché sono frustrati
con esso e sono cattivi, che deve essere cattivo.
Ma, ottengono più esperienza. Imparano l’obiettivo-C
e iOS, e poi Swift esce.
Imparare la nuova cosa è più facile
che imparare la vecchia cosa.
Suppongono che sia perché la nuova cosa è migliore,
ma in realtà è anche perché loro hanno
più esperienza ed è più facile imparare le cose.
Hanno mescolato queste due idee (hanno attraversato fili
nel loro cervello avevano una cosa vecchia che era difficile
per imparare perché erano alle prime armi, hanno un nuovo
cosa che è facile da imparare in parte perché hanno
più esperienza).
Questo è il motivo per cui le nuove idee sono allettanti.
Ecco perché le nuove e brillanti API che escono ogni anno
sono eccitanti mentre i vecchi sono così terrificanti
e lordo.
Diamo la colpa alla versione precedente di iOS.
È uno scherzo nella nostra comunità:
non vediamo l’ora di rilasciare il supporto per iOS 9,
non posso aspettare per iOS X.
iOS è in continua evoluzione; Apple ci fornisce sempre
con le nuove API. Ciò significa che c’è una costante
fornitura di vecchie API per farci arrabbiare
e per noi la colpa.
Non penso che lo stiano facendo apposta;
Penso che Apple stia facendo del suo meglio per darci API
che ci consente di creare applicazioni interessanti,
perché questo li renderà soldi.
Questo è un effetto collaterale, non qualcosa
dobbiamo vergognarci;
è qualcosa che sarebbe bello riconoscere
e renditi conto che
se ci vediamo noi stessi a fare questo
forse fai un passo indietro e pensa a iOS 8
o 7, non è così male.
(Voglio prendere una traccia laterale.
Questo è qualcosa che ho pensato per molto tempo).
Voglio parlare del refactoring.
(Questo è un termine che sento sempre, persone su Twitter
refactoring del controller di visualizzazione o refactoring di un oggetto
in alcuni oggetti più piccoli, forse parlano di
refactoring di un intero progetto nel fine settimana).
(Continua ad usare quella parola, non penso che tu sappia cosa significa,
“Non penso significhi cosa pensi che significhi.”)
Cosa non è un refactoring?
Se stai aggiungendo nuove funzionalità
quello non è un refactoring.
Se stai modificando l’interfaccia pubblica per il tuo tipo,
quello non è un refactoring.
Un refactoring non modifica il comportamento di un tipo.
Se fosse abituato a fare qualcosa e non lo fosse più,
o se non lo fosse e ora lo fa non è un refactoring.
questa è una riscrittura.
Questo è un test molto semplice.
Devi cambiare un test unitario.
Se lo fai, allora è una riscrittura, se non lo fai
allora stai effettivamente rifacendo qualcosa.
Perché questo importa?
Perché le riscritture sono cattive e questo non sono io
(qui nella parte anteriore della stanza, a chi importa
cosa penso).
Qualcuno molto più intelligente di me ha detto questo.
Ho letto questo articolo all’inizio della mia carriera e lo ha avuto
un grande impatto su di me.
Joel Spolsky ha scritto questo: Cose che non dovresti mai fare,
Parte 1: dedicata al software di riscrittura.
Non riscrivere mai il software.
Ora, conceduto questo post del blog stava discutendo
Netscape (un’intera applicazione,
non un controller di visualizzazione).
L’idea che non dovresti mai riscrivere
un controller di visualizzazione non trattiene l’acqua.
Ma, che cos’è un’applicazione ma solo una collezione
controller di vista?
Se non dovresti mai riscrivere le applicazioni,
forse dovremmo essere più attenti alla riscrittura
i nostri controller di visualizzazione.
Dovremmo favorire i cambiamenti incrementali.
Non penso che quel codice sia necessariamente prezioso.
Penso che il codice sia abbastanza inutile, e
il codice che scrivo ora non avrà
qualsiasi valore in un anno o dieci anni anche.
Lanciare il codice e sostituirlo con qualcosa
nuovo di zecca è pericoloso, perché ti manca il contesto
come quel codice interagisce con il resto del codice.
Ecco perché riscrivere è terribile, perché ci vorrà sempre
più di quanto pensi e farai sempre degli errori
che non prevedi.
Se non dovessimo buttare via le idee
o codice, le due cose che dovremmo
mai buttare via sono codice e idee.
Forse c’è qualcosa di interessante in Obejctive-C
che ancora non lo so, ma dovrei imparare in ordine
per farlo in Swift o portare l’idea a Swift.
Forse il mio progetto che è in Objective-C può rimanere dentro
È possibile scrivere Objective-C e qualsiasi nuova classe che aggiungo
in Swift.
Non devo buttare via tutto solo per abbracciarlo
la nuova cosa.
(Questo è il numero uno).
Parliamo dei test unitari.
Il test delle unità ti aiuterà a cambiare meglio il tuo codice.
Questi cambiamenti incrementali che ti sto chiedendo di fare
lo fai con i test unitari.
Voglio parlare di cosa significa.
Test unitario, argomento controverso
in iOS, non così controverso letteralmente da nessun’altra parte.
Siamo le uniche persone che hanno un
grosso problema con i test unitari.
I singoli sviluppatori sanno che le comunità
non mi piace, ma come iOS è allergico ad esso,
almeno questo è il modo in cui agiamo.
Ci arriveremo più tardi.
Innanzitutto, voglio presumere che i test unitari
è una buona idea
Se non sei d’accordo, parcheggia quella convinzione
e supponiamo che io abbia ragione solo per questa diapositiva,
e quello dopo, e quello dopo.
Non mi interessa molto dei test.
C’è questa idea “Non ho mai preso
“un bug a causa di un test unitario – test dell’unità
“non deve essere così prezioso”
Se l’unico valore che vedi
nei test unitari sono i test effettivi, quindi lo sei
manca il punto.
Mi interessa di più scrivere il test a causa del modo
quel test di scrittura cambia il modo in cui scrivo il codice.
Scrivere prove mi costringe a pensare a quello che sto facendo,
che è un po ‘importante, specialmente nel contesto
di come trovare nuove migliori pratiche.
Non possiamo trovare nuove migliori pratiche se non stiamo pensando
su di loro.
(ha senso, giusto?)
I test ci costringono a pensare così forse ai test unitari
ci aiuterà a scoprire le migliori pratiche.
Uno dei maggiori vantaggi dei test unitari
è che limita la portata del tuo oggetto
perché devi pensarci.
Se hai un oggetto che è complesso
e fa molte cose che è molto difficile da testare
e tu hai più probabilità di creare diversi oggetti più piccoli
ognuno fa una cosa individualmente, ma le fa bene.
È meglio perché ora hai più oggetti coesivi
quello fa solo una cosa e tu non hai un comportamento
che è accoppiato l’un l’altro.
Parte dell’oggetto dipende da quest’altra parte
ma dipende anche da questo. Dipende
come prima. Non hai quello
perché tutto è separato in singoli componenti.
Come limiti l’ambito?
Il modo migliore è controllare la tua interfaccia pubblica
e lo fai in congiunzione con qualcosa chiamato
iniezione di dipendenza che è la parola più spaventosa
nello sviluppo del software.
Iniezione di dipendenza?
(Non voglio farlo, non volevo nemmeno alzare lo sguardo
cosa significava).
L’ho cercato, sono andato su Wikipedia
ed è complicato
(non è, credimi, Wikipedia è proprio come,
se non sapessi cosa fosse un computer e te ne sei andato
a WIkipedia e ti ha detto che un computer è una macchina
di logica formale che processa input e blah, blah,
blah, blah, blah.
Sarebbe confuso, vero?)
Lo stesso con l’iniezione di dipendenza, non è così complicato
di un argomento.
L’iniezione di dipendenza è una parola di cinque euro
per un’idea da cinque centesimi.
(Ward sta ridendo perché usa molto questa espressione).
L’idea dell’iniezione di dipendenza,
la tua cosa non dovrebbe creare le cose di cui ha bisogno.
È così.
Lascia che ti ripeta: la cosa che stai facendo
non dovrebbe di per sé creare le altre cose di cui ha bisogno
farlo è un lavoro.
Diamo un’occhiata ad alcuni esempi.
Questo è quello che direi piuttosto standard
iOs visualizza il controller.
Ha un controller di rete e se hai caricato
recupera roba dalla rete.
Una volta fatto, un blocco di completamento
è invocato e mostra quella roba.
Molto semplice, non c’è niente di sbagliato
con questo controller di visualizzazione.
Ho scritto questo controller di visualizzazione molte volte.
Immagino che la maggior parte di voi abbia anche lei.
Come appare diverso con l’iniezione di dipendenza?
Guarda attentamente le diapositive;
vedi se riesci a capire la differenza.
(qualcuno manca?)
(è proprio lì).
Non stiamo più creando il controller di rete.
Invece, abbiamo un controller di rete,
è variabile perché dobbiamo impostarlo
a qualcosa più tardi.
È un controller di rete opzionale e ora quando
viewDidLoad è chiamato chiediamo al nostro controller di rete
per prendere roba. Quando è fatto invoca
il nostro blocco di completamento e mostriamo quella roba.
Questo è esattamente lo stesso, niente nel resto
della nostra classe è cambiato.
L’unica cosa che viene cambiata è la linea che definisce
il controller di rete.
Ci affidiamo a qualcun altro per creare la rete
controller per noi e darlo a noi.
Potrebbe essere un’altra parte della nostra app, magari in preparazione
per Segue.
Il controller di visualizzazione prima di noi ha creato una rete
controller per noi, o forse è passato in un riferimento
a quello che aveva.
Forse è un test unitario.
(Questa è la parte eccitante, e ci arriveremo
cosa significa in seguito).
L’iniezione di dipendenza non è così difficile.
I protocolli funzionano bene per questo.
Diamo un’occhiata a un ipotetico controller di rete
protocollo.
Ha una funzione, fetchStuff.
Accetta un blocco di completamento che chiama
quando fa il recupero.
Diamo un’occhiata a un controller di rete API.
Questa è una classe specifica conforme al protcol.
Ha la funzione fetchStuff.
(Non l’ho ancora implementato, ma puoi ottenere
l’idea di cosa farò).
Sto andando alla rete, fetchStuff,
e quindi invoca il blocco di completamento.
(Nel mio test unitario avrei qualcosa di simile.)
Un controller di rete di prova è conforme allo stesso protocollo.
Invece di andare a prendere dalla rete
usa i dati stubbed che conosco in anticipo
e invoca immediatamente il blocco di completamento.
Ora, posso configurare il controller di test, passarlo
il controller della vista e chiedi al controller della vista
fare qualcosa e testarlo è un comportamento.
Ho un protocollo (e
fa tutto), non mi interessa
ai fini dei test unitari.
Lo testerò in modo indipendente più tardi.
Ho un protocollo e sono conforme a tale protocollo
nella mia simulazione, questo controller di rete di test.
Faccio qualcosa che so cosa farà
in anticipo e so come mi aspetto la vista
controller per reagire.
Quindi, cerco di fare in modo che quella reazione
è quello che mi aspetto.
(Questa è tutta l’iniezione di dipendenza è).
L’uso di protocolli ti aiuta a limitare l’ambito
(perché hai un contratto chiaramente definito
su cosa dovrebbe fare il tuo oggetto individuale).
L’aggiunta di un metodo al protocollo diventa ora
una decisione.
Non hai accesso all’intero elenco di funzioni,
anche quelli interni che non dovrebbero sapere.
Se non è nel protocollo, non puoi chiamarlo
(affare).
Se vuoi chiamarlo devi prendere una decisione
per aggiungerlo al protocollo (va bene,
a volte ha senso).
L’iniezione di dipendenza è più utile di questo.
Parliamo di stato condiviso e singleton.
(Non so quale sia la reazione di Sal
sarà).
I singleton non sono poi così male,
se usi l’iniezione di dipendenza.
Diciamo che abbiamo questa funzione chiamata loadAppSetup.
(qualcosa che chiami quando l’app si avvia).
È responsabilità controllare e vedere,
“Ho lanciato prima?
“Se non ho lanciato prima di mostrare
“l’utente qualcosa”, forse un login sullo schermo
(che importa?)
Afferra qualcosa da NSUserDefaults
standardUserDefaults; se non è ancora successo
quindi chiama qualche funzione.
Come lo verificheresti?
Non ne ho idea.
Stai per eliminare lo standard UserDefault
e quindi impostarli per il test specifico.
Quindi, assicurati di eliminarli
in seguito (quindi non inquina il prossimo test che si esegue).
(sembra molto lavoro).
Iniezione di dipendenza ci dovrebbe iniettare
le impostazioni predefinite nella funzione (che è).
Questa è ora una funzione di facile utilizzo per le dipendenze.
Non essere un ideologo.
Non ha sempre senso fare le cose.
A volte hai bisogno di infrangere le regole e qualche volta
hai bisogno di imbrogliare.
A volte devi piegare le regole,
e a volte è necessario ignorarli del tutto.
Questo è come barare con quella funzione.
Direi, “stessa cosa, ma ho intenzione di fornire
“un valore di parametro predefinito di standardUnitDefaults.”
Ora, se non specificherò un parametro, verrà ripiegato
agli standardUserDefaults.
(È fantastico per la mia applicazione
perché è meno digitante per me).
Nei miei test unitari posso creare le mie impostazioni predefinite personali
che non sono quelli standard (non condivisi
con qualcun altro).
Posso iniettarli dentro
Ecco come appare loadAppSetup. Niente ha
cambiato dal resto della prospettiva dell’applicazione,
ma nei test unitari ora possiamo iniettarlo
e i nostri test diventano più semplici e diventano
isolato (che è quello che vuoi nei test).
Torniamo all’esempio del nostro controller di visualizzazione.
Usando lo stesso cheat potrei avere il controller di rete
proprietà impostata sul controller di rete dell’API,
ma in questo caso è fondamentale che io sia così
specificando che è conforme al protocollo.
Il controller di visualizzazione non ha ancora accesso
al controller di rete API effettivo.
Ha solo accesso al protocollo
(esattamente quello che vogliamo).
Nient’altro nel controller della vista è cambiato.
Potresti testarlo ora
creando il controller della vista, creando uno stub
o versione derisoria del protocollo del controller di rete
e iniettandolo dentro
Finché lo si inserisce prima che la vista sia caricata
quindi puoi testare il tuo controller (facile).
C’è questa sorprendente citazione di Mackenzie King,
primo ministro del Canada negli anni ’40.
Ha detto: “TDD se necessario, ma non necessariamente TDD”.
La gente lo ha paragonato a Winston Churchill del Canada
(che mi piace molto perché il suo stile di gestione
stava dicendo cose che erano così imperscrutabili
che non potevi essere in disaccordo con lui).
(Ovviamente, questo è quello che sto cercando di fare adesso).
Esaminiamo i test unitari.
Non testare le funzioni private, anche iniziare a segnare
le tue funzioni come private. Di default
sono interni, il che significa che puoi chiamarli
e non dovresti chiamarli.
Evitare di riscrivere, ove possibile,
e non testare la tua implementazione.
Ricorda che l’obiettivo del test unitario è quello di testare il comportamento
dell’interfaccia pubblica.
In un mondo ideale ogni oggetto ne avrebbe solo uno
funzione pubblica.
(Non viviamo in un mondo ideale, ma immaginiamo).
La scorsa settimana Justin Sirls ha avuto questo fantastico post
sull’utilizzo di mock parziali.
Un finto parziale è qualcosa di reale,
ma anche falso.
Nel nostro esempio non potremmo farlo perché abbiamo usato i protocolli;
diciamo che in base ai protocolli abbiamo usato la sottoclasse,
ma abbiamo solo sovrascritto alcuni dei metodi,
alcune delle funzioni.
Alcuni dei comportamenti sono reali e alcuni sono falsi.
(Lo confronta con le auto di prova.
Il collaudo delle unità è come testare la sicurezza delle auto.
Una finta sarebbe a
manichino di crash test, come lo chiami tu.
A quelli piacciono le persone con un po ‘di giallo
e cerchi neri, e sai, misurano la forza
che provano quando una macchina si schianta.
Questo è il nostro doppio, quelli sono utili).
(Un finto finto è qualcuno che indossa un costume di Halloween
sembra un manichino da crash di test.
Com’è utile per testare la sicurezza dell’auto?)
(Probabilmente non vuoi mandarli a sbattere contro un muro
e vedere se sopravvivono).
(Sarebbe molto meglio usare un pieno,
vero e proprio crash test di prova).
Perché gli sviluppatori di iOS non amano testare?
Penso che si tratti di questo:
non è familiare e nessuno ci obbliga a farlo
(una sciocca ragione per non fare qualcosa).
(Andare dal dottore non è familiare
e non mi piace farlo e mia madre non ha forzato
io per andare dal dottore tra 10 anni.
Forse dovrei andare dal dottore
se mi sento male anche se non mi piace.
è la stessa cosa con il test delle unità).
È buono per noi, anche se ci si sente
strano all’inizio.
(Non potrei inventare una metafora migliore, mi dispiace).
(ride)
I test mi hanno reso uno sviluppatore migliore
(Penso che ti renderà anche uno sviluppatore migliore
se lo provi).
Voglio fare il codice che è facile
per mantenere, che è facile da espandere in seguito,
e di cui sono orgoglioso.
Il test unitario mi aiuta a fare queste tre cose.
Ultima sezione del discorso, astrazione.
(“questo è già stato un discorso astratto,
“e ora parlerà di astrazione”).
Ho lavorato in un’azienda che ha detto questo,
“Se stai ripetendo due o più righe di codice,
“allora stai sbagliando, devi trovare
“un’astrazione e farlo in un modo migliore”.
(Che cosa?)
Creare un’etichetta e quindi aggiungerla alla mia vista
questo è due righe di codice.
“Estratto.”
(All’inizio era difficile da fare
ma dopo un giorno o due mi è piaciuto).
(Dopo alcune settimane sono tornato al mio vecchio progetto
e pensavo fossero banane, guarda tutto questo
codice duplicato, sto aggiungendo un’etichetta qui, e qui,
e qui, e qui).
(Era terribile, non mi piaceva.
E ora, provo a prenderlo a cuore.
Non lo faccio sempre, ma è qualcosa
Sto sempre cercando).
Stai già imparando nuova sintassi con Swift 2.
Cerchiamo nuove astrazioni lungo la strada.
Proviamo nuove cose.
Non tutte le idee funzioneranno, infatti,
molti di loro non lo faranno, ma dovresti farlo comunque.
La sperimentazione è personale
e benefici professionali.
È soddisfacente giocare con una cosa nuova.
Questo è il motivo per cui tutti scarichiamo i beta
di Xcode e prova a costruire cose con loro.
(è divertente provare nuove cose).
Facciamolo anche con le astrazioni.
È anche lo sviluppo professionale:
se troviamo qualcosa di nuovo che funzioni,
possiamo costruire un codice migliore
è meglio per i nostri datori di lavoro.
Questo è il caso che dovresti fare al tuo capo
quando lo è, “Perché stai scaricando la versione beta di Xcode?”
(è così che lo fai.
Una buona idea).
(Avevo un altro punto, ma l’ho dimenticato.
Anche se provi qualcosa e non funziona,
questo è il punto, ricordavo).
Anche se provi qualcosa e non funziona
capisci ancora quella soluzione.
(Prova la tecnica e ti scoppia in faccia).
Ora sai che non dovresti usare quella tecnica,
ma forse quella tecnica sarebbe preziosa
in un altro scenario, un’altra soluzione, un altro problema
altrove.
Quando provi qualcosa forse non funziona
ma tu impari ancora qualcosa.
Secondo me, è il caso dell’idea
che non esiste un esperimento fallito.
Se provi qualcosa e non funziona,
se hai un’idea e si scopre che hai torto,
hai ancora imparato qualcosa.
In questo modo è un successo.
Alcuni dicono che non c’è sempre tempo
sperimentare.
Hai tempo di crunch, ce l’hai
rilasciare il codice in pochissimo tempo.
(succede, ma è importante provare a sperimentare
quando puoi).
Quando non puoi più, ti ricadrà
a un diverso livello di astrazione.
(questo è un livello migliore di astrazione
di quando hai iniziato).
(Ho fatto un grafico.
Puntatore laser).
Puoi vedere l’inizio a questo discorso proprio ora.
Ti sto incoraggiando a sperimentare e provare nuove cose.
Stai per scrivere
test unitari lungo la strada.
(Stai migliorando molto),
Stai lavorando ad alto livello di astrazione
(è fantastico9.
È tempo di crunch, hai una scadenza,
devi spedire all’App Store.
Non hai tempo per scrivere i test unitari,
non hai tempo per esplorare, non hai tempo
provare nuove cose.
(Oh guarda!
tu sei lì, più in alto di dove
eri quando hai iniziato).
Puoi tornare a una posizione successiva.
Non è necessario scrivere sempre un test delle unità.
Non devi testare sempre, non devi
sperimentare sempre.
Ma quando sei abituato a sperimentare
e sei abituato a testare diventa più facile
in modo che tu possa farlo, puoi sperimentare
e continua a sperimentare e testare quando non lo fai
avere tanto tempo
Quando hai finito il tempo di crunch
puoi tornare indietro e farlo ancora un po ‘.
C’è sempre l’opportunità di imparare.
Dovremmo approfittare di queste opportunità.
Concludiamo
Abbiamo una storia, come comunità e come industria,
La community iOS ha una storia di esplorazione
nuove tecnologie: prendere qualcosa che è bello e nuovo
e costruendo cose incredibili con esso.
Lo abbiamo fatto con Objective-C,
con Swift (penso che continueremo a farlo).
Ora non è il momento di smettere di cercare nuove e fresche soluzioni.
L’apprendimento non è solo per quando Xcode è in beta.
(Solo perché Xcode 7 è fuori, Swift 2 è stabile …)
(ride)
(finito, finito).
Solo perché Swift 2 è finito, non significa che tu
non dovrebbe più cercare cose nuove e interessanti
puoi farcela.
Le idee sono più preziose del codice, ma nessuna delle due
di loro dovrebbero essere gettati via (gettando via
il codice è pericoloso).
Test di unità efficaci semplificano il cambiamento del codice
in modo incrementale.
Infine, se puoi operare al più alto livello
di astrazione puoi in qualsiasi momento
allora quando non puoi operare a quel livello alto
puoi ricorrere a qualcosa che è ancora meglio
di dove eri.
(questo è stato un discorso divertente per me per la ricerca
e pensa.
Ripensandoci
la mia carriera e alcune delle decisioni che ho preso.
Ho fatto degli errori e cose che avrei fatto
diversamente ora con il senno di poi, ma non me ne pento
uno qualsiasi degli errori che ho fatto perché ognuno di loro
mi ha aiutato ad imparare.
Finché penso all’errore in seguito
e imparare da esso, quindi non è una cosa negativa).
Il nostro obiettivo come sviluppatori di software non dovrebbe essere
non commettere mai errori
Il nostro obiettivo come sviluppatori di software dovrebbe essere quello di provare
e fare errori migliori domani.
Grazie mille.
(applausi)
– [Voiceover] Un paio di domande dal pubblico,
iniziare in fondo penso.
In MVVM, dovrebbe visualizzare i controller comunicare
con modelli di vista attraverso un protocollo, o sapere
il tipo concreto con cui hanno a che fare?
– Adoro come ho questa reputazione come MVVM,
come se non li menzionassi affatto,
sì, ed è come, “Oh una domanda su MVVMs.”
MVVM, recentemente ho convertito una gran parte della nostra base di codice,
questo è codice di base Swift per Model View ViewModel
e ho trovato i protocolli molto migliori,
perché mi ha aiutato a evitare la simulazione di una situazione parziale.
Se lo stub del test, come la sottoclasse che avresti,
non posso scegliere di non scavalcare qualcosa perché,
non c’è nulla da scavalcare, allora è meglio.
Non è possibile ricorrere accidentalmente a prestazioni reali
una richiesta di rete nei test dell’unità.
protocolli sicuramente, fino in fondo.
– [Voiceover] Giusto, e se non possiamo passare in oggetti
come passare un oggetto al controller della vista
ViewModel?
– Giusto, quindi questa è una domanda comune
chi crea il viewmodel?
è il controller di visualizzazione?
È il controller di visualizzazione che ha presentato questo?
È difficile e scende
alle preferenze personali.
Lo sto ancora cercando di capire.
A mio parere, mi piace il viewmodel che viene creato
dal controller della vista in un pigro blocco di chiusura.
E poi, se viene eseguito un test, allora può scavalcare
quella proprietà in modo che il viewmodel reale non venga mai creato,
in modo che il controller della vista usi sempre solo il test
guarda i modelli nei test unitari.
Il viewmodel stesso da creare
puoi averlo creato da un diverso modello di vista,
oppure puoi averlo creato dal controller della vista
questo è presentare questo.
Non importa; Ti incoraggio a sperimentare
e vedi cosa ti piace di più.
– [Voiceover] se avvii un nuovo progetto iOS
domani lo scriverai in Swift of Objective-C?
L’unica ragione per cui posso pensare di scegliere Objective-C
starebbe avendo un team di sviluppatori senza Swift
esperienza e una scadenza stretta.
Puoi pensare ad altri motivi?
– Sarebbe un grande,
Lo scriverei in Swift, prima di tutto, anche se lo avessi
una scadenza ravvicinata, ma ho fatto l’errore l’anno scorso
e non ha funzionato bene.
forse non ascoltarmi.
Parlane con la tua squadra, capisci
quanto sono familiari con Swift e quanto sono eccitati
devono imparare Swift.
Prendi una decisione insieme.
Non posso dirvi cosa fare perché non lo so
cosa è meglio per la tua squadra.
Non conosco le diverse priorità che hai,
e non conosco i diversi vincoli
in cui lavori.
se comunichi tra loro e capisci
cosa funzionerà meglio per tutti voi come squadra
questa è la soluzione migliore.
– [Voiceover] cosa ha fatto parentesi quadre
fare per offenderti così tanto?
– Le parentesi quadre non hanno fatto nulla per offendermi.
Sono abbastanza sicuro di sapere chi ha fatto quella domanda.
(ride) Esattamente.
Non odio le parentesi quadre.
Non odio i punti e virgola, non odio nessuno,
o niente.
Cerco di essere accomodante ora.
Ero arrabbiato.
Parentesi quadre
fanno alcuni tipi di programmazione,
come la programmazione reattiva funzionale
più prolisso di quanto debbano essere,
questo è quello che direi è il caso contro parentesi quadre.
– [Voiceover] Giusto, e naturalmente questi sono
anonimo quando il Canada sta per atterrare su Marte?
– Terra su Marte?
Abbiamo inventato il braccio spaziale,
il Canadarm.
A dire il vero, è in realtà quello che viene chiamato.
Era popolare nei giorni dello space shuttle
ed era come un braccio multi-articolato che poteva piacere
ruotare e afferrare come telescopi spaziali e cose
e piace fare cose con esso.
Grazie per averlo verificato.
Non so quando atterreremo su Marte,
ma so che se lo faremo sarà per il beneficio
di tutta l’umanità, come il nostro oratore principale stamattina
discusso, e non solo per il beneficio di una nazione.
(ride)
– [Voiceover] Altre domande dal pubblico?
– [Voce fuori campo] Ne ho uno perché hai parlato
facendo molti esperimenti, e alcuni di loro, ovviamente,
essere cattivo … – Nessun cattivo esperimento.
– [Voiceover] fine della produzione e qualcuno
li deve mantenere per molto tempo in seguito.
Se tutti stanno sperimentando tutto il tempo
allora ti divertirai a scrivere codice che penso.
– questo è vero.
Suppongo che avrei dovuto stipularlo se un esperimento
non funziona nel modo in cui pensi che dovresti
buttarlo via, o almeno non fonderlo in master.
Le idee sono–
– [Voiceover] di cui stiamo parlando, credo, funzionalità
fotogrammi esperimenti, non come facciamo cose strane
e vedi cosa succede
– Esattamente sono come gli spaghetti contro il muro
approccio, o qualcosa del genere.
Idealmente, lavoreresti agli esperimenti in
un parco giochi, non in un’applicazione di produzione.
È lì che lo faccio, quindi.
– [Voiceover] Ash. – Come va?
– [Voce fuori campo] Bene, com’è stato il tuo discorso per te?
– Un po ‘stanco. (ride)
– [Voiceover] semplicemente facile allora.
c’è stata una diapositiva eccitante in cui hai detto,
“a causa dell’iniezione di dipendenza
“Sono in grado di scrivere test per il mio codice, scrivo anche il mio codice
in un modo migliore. “
Non sono sicuro che lo dica parola per parola,
ma il … – questo è l’essenza generale.
– [Voiceover] E poi, come hai imbrogliato e solo in realtà
non ha cambiato il tuo codice attuale.
Ero un po ‘deluso, quindi puoi commentare?
– Certo, sì, quindi non ho cambiato il codice
perché l’intera classe era come otto linee e non c’è
non molto da cambiare.
Stavo cercando di mostrare quanto fosse semplice
fare un’iniezione di dipendenza e questo è un po ‘
un imbroglio, ma mi concentravo sulla pedagogia
esempio di insegnarti come fare l’iniezione di dipendenza
e non al momento come scrivere un codice migliore
con test unitari.
In quel caso specifico non sarebbe il
visualizzare controller necessariamente che sarebbe stato cambiato.
è il controller di rete, la cosa che fa
la richiesta di rete.
Se il controller della vista può accedervi solo attraverso
il protocollo chiaramente definito, quindi è meno probabile
chiamare le funzioni interne che non dovrebbe
essere consapevoli e in questo modo si ha un accoppiamento molto lento.
Il controller di visualizzazione e il controller di rete
non si conoscono l’un l’altro, se non attraverso esplicitamente
modi definiti e limitati.
Non fanno cose come il controller di rete
non è in grado di aggiungere una sottoview.
Il controller della vista non è in grado di analizzare JSON.
Queste sono due diverse preoccupazioni separate
e dovrebbero essere in classi separate
e la loro comunicazione reciproca dovrebbe essere
molto ristretto.
Penso che forse in una versione futura di questo discorso
forse uno che è invece di chiamarlo come,
“Fondere le migliori pratiche”, cosa succede se ho effettivamente un discorso
sui test unitari, forse vorrei approfondire questo argomento.
Grazie.
Dovrei ricordarti di valutare questa sessione.
Grazie ancora a tutti, sei stato un grande pubblico.
(applausi)
Please follow and like us: