Devo usare le proprietà per le proprietà delle proprietà?

4

A volte uso alcune proprietà indirette per impostare o ottenere altre proprietà secondarie,

Dò un esempio

class Page
{
    public string MainText 
    { set { MainParagraph.Text = value; } get { return MainParagraph.Text; }}
    public TextBlock MainParagraph {set; get;}
    public TextBlock FootNotes {set; get;}
}

class TextBlock
{        
    public String Text {set; get;}
    public bool   RightToLeft {set; get;}
}

Senza la proprietà MainText di Page Devo usare myPage.MainParagraph.Text = something e ora uso myPage.MainText = something , tuttavia si può ancora usare la prima alternativa. (Dovrei impedirlo?)

Si noti che Text non è una proprietà reale di Page e in questo modo potrebbe rappresentare alcune proprietà secondarie ma non tutte. C'è qualche compromesso?

Ad esempio per la proprietà RightToLeft preferisco myPage.FootNote.RightToLeft = true perché è un attributo specifico di ogni TextBlock ma MainText potrebbe ancora essere conosciuto come testo principale di ogni pagina.

È meglio rendere FootNotes pubblico, ma MainParagraph privato? Quindi devo definire una proprietà in Page per ogni proprietà di MainParagraph ?

    
posta Ahmad 01.03.2015 - 12:54
fonte

2 risposte

2

Rendere le "proprietà wrapper" come questa va bene se è il modo più pulito per implementare l'API che vuoi che questa classe abbia.

Tuttavia, l'esempio specifico che hai pubblicato mi sembra discutibile, soprattutto perché l'utente della tua classe può ora fare esattamente la stessa cosa in due modi diversi: myPage.MainParagraph.Text e myPage.MainText . Dal momento che l'utente non sa (e non dovrebbe) sapere che si avvolge semplicemente l'altro, questo solleva ogni genere di domande che non dovrebbe dover chiedere. Sì, la documentazione può aiutare, ma a mio parere la confusione e la complicazione aggiunte da questo duplicato superano la convenienza di non dover digitare quei due caratteri in più.

Ciò che probabilmente si vorrebbe fare è nascondere completamente l'oggetto TextBlock e fornire wrapper solo per le proprietà a cui l'utente della pagina deve avere accesso. Quindi, se in seguito decidi che TextBlock non è la migliore implementazione di Page, è molto più facile cambiare le cose. In alternativa, puoi lasciare TextBlock completamente esposto senza wrapper, se pensi di dire all'utente "questo è il modo in cui ottieni l'oggetto TextBlock che la pagina usa" è una scelta migliore per la tua API.

Modifica: Ora che hai aggiornato la domanda, e posso vedere che la tua classe Page contiene due oggetti TextBlock, vorrei insistere molto sul fatto che i due TextBlocks pubblico e senza wrapper. Qualsiasi tentativo di avvolgerli immediatamente porta a una potenziale confusione con la disambiguazione del wrapper MainParagraph dal wrapper Footer dal wrapper Header che probabilmente aggiungerai nella versione 3.0 da qualsiasi delle proprietà TextBlock effettive con cui sono tutti implementati. È molto più semplice esporli entrambi e lasciare che l'API TextBlock faccia il suo lavoro.

    
risposta data 01.03.2015 - 13:12
fonte
3

Credo che dovresti esporre l'oggetto TextBlock da Page o avere metodi delegati in Page per fornire l'accesso ai metodi di TextBlock ma non entrambi. Immagino che dipenda dal numero di proprietà e metodi di TextBlock che vuoi esporre, quindi se sono molti, questi forniscono appena TextBlock e non hanno tutte quelle deleghe semplici.

Puoi anche controllare due refettori opposti dal catalogo di Fowler: Nascondi delegati e Rimuovi Middle Man

    
risposta data 01.03.2015 - 19:44
fonte

Leggi altre domande sui tag