C ++ vs Objective-C principi di progettazione di setter e getter

3

In C ++ mi è stato detto che le mie classi non dovrebbero avere getter e setter: Fare torto ... post del blog .

D'altra parte, in Objective-C, l'uso diretto di ivar è sconsigliato, perché i getter permettono di eseguire un'istanza pigra ei setter rendono semplice KVO.

Perché questa differenza?

    
posta toasted_flakes 03.03.2013 - 09:25
fonte

3 risposte

7

Penso che il miglior take-away dal post "Do it it wrong ..." sia che l'esposizione di utenti pubblici senza una buona ragione rompa l'incapsulamento dando alle classi esterne la possibilità di modificare e ispezionare lo stato che non dovrebbe essere reso pubblico. Si esprime solo in modo assolutistico (direi che se hai un oggetto Contact e vuoi mettere il nome di quel contatto su un'etichetta per un'applicazione di rubrica, a un certo punto Contact probabilmente dovrà esporre la sua name a un altro oggetto). Indipendentemente da ciò, qualunque sia il linguaggio, rendendo accessibili gli accessor senza il pensiero, si interromperà l'incapsulamento e si determinerà un accoppiamento stretto.

Questo è ortogonale alla migliore pratica in Objective-C di usare i metodi di accesso per tutti (almeno la maggior parte) l'accesso alle variabili di istanza. No, dove Objective-C consiglia di rendere tutti i tuoi accessor visibili pubblicamente. Spesso avrai un'estensione di classe visibile solo all'implementazione della classe che definisce la maggior parte delle sue variabili di istanza e quindi l'implementazione della classe utilizza gli accessor. E certamente, il codice esterno dovrebbe sempre usare gli accessor, ma dovrebbero essere resi visibili solo al codice esterno se assolutamente necessario.

    
risposta data 03.03.2013 - 10:55
fonte
1

Gli incastonatori e i getter sono la tecnologia derivata dalle proprietà visive di base negli anni '80. Poiché vengono spesso utilizzati insieme alle tecniche di programmazione che provengono anche dallo stesso luogo, è considerato una cattiva pratica. Il problema con getter e setter è che il comportamento della classe viene spostato all'utente della classe e la classe non gestisce più il proprio comportamento; ma supporta il qualsiasi comportamento possibile. Questo non crea una buona classe, dal momento che non sta facendo le decisioni che normalmente fanno parte della responsabilità della classe.

    
risposta data 03.03.2013 - 10:04
fonte
0

Come sviluppatore C #, uso sempre getter / setter. Poiché raramente (ma continuo a farlo) uso C ++, potrei offrire una prospettiva diversa su questo.

Ai miei occhi, la maggior parte della differenza di accettabilità tra C ++ e C # è dovuta alle convenzioni tra gli utenti di una lingua (anche se ce ne sono altri che farò in seguito ...). Il più delle volte in C ++, non ho bisogno di usare un getter / setter perché non è incoraggiato a farlo. A differenza del post sul blog, non lo vedo nemmeno come "modo corretto di codificare" o "modo sbagliato di codificare". È una convenzione che consente ad altri umani di fare testa o croce su ciò che ho scritto / mantenuto.

C # non attenua questa necessità e, per quanto ho visto, non ci sono prove che affermino che i getter / setter in C # sono più o meno efficaci dei metodi in C ++ (suppongo che siano all'incirca stesso ordine, ma questa è una sensazione istintiva, lì.) Tuttavia, la sensazione generale nella comunità C # è che, mentre i metodi sono preferibili, le proprietà sono ottime per l'utilizzo di metodi come:

public string GetName()
{
    return _lastName + ", " + _firstName + " " + _middleInitial;
}

public string SetName(string fullName)
{
    // Assumptions are made here; this is just example code!
    string[] frags = fullName.Split(' ');
    _firstName = frags[0];
    _middleName = frags[1];
    _lastName = frags[2];
}

e creando una sintassi leggermente più breve, diversa, ma ragionevolmente leggibile come:

public string Name
{
    get { return _lastName + ", " + _firstName + " " + _middleInitial; }
    private set 
    {
        string[] frags = value.Split(' ');
        _firstName = frags[0];
        _middleName = frags[1];
        _lastName = frags[2];
    }
}

Potresti dire che a un programmatore C # o Java, vediamo le proprietà come zucchero sintattico per i metodi semplici, dato che è tutto un getter / setter in realtà: un metodo.

Un'altra ruga nelle tecnologie si trova in vari quadri. Ad esempio, nel mio attuale negozio, i nostri progetti MVC sono configurati in modo tale che siamo più o meno richiesti per utilizzare getter e setter da parte di NHibernate e dello stesso framework MVC. Abbiamo avuto conversazioni sulla sovrabbondanza percepita di proprietà nella nostra app, ma alla fine non abbiamo avuto alcun ricorso tecnico per rivedere quelli con metodi semplici. Dobbiamo usare le proprietà perché la riflessione è usata per recuperare le proprietà e quindi i loro contenuti. Il nostro codice sarebbe più grande e più cattivo senza di loro, quindi nessuno si lamenta davvero tanto.

Per rispondere finalmente alla tua domanda, penso che mi tuffi nel vivo della questione.

Un programmatore C ++ si aspetta di bisogno dei dettagli tecnici profondi di una determinata operazione; invece di oscurare questa macchinazione con lo zucchero sintattico, è più comprensibile solo mordere il proiettile e fare il lavoro. Non è che i programmatori C ++ siano avversi allo zucchero sintattico (in effetti, mi trovo a desiderare modi migliori per esprimere il mio codice C ++ quando lo uso ...), ma le cose che si trasformano in C ++ e le cose che si usano le proprietà tipicamente non si adattano bene a livello pratico *.

Un programmatore C # o Java sta sfruttando la macchina virtuale interposta tra il livello fisico e il nostro codice di alto livello; perdiamo poco utilizzando lo zucchero sintattico, e guadagnando (leggermente) una migliore leggibilità senza violare completamente l'incapsulamento ... a condizione che i getter / setter siano implementati correttamente. Le cose che passi a C # o Java per fare mesh bene con le proprietà a livello pratico.

*: Si noti che non sono un utente C ++ frequente! Chiedo correzione, se qualcuno ne ha da dare.

    
risposta data 04.03.2013 - 22:51
fonte

Leggi altre domande sui tag