È appropriato elaborare una proprietà nel setter?

4

Ho una classe con una proprietà Name , in cui il nome è impostato dall'utente finale. Per garantire la compatibilità con il resto dell'ambiente e per evitare il rifiuto di molti input, alcuni processi del nome vengono eseguiti automaticamente:

public string Name {
    get { return _Name; }
    set {
        if (value == null)
            return;
        _Name = value.Replace("/", "-").Replace("%", "pct").Replace("&", "-").Replace("'", "").Trim();
        _RawName = value;
    }
}

La mia preoccupazione riguarda incapsulamento e SRP.

Mi chiedo se qualcosa come nessuna elaborazione, e quindi un metodo come myObject.processName() sarebbe meglio da un punto di vista dei principi (e se ho ragione penso che non sia chiaro come la mia attuale implementazione).

Ho letto attentamente una domanda simile a , ma discute solo della convalida, e questo va oltre, e i dati sono manipolati.

- Non c'è nessun tag beginner qui, quindi lascia che lo metta qui. Sono nuovo di tutto questo, ti prego di perdonare qualsiasi domanda stupida:)

    
posta Maxime 27.10.2017 - 15:46
fonte

4 risposte

3

Questo rompe il principio della sorpresa minima. Per una proprietà con un getter e un setter, si suppone che siano simmetrici, cioè. ottieni la stessa cosa che hai impostato, almeno semanticamente. Qui si imposta una cosa, ma si ottiene una cosa diversa che è una sorta di stringa sterilizzata o codificata in cui alcune informazioni sono state rimosse.

Probabilmente l'evento non dovrebbe rappresentare questi due tipi di valori (nomi grezzi e sterilizzati) come stringhe nude, dal momento che sei obbligato a mescolarli a un certo punto.

Potresti avere due proprietà, RawName e SanitzedName . SanitzedName non dovrebbe avere un setter, dato che la codifica è a senso unico.

    
risposta data 27.10.2017 - 18:59
fonte
2

No, non va bene; tuttavia, non è nemmeno la cosa peggiore del mondo. Rifiuterei un PR con questo, ma non mi arrabbierò con te;)

Supponiamo che tu lo distribuisca in produzione ... alcuni mesi passano e poi ricevi un'email dal tuo PM:

Max, the user wants to know why the "%" was removed from his name, they are very annoyed as the "%" is indicative of their title in their country. Now, I know there is a reason you have to do that, so if the user enters a weird character, just display to them a message explaining that is will be stripped.

Un luogo migliore per fare i servizi igienici sarebbe il getter, che rende la tua classe più flessibile, puoi quindi aggiungere un'altra proprietà boa WasSanitized, quindi non hai bisogno del campo RawName extra.

Meglio ancora, non avere questa logica in questa classe. È un errore comune pensare che l'igiene degli utenti sia una preoccupazione aziendale; ma non è. La convalida dell'input di base non appartiene a un oggetto business. Se hai tutte queste considerazioni in questa classe, la classe ha troppe responsabilità trasversali ... è passato dalla modellazione di un'entità aziendale alla modellazione di un'entità aziendale e validazione dell'input dell'utente.

La pulizia dei dati di input di base è un problema di interfaccia utente, mantieni questo codice nel tuo livello di interfaccia utente, la tua base di codice sarà molto più pulita. Mantenere questa logica nella classe ti mette a rischio per l'anti-pattern "ambiguo punto di vista".

    
risposta data 27.10.2017 - 17:58
fonte
0

Penso che vada bene.

Ciò che non vorresti è se viene eseguito di nuovo sull'output, quindi produce un output diverso. Ad esempio Replace("-", "--") .

    
risposta data 27.10.2017 - 15:59
fonte
0

Penso che sia più chiaro in quanto non mescola le preoccupazioni con una singola proprietà.

 public class Name
    {
        public string Raw { get; set; }

        public string Formatted
        {
            get
            {
                return string.IsNullOrWhiteSpace(Raw) ? null : Raw.Replace("/", "-").Replace("%", "pct").Replace("&", "-").Replace("'", "").Trim();
            }
        }

        public Name(string raw)
        {
            Raw = raw;
        }
    }
    
risposta data 27.10.2017 - 18:58
fonte

Leggi altre domande sui tag