2015-09-18 1 views
11

Per settembre 2015, qui è esattamente come si fa un Singleton a Swift:Qualsiasi motivo non utilizzato utilizza una "variabile" singleton in Swift?

public class Model 
    { 
    static let shared = Model() 
    // (for ocd friends ... private init() {}) 

    func test()->Double 
     { 
     return 3.33 
     } 
    } 

poi altrove ...

// file ViewController.swift, say 
import UIKit 
class ViewController:UIViewController 
    { 
    override func viewDidLoad() 
     { 
     super.viewDidLoad() 
     print("view controller loaded!") 
     print("singleton test! \(Model.shared.test())") 
     } 
    } 

Nessun problema.

Tuttavia. Aggiungo questa piccola cosa ...

public let model = Model.shared 
public class Model 
    { 
    static let shared = Model() 

    func test()->Double 
     { 
     return 3.33 
     } 
    } 

allora, si può semplicemente effettuare le seguenti operazioni progetto di ampio:

class ViewController:UIViewController 
    { 
    override func viewDidLoad() 
     { 
     super.viewDidLoad() 
     print("view controller loaded!") 
     print("singleton test! \(model.test())") 
     } 
    } 

linguaggio convenzionale:

Model.shared.blah() .. . si vede questo in ogni parte del codice di base

"mio" idioma:

model.blah() ... si vede questo ev erywhere nella base di codice

Quindi, questo si traduce in tutto cercando piuttosto:

enter image description here

(Nel progetto, le "variabili di unico" sarebbe cose come scores., networking., heuristics., o qualunque sia il caso potrebbe essere nel tuo progetto.)

Questo quindi, è un idioma "macro-like".

L'unico scopo è l'aspetto del codice.

Semplificazione degli aspetti di ImportantSystem.SharedImportantSystem fino a importantSystem. per tutto il progetto.

Qualcuno può vedere problemi con questo idioma?

I problemi possono essere tecnici, stilistici o di qualsiasi altra categoria, purché siano molto profondi.

+2

dat codestlye! .. – glyuck

+0

Ciao Glyuck. Sono d'accordo con te, è "bitchin". Tuttavia dal momento che (molto sorprendentemente) non lo vedo in alcun punto in un sondaggio della letteratura, dobbiamo considerare eventuali potenziali svantaggi. – Fattie

+3

Sono totalmente confuso. Perché dovresti avere un'istanza globale di un singleton? Un lavoro globale funzionerà, un singleton funzionerà ... WTF è un'istanza globale di un "singleton"? – Grimxn

risposta

8

punto di vista funzionale, questi sono molto simili, ma vorrei consigliare utilizzando la sintassi Model.shared perché questo rende assolutamente chiaro, ovunque lo si utilizza, che hai a che fare con un Singleton, mentre se basta che model fluttuante a livello globale, non è chiaro con cosa hai a che fare.

Inoltre, con le variabili globali (in particolare con il nome semplice come "modello"), si rischia di avere una classe futura che ha le stesse variabili con il nome e fa accidentalmente riferimento a quella sbagliata.

Per una discussione sulle considerazioni generali relative ai globulari v singletons v altri pattern, vedere Global Variables Are Bad che, nonostante il titolo abbastanza importante, presenta una discussione sobria, presenta alcuni link interessanti e presenta alternative.


Tra l'altro, per i vostri "amici OCD" (all'interno del quale credo che devo contare me stesso, perché penso che sia delle migliori pratiche), non solo avrebbe dichiarato init essere private, ma si sarebbe probabilmente dichiara l'intera classe deve essere final, per evitare la sottoclasse (a questo punto diventa ambiguo a quali riferimenti shared).

+1

Sono completamente d'accordo con te; Credo nel ** nome del software assolutamente evidente **. È un grande punto. Sai, quando si sviluppano i giochi (ad esempio Unity) è inevitabile nella maggior parte dei generi che ci siano uno o due singleton (l'intelligenza centrale, punteggio, meteo, ecc.) E in C# di qualsiasi cosa di solito usi qualche idioma per farli scendere a un singola parola o il più breve riferimento possibile; questo probabilmente ha influenzato il mio modo di pensare. (Effettivamente nell'esempio, ogni vista avrebbe il proprio modello, è piuttosto cremoso avere "modello" come esempio singleton nell'ambiente iOS!) Grazie come sempre! – Fattie

