Funzioni di classe che popolano le proprietà della classe

1

Quali sono i pensieri su come chiamare una funzione di classe che non restituisce nulla, ma imposta valori di proprietà interni che poi leggi.

var myClass = new MyClass();
myClass.DoFunction(specialDate, "A");

// after calling DoFunction() the Name and Type property are now set
var name = myClass.Name;
var type = myClass.Type;

In cima alla mia testa questo mi sembra un modo scomodo di fare le cose rispetto al fatto che DoFunction () restituisca un oggetto che contiene le proprietà Name e Type. Pensieri?

    
posta user441521 05.01.2018 - 19:48
fonte

6 risposte

3

Questo è ragionevole. Dato che hai già un campo Nome e Tipo, facciamo finta che questo sia un tipo di classe "Persona". Potresti avere un metodo

person.updateFromRecentMarriageRecords(MarriageRecords)

che potrebbe cambiare il nome (ad esempio, dal nome da nubile al nome del coniuge) e digitare (da "singolo" a "sposato").

    
risposta data 05.01.2018 - 21:35
fonte
4

Un esempio ovvio di questo modello che posso pensare è uno stream: se chiamo i metodi Read o Write di qualche flusso .net, la proprietà Position viene aggiornata / avanzata dal numero di byte lettura / scrittura. Un altro potrebbe essere dataset.ReadXml - il metodo accetta un percorso file e deserializza xml, popolando il set di dati con tabelle e righe che rappresentano l'xml. Non restituisce l'xml: se vuoi guardarlo devi controllare il set di dati dopo aver chiamato read, e un vasto numero di proprietà diventa di conseguenza impostato su vari valori diversi

Come tale, anche se personalmente non penso che sia un modello lodevole in molti casi, è certamente contestualizzato e ha senso in alcuni. Il caso che hai postato sembra un pessimo esempio perché non vedo come impostare una data e una stringa possa ragionevolmente alterare un nome e un tipo, ma forse questo è dovuto al fatto che l'esempio della tua domanda è un accenno di stile Foo / Bar. Per un po 'ho pensato di trovare un riscontro per l'esempio che hai pubblicato e ho trovato il seguente:

Se avessi calenderEntry.setDateAndLocation , le proprietà Name e Type potrebbero essere impostate su qualche cosa contestuale pertinente:

calendarEntry.setDateAndLocation(Date.Parse("4 Jul 2018"), "USA")
calenderEntry.Name //now "Independence Day"
calendarEntry.Type //now PublicHoliday

Quindi, sì ... potrebbe funzionare - non dire che è un modello universalmente saggio ma se pubblichi una resa più accurata di dove stavi pensando di usarlo, quali nomi e processi sono coinvolti nel contesto, allora potremmo forse essere un po 'più a bersaglio di "dipende".

    
risposta data 06.01.2018 - 00:27
fonte
3

Tali domande sono per lo più prive di senso usando termini arbitrari come "Foo" o "Bar", o in questo caso DoFunction e MyClass , invece di usare termini appropriati che riflettono la vera funzione oi nomi di classe. Ecco un esempio che potrebbe avere un senso:

var myPoint = new Point2D(); // lets assume for some reason 'Point2D' is mutable
// ... and though there is a constructor taking x and y, you also want to be able
// ... to change those values later.

// Now, ..
myPoint.SetXY(123,456); 
// as a shorter form of myPoint.X=123, myPoint.Y=456
// can be useful as syntactic sugar, when X and Y are very often changed together

// still X and Y can be retrieved individually
var x = myPoint.X;
var y = myPoint.Y;

Ma posso facilmente immaginare un diverso esempio in cui questo non ha senso (e sono sicuro che anche tu puoi farlo). Quindi non cercare le regole generali di Braindead, in cui puoi decidere se un codice è buono o cattivo solo a causa di una struttura formale, ma guarda se l'astrazione che i metodi e le classi creano sono utili e sensate.

    
risposta data 05.01.2018 - 22:24
fonte
2

Per quanto ho capito, quel tipo di funzione è chiamato setter. Consentono di verificare le regole di convalida prima che la variabile di classe venga apportata all'input. Ulteriori informazioni su Getter & setter: link

    
risposta data 05.01.2018 - 20:45
fonte
2

Una classe è un meccanismo per creare astrazioni.

Un'astrazione è un raggruppamento di capacità (metodi e stato) che offre al cliente consumatore (un programmatore, spesso noi stessi) qualcosa di utile in un singolo concetto, nascondendo alcuni dettagli irrilevanti (a volte b / c nel mondo reale i dettagli sono irrilevanti e spesso b / c l'implementazione interna dell'offerta è un dettaglio che il client consumatore non deve / non dovrebbe sapere per usarlo)

È meglio avere astrazioni coerenti. Un modo per giudicare la coerenza di un'astrazione è guardare le vite dello stato. La vita di tutti i campi di un oggetto, idealmente, è la stessa (come l'oggetto stesso).

Quando l'oggetto viene creato e i suoi campi vengono inizializzati insieme e tale oggetto è un'astrazione più o meno coerente. I campi possono essere aggiornati durante l'operazione dell'oggetto, sebbene rimanga sempre in uno stato utilizzabile.

Quando scopriamo che alcuni campi dell'oggetto non sono necessariamente inizializzati allo stesso tempo, suggerisce una combinazione di due diverse astrazioni.

Quindi, dato quello che posso vedere nelle vostre domande, considero tale approccio avere margini di miglioramento. Puoi modificarlo come segue:

  • rimuovi il metodo DoFunction() e passa i parametri nel costruttore in modo tale che l'intero scopo dell'oggetto

  • restituisce un oggetto diverso come valore di ritorno, una nuova classe che raggruppa insieme i vari campi di interesse.

risposta data 05.01.2018 - 21:29
fonte
1

Non è sempre necessario o si desidera restituire qualcosa dopo aver impostato le variabili.

Se possibile, invia i valori tramite il costruttore e impostali in fase di inizializzazione.
Ma se non hai valori in quel momento, puoi usare una funzione set per assegnarli in seguito. Non c'è bisogno di un ritorno qui.
Inoltre, se è necessario modificare alcuni di questi valori in futuro, di nuovo, è possibile utilizzare la funzione set per farlo. Non è necessario il reso.
Se le tue variabili non sono visibili al di fuori dell'ambito della tua classe, avrai bisogno dei metodi set e get per affrontare tale situazione.

Ecco alcuni esempi di tale utilizzo:

myClass(n='', t='')
    setName(n)
    setType(t)

    setName(n)
        name = n
    setType(t)
        type = t

    doSomethingToName()
        setName('some other name')

    doSomethingToType()
        setType('some other type')


myC = myClass() //Initialization with no values

myC.setName('name')
myC.setType('type')

print myC.name //Prints 'name'

myC.doSomethingToName()
print myC.name //Prints 'some other name'
print myC.type //Prints 'type'

myC1 = myClass('myName', 'myType') //Initialization with values
print myC1.name //Prints 'myName'
print myC1.type //Prints 'myType'
    
risposta data 05.01.2018 - 20:44
fonte

Leggi altre domande sui tag