Design Mønstre: Singletons 
 26 
 Del 
 6 
 Del 
 
 Dette Cyber mandag Envato Tuts + kurs vil bli redusert å bare $ 3. Ikke gå glipp av. 
 
 Design mønstre blir ofte betraktet som en mer avansert emne og derfor ignorert eller oversett av nye folk til iOS eller OS X utvikling. Det finnes imidlertid en rekke designmønstre alle aspirerende iOS eller OS X utvikler vil bli møtt med fra dag én. Av Singleton mønsteret er et slikt mønster. 
 
 Før vi begynner å se på teknikker for å implementere Singleton mønster i Swift og Objective-C, vil jeg gjerne ta et øyeblikk å forstå Singleton mønster, inkludert sine fordeler og ulemper. 
 
 1. Hva er en Singleton 
 
 Sanne & Funksjonelle Singletons 
 
 The Singleton mønsteret er uløselig knyttet til objektorientert programmering. Definisjonen av Singleton mønsteret er enkelt, bare én forekomst av singleton klasse kan opprettes eller er i live til enhver tid. 
 
 Brent Simmons, men nyansene denne definisjonen ved å gjøre et skille mellom  sant   Jeg er sikker på at mange utviklere ikke vil kategorisere funksjonelle enkeltfødte som enkeltfødte, men jeg liker skillet Brent gjør. Funksjonelle enkeltfødte mangler ofte ulempene typiske å true enkeltfødte. Vi skal se på disse ulempene senere i denne artikkelen.   Hvis du er kjent med iOS eller OS X utvikling, så vil du legge merke til at Apples rammeverk gjøre bruk av Singleton mønster. En iOS-applikasjon, for eksempel, kan bare ha én forekomst av UIApplication klassen, som du kan få tilgang til gjennom sharedApplication klassen metoden   Selv om UIApplication klassen gir deg tilgang til UIApplication enkelt, ingenting som hindrer deg fra å eksplisitt Instantiating en UIApplication eksempel   Resultatet, derimot, er en runtime unntak. Unntaket sier klart at bare én forekomst av UIApplication klassen kan være i live til enhver tid. Med andre ord ble UIApplication klassen utformet med Singleton mønster i tankene   Den mest åpenbare fordelen av Singleton mønsteret er tilgjengelighet. Vurdere UIApplication klassen som et eksempel. Ved å importere den UIKit rammeverket, er UIApplication singleton tilgjengelig fra hvor som helst i prosjektet. Ta en titt på følgende eksempel på en UIViewController underklasse   Det er noen ganger nyttig eller avgjørende at bare én forekomst av en klasse er i live til enhver tid. Den UIApplication klassen er et eksempel på dette kravet. Andre eksempler kan inkludere klasser for logging, caching, eller I /O-operasjoner.   Når det er sagt, er det viktig å forstå at enkeltfødte er et middel for å oppnå kontroll og atferd. Defensive koding teknikker kan gi deg samme resultat uten den mentale overhead av Singleton mønsteret.   Ved å opprette en enkelt, du er i hovedsak å skape global tilstand. Det er viktig at du er klar over dette. For noen år siden skrev Miško Hevery en stor artikkel om Singleton mønster der han forklarer hvorfor mønsteret bør unngås. Miško understreker at global stat er hovedårsaken til at enkeltfødte er skadelig.   Det finnes unntak skjønt. For eksempel kan enkeltfødte som er uforanderlig gjøre lite skade. Du er fortsatt skaper global tilstand, men at tilstanden er uforanderlig. Miško nevner også loggere som a-noe-akseptabel bruk av Singleton mønsteret siden staten flyter i én retning, fra programmet inn i logger.   De fleste objektorienterte programmeringsspråk vurdere tett kobling av moduler en dårlig praksis. Sagt på en annen, er det anbefalt å kople moduler så mye som mulig. Dette setter Singleton mønster i et dårlig sted og enkeltfødte blir derfor betraktet som en dårlig praksis av mange respekt programmerere. Noen utviklere gå så langt som vurderer det en anti-mønster som bør unngås.   For å bedre forstå problemet, bør du vurdere følgende scenario. Du har opprettet en iOS-applikasjon med en nettverkskomponenten der du får tilgang til UIApplication enkelt. IOS-applikasjonen er en slik suksess at du vurdere å opprette en OS X-program. Den UIApplication klasse, men er ikke tilgjengelig på OS X på grunn av mangel på UIKit rammeverket. Dette betyr at du må refactor eller endre nettverkskomponenten av iOS-programmet.   Det finnes en rekke løsninger for å løse dette problemet, men poenget jeg ønsker å gjøre er at du tett har kombinert nettverk modulen til UIKit rammer, UIApplication klasse i særdeleshet.   Tett integrasjon er ofte nært knyttet til gjenbruk. En tett koblet objekt grafen er svært ofte vanskelig å gjenbruke uten refactoring. Dårlig gjenbruk er noen ganger uunngåelig, men det er absolutt noe å huske på når du utvikler programvare.   Opprette et enkelt inne Objective-C er veldig enkelt å gjøre. I det følgende kodebiten, skaper vi og implementere en logging klasse, Logger. Vi får tilgang til singleton objekt gjennom sharedLogger klassen metoden   implementeringen er enkel. Vi erklærer en statisk variabel _sharedInstance som vil holde en referanse til singleton objekt. Vi påberope dispatch_once, en Grand Central Dispatch funksjon, og passerer i en blokk der initial vi en forekomst av Logger klassen. Vi lagrer en referanse til forekomsten i _sharedInstance   dispatch_once funksjonen sørger for at blokken vi passerer det utføres en gang for levetiden til programmet. Dette er veldig viktig siden vi bare ønsker å initial én forekomst av Logger klassen.   oncePredicate variable som er gått som det første argumentet til dispatch_once funksjonen brukes av dispatch_once funksjon for å sikre at blokken blir utført bare én gang.   sharedLogger klassen metoden returnerer Logger eksempel ved å returnere referansen lagret i _sharedInstance. Gjennomføringen av sharedLogger kan se skremmende i starten, men jeg er sikker på at du enig i at ideen er veldig enkel.   For å gjennomføre Singleton mønster i Swift, gjør vi bruk av klasse konstanter, som ble introdusert i Swift 1.2. Hvis du har problemer med under kodebiten, så sørg for at du bruker Xcode 6.3+.   La meg gå gjennom den korte gjennomføringen av Logger klasse. Vi starter med å erklære en klasse som heter Logger. Å gjennomføre Singleton mønster, erklærer vi en type eiendom, sharedInstance, av type Logger.   Ved å bruke den statiske nøkkelordet, den sharedInstance konstant er knyttet til Logger klassen i stedet for forekomster av klassen. Den sharedInstance konstant betegnes som en  skriver eiendom   Du lurer kanskje på hvorfor vi ikke bruker dispatch_once funksjon som vi gjorde i Objective-C gjennomføring. Under panseret, bruker Swift allerede dispatch_once når initialisering statiske konstanter. Det er noe du får gratis i Swift.   En annen vanlig metode for gjennomføring av Singleton mønsteret er ved å utnytte nestede typer. I følgende eksempel, erklærer vi en beregnet typen eiendom, sharedInstance, av type Logger. I nedleggelsen av den beregnede typen eiendom, erklærer vi en struktur som heter Singleton. Strukturen definerer en konstant typen eiendom, f.eks av typen Logger   Tilgang til Singleton formål er den samme for begge strategier. Hvis du bruker Swift 1.2, så jeg anbefaler å bruke den første tilnærmingen for sin kortfattethet og enkelhet.   Da jeg først hørte om Singleton mønster, var jeg spent på hvor nyttig det ville være i mitt neste prosjekt. Det er meget fristende å bruke et verktøy som virker til å løse mange problemer. Ved første øyekast kan det Singleton mønsteret ser ut som en sølvkule eller en gyllen hammer, men det er ikke det av Singleton mønsteret er.   For eksempel, hvis du bruker en singleton bare for å gjøre det lett tilgjengelig , så du kan være ved hjelp av Singleton mønster for de gale grunnene. Det er ikke fordi Apple bruker av Singleton mønster i sine egne rammer at det er den riktige løsningen på alle problemer.   Singletons kan være svært nyttig, men de blir ansett som et anti-mønster av mange erfarne programmerere. De fleste av dem har hatt dårlige erfaringer med mønster for å komme til denne konklusjonen. Lære av sine feil og bruke dem med måte.   Jeg anser ikke av Singleton mønsteret en anti-mønster, men det er et mønster som bør brukes med forsiktighet. Hvis du føler deg fristet til å slå et objekt i et enkelt, spør deg selv spørsmålet om det er noen annen måte som du kan løse problemet. I de fleste tilfeller er av Singleton mønsteret ikke er den eneste løsningen som er tilgjengelig. En alternativ løsning kan kreve mer arbeid eller en bit av overhead, men det er trolig bedre i det lange løp.   De funksjonelle enkeltfødte Brent Simmons viser til er ofte en helt gyldig alternativ til ekte enkeltfødte. Det er ingenting galt med å opprette en forekomst av en klasse, og den sendes til objektene som trenger det. Vurdere denne tilnærmingen neste gang du er om å skape et annet enkelt.   The Singleton mønsteret er enkel og kraftig, men det bør brukes med måte. Noen av dine kolleger kan råde deg mot det, men jeg tror det er viktig å vurdere bruken og døm selv om du tror det er et nyttig tillegg til verktøykassen.
 enkeltfødte og  funksjonelle 
 enkeltfødte. Brent definerer sanne enkeltfødte som klasser som alltid returnere samme forekomst av seg selv. Det er ikke mulig å lage mer enn én forekomst av klassen. Funksjonelle enkeltfødte opprettes én gang og brukes flere steder. 
 
 
 UIApplication * sharedApplication = [UIApplication sharedApplication];. La sharedApplication = UIApplication.sharedApplication () 
 UIApplication * newApplication = [[UIApplication Alloc] init];. la newApplication = UIApplication () 
 *** Avslutte app grunn uoppfanget unntak 'NSInternalInconsistencyException', grunn: ".. Det kan bare være én UIApplication eksempel '
 Fordeler 
  Tilgjengelighet 
 
 #import < UIKit /UIKit.h >interface ViewController. UIViewController @ slutten # import "ViewController.h"@implementation ViewController # pragma mark - # pragma mark Vis Livet Cycle- (void) viewDidLoad {[super viewDidLoad]; //Tilgang Application Singleton UIApplication * søknad = [UIApplication sharedApplication];} @ slutten  Kontroll og Behavior 
 
 
 
 Ulemper 
  Global State 
 
 
  Tight Coupling 
 
 
 
  Gjenbruk 
 
 
 2. Opprette en Singleton 
 
 Objective-C 
 
 #import < Foundation /Foundation.h >interface Logger. NSObject # Pragma mark - # pragma mark Klassemetoder + (Logger *) sharedLogger;end 
 #import "Logger.h"@implementation Logger # Pragma mark - # pragma mark Klassemetoder + (Logger *) sharedLogger {statisk Logger * _sharedInstance = null.; statisk dispatch_once_t oncePredicate; dispatch_once (& oncePredicate, ^ {_sharedInstance = [[selvtillit Alloc] init];}); returnere _sharedInstance;} @ slutten 
 
 
 
 Swift 
 
 Klasse Logger {statiske la sharedInstance = Logger ()} 
 
 ettersom det er knyttet til den type, det vil si den Logger klasse. Vi får tilgang til singleton objekt gjennom Logger klassen. 
 Logger.sharedInstance 
 
 klasse Logger {class Var sharedInstance: Logger {struct Singleton {statiske la eksempel: Logger = Logger ()} returnere Singleton.instance}}. 
 
 3. Når man skal bruke Singletons? 
 Jeg antar at det er fristende, hvis det eneste verktøyet du har er en hammer, for å behandle alt som om det var en spiker. - Abraham Maslow 
 
 
 
 
 
 Konklusjon 
 