+4

Ci sono errori di correzione .. c'è l'ingegneria reale .. e soprattutto, c'è Rob;) – Fattie

1

non riesco a vedere un unico aspetto negativo di questo approccio:

  • È possibile utilizzare variabili diverse per le diverse parti del programma (-> No namespace vadano a finire, se non ti piace questo credo)
  • È breve, carino, facile da usare e ha un senso quando lo leggi. Model.shared.test() non ha senso se ci pensi, vuoi solo chiamare test, perché dovrei chiamare shared quando ho solo bisogno di una funzione.
  • Utilizza lo spazio dei nomi globale pigro di Swift: la classe viene allocata e inizializzata quando la si usa la prima volta; se non lo usi mai, non viene nemmeno assegnato/inserito.

In generale, mettendo da parte il linguaggio esatto in discussione, per quanto riguarda l'uso di single:

  • Ricordiamo che, naturalmente, invece di usare static var shared = Model() come una sorta di macro per un Singleton , come suggerito in questa Q, puoi semplicemente definire let model = Model() che crea semplicemente un normale globale (non correlato ai singleton).
  • Con Swift singleton, si è discusso che probabilmente si desidera aggiungere un private init() {} alla classe, in modo che venga inizializzato solo una volta (notando che init potrebbe ancora essere chiamato nello stesso file).
  • Ovviamente, quando si considera l'uso di un singleton, se non si ha realmente bisogno di uno stato e dell'istanza della classe stessa, è sufficiente utilizzare semplicemente le funzioni/proprietà statiche. È un errore comune utilizzare un singleton (per esempio, funzioni di tipo "calcolo") in cui tutto ciò che è necessario è un metodo statico.
+0

@JoeBlow Modificato "esattamente" su "fondamentalmente" perché sì non è esattamente lo stesso, tuttavia non riesco a pensare ad un modo in cui l'uso di 'modello' si differenziasse usando i due approcci – Kametrixom

+0

@JoeBlow Rimosso anche il codice di funzione statico per renderlo meno prominente :) – Kametrixom

+1

@JoeBlow Immagino che tu abbia ragione con il metodo che stai utilizzando, se in qualche modo decidessi di creare più variabili globali, sarebbero comunque tutte la stessa istanza. Btw davvero non c'è bisogno di taglie;) – Kametrixom

3

Ci sono alcune cose da guardare fuori per quando si utilizza questo metodo:

La variabile globale

Una variabile globale di per sé è un grosso problema, ma se avete abbastanza alcuni variabili globali, si potrebbe avere problemi con il completamento automatico, perché suggerirà sempre queste variabili globali.

Un altro problema con le variabili globali è che si potrebbe avere un altro modulo nell'applicazione (scritta dall'utente o in altro modo) che definisce la stessa variabile globale. Questo causa problemi quando si usano questi 2 moduli insieme. Questo può essere risolto utilizzando un prefisso, come le iniziali della tua app.

L'utilizzo delle variabili globali è generally considered bad practice.

Il pattern Singleton

un singoletto è utile quando si lavora con un controller, o un repository. Viene creato una volta e crea tutto ciò da cui dipende. Può esserci un solo controller e apre solo una connessione al database.Ciò evita molti problemi quando si lavora con risorse o variabili a cui è necessario accedere da tutta la tua app.

Tuttavia, ci sono degli svantaggi, come la testabilità. Quando una classe usa un singleton, il comportamento di quella classe è ora influenzato dal comportamento dei singletons.

Un altro problema possibile è la sicurezza del filo. Quando si accede a un singleton da thread diversi senza il blocco, possono verificarsi problemi difficili da eseguire il debug.

Sommario

Si dovrebbe guardare fuori al momento di definire le variabili globali e di lavoro con single. Con la cura appropriata, non dovrebbero sorgere molti problemi.