O aplicatie bine structurata consta din obiecte simple, cu responsabilitati bine definite, vorbind intre ele. Cand proiectati un obiect, s-ar putea sa va ganditi la proprietatile unui obiect si la actiunile pe care le intreprinde, dar este la fel de important sa decideti cum vor comunica.
Cacao ofera o mana de modele fara prea multe indrumari cu privire la utilizarea lor. Astazi, sa contrastam delegatii cu observatorii.
Cand nu stiu ce tipar sa folosesc, incep prin a incerca delegarea.
Array
Este minunat pentru relatiile individuale intre obiecte. Este usor de depanat si veti obtine mai multe verificari in timp de compilare decat alte modele.
Notificarile sunt ideale in relatiile unu-la-mai multe, cu comunicare unidirectionala. Luati in considerare tastatura iOS. Imaginati-va daca iOS a folosit delegatul aplicatiei pentru a notifica evenimentele de pe tastatura:
func application (application: UIApplication, willShowKeyboardAtFrame frame: CGRect) {
homeViewController.
Array
adjustKeyboardAtFrame (frame) profileController.adjustKeyboardAtFrame
(frame)
messagesController.adjustKeyboardAtFrame (frame)
}
Cu fiecare dintre acele controlere care se ocupa de controlere pentru copii, avem un cazan fragil, predispus la erori. Daca refactorizati intr-un obiect „dispecer global” mai usor de intretinut, va dati seama ca ati reinventat centrul de notificare.
Atunci cand abuzat, notificarile sunt ca un programator de cacao lui Goto declaratie.
Array
Atunci cand declansati o notificare, efectele secundare pot aparea oriunde in aplicatia dvs. si este greu de prezis ordinea acestora. Acest lucru creeaza un flux de control care este innebunitor de depanat.
Protocoalele cresc mai bine pe masura ce comunicarea devine mai complexa. Notificarile necesita o multime de cabluri de rulare nesigure, fara minte.
- simpson porno s67.net
- film porno clara morgane gbqnet.biz
- porno petite fille mideafire.com
- porno forcé 3eda.com
- porno fairy tail mchughzoo.com
- porno orzel alakhyog.org
- porno katsumi xvido.com
- porno sur netflix dontfuckwithmrzero.com
- porno chien mydlarz.com
- porno gay noir perfectphotos.com
- roman porno completefwd.com
- porno punition exboll.com
- porno doeda nimseye.com
- porno mere fille i-hate-carmax.net
- catherine ringer porno letmewhatchthis.com
- porno avec chien orangepapers.org
- arielle dombasle porno tripro.com
- porno marc dorcel chiloan.net
- porno horreur pallmallcolors.com
- porno island games movilexito.com.co
- porno yoga keywordqueryresults.com
- porno cousine unfuckit.info
Utilizati observatori pentru difuzare si delegare pentru conversatii.
Imaginati-va aplicatia ca pe un magazin. De cele mai multe ori ar trebui sa purtati conversatii individuale, ca atunci cand un functionar spune unui client unde se afla un produs. Ocazional, trebuie sa transmiteti intr-o camera plina de oameni, „Vom inchide intr-o jumatate de ora”.
Daca difuzati cand ar trebui sa utilizati conversatii individuale, jucati jocul telefonic; este ineficient si uneori mesajele sunt abandonate. Daca cineva are conversatii prin megafoane, strigati rapid unul peste celalalt si trebuie sa va faceti griji cu privire la ascultatorii.
Sa construim o aplicatie de cumparaturi precum Amazon. Afiseaza produse. Fiecare produs are o fotografie, un nume si un pret. O singura instanta de produs poate aparea in mai multe locuri, cum ar fi pagina de pornire si cosul dvs. de cumparaturi.
clasa Produs {
var fotografie: UIImage?
private var photoURL: URL
var price: Float
var name: String
}
Decidem sa incarcam lenes fotografiile. Prima data cand accesati proprietatea foto, incepe o descarcare si revine la zero. Cateva clipe mai tarziu fotografia este disponibila. Sa descompunem responsabilitatile si sa le conectam.
In primul rand, unde ar trebui sa punem codul de retea? L-am putea arunca in entitatea noastra; poate creati o clasa NetworkEntity si o subclasati pentru toate obiectele din aplicatia noastra?
Ar trebui sa preferam compozitia decat mostenirea. Responsabilizarea unui alt obiect pentru descarcarea resurselor reduce responsabilitatile Produsului si faciliteaza testarea lucrurilor.
Din moment ce ne uitam la zeci de instante independente prin intermediul aplicatiei noastre, ar fi minunat sa canalizam toate cererile printr-o singura instanta a acestui lucru care descarca resurse, astfel incat sa putem restrange sau anula solicitarile. Cum il conectam? Sugestie: nu este o singura singura.
Vom folosi un delegat. Ei bine, din punct de vedere tehnic o sursa de date aici, dar este aceeasi afacere.
typealias ImageResponse = (UIImage ?, NSError?) -> () protocol ProductDataSource: class {
func product (product: Product, requiredPhotoWithURL url: NSURL, callback: ImageResponse)
} class Produs {data
slaba var Sursa: ProductDataSource?
var fotografie: UIImage?
private var photoURL: URL
var price: Float
var name: String
}
Observati ca nu spunem „retea” nicaieri in delegat. Poate fi preluat din HTTP sau doar incarcandu-l dintr-o memorie cache pe disc.
Ca exercitiu, cum ar arata acest API cu notificarile? Ati putea construi ceva in jurul unei PhotoCacheMissNotification , dar asta se simte gresit.
Notificarile expun starea intregii aplicatii. Trebuie sa stie toata lumea cand un produs solicita o fotografie? Este usor ca logica sa se extinda, iar publicarea acestor informatii in lume o aproba ca API. Este usor sa apara efecte secundare ascunse.
Luati in considerare o celula tableview care reprezinta produsul. Are un buton „Adaugare in cos” care ii spune controlerului nostru de vizualizare sa adauge produsul in cosul de cumparaturi.
class ProductCell: UITableViewCell {
var addToCartButton: UIButton!
var produs: Produs!
}
Este greu de utilizat tinta / actiunea, deoarece trebuie sa stiti ce produs ar trebui adaugat. Exista un antipattern comun pentru a conecta vizualizarile la controlere prin notificari, cum ar fi o notificare AddToCard care include produsul in userInfo.
Ce se intampla daca aveti doua instante din aceeasi clasa de controler de vizualizare in doua file diferite? O fila ar putea avea „Best Sellers” si o alta „Recomandat pentru dvs.”. Ambele controlere de vizualizare ar putea afisa acelasi produs, ceea ce ar adauga produsul in cosul de cumparaturi de doua ori.
Filtrarea notificarilor devine dificila. Parametrul „obiect” utilizat pentru filtrare este inutil cu tipurile de valori Swift, iar filtrarea prin conditionare poate duce la un mare router monolitic.
In schimb, as conecta butonul la celula tableview, care doar apeleaza:
protocol ProductCellDelegate: class {
func productCell (celula: ProductCell, didTapAddToCartForProduct product: Product)
}
Acum luati in considerare o situatie in care observatorii stralucesc: relatia unu-la-multi a unui produs cu punctele de vedere. Cand imaginea produsului se actualizeaza, dorim ca atat pagina produsului, cat si vizualizarea cosului de cumparaturi sa incarce ultima imagine. Deci, atunci cand imaginea produsului nostru se incarca, declansam:
permiteti ProductDidUpdateNotification: String
Daca dorim sa reducem ceea ce fiecare vizualizare are de urmarit pentru a urmari modificarile, am putea oferi context despre actualizare prin dictionarul userInfo.
Pentru simplitatea exemplelor mele, am folosit delegarea, dar ati putea construi relatii similare cu apeluri de apel. Am folosit NSNotificationCenter in locul KVO si voi explica de ce intr-o postare viitoare.
Daca exista o singura mancare de astazi, preferati conversatia izolata decat transmisia.
Aceasta postare a aparut initial pe sandofsky.com








