В принципе нет ничего плохого в том, что функции имеют доступ к полям объекта, но конкретный пример, который вы приводите, пугает меня, потому что цена упрощения ваших вызовов функций заключается в том, что вы запутываете жизненный цикл своих данных.
Чтобы перевести пример args в поля, вам нужно что-то вроде:
void Start() {
// read FieldA, FieldB, and FieldC
// set the value of FieldD
}
void Process() {
// read FieldA and do something
// read FieldD and do something
}
void Stop() {
// read the value of FieldC
}
Start()
устанавливает FieldD
побочным эффектом. Это означает, что, вероятно, нельзя звонить Process()
до тех пор, пока вы не позвоните Start()
. Но код не говорит вам этого. Вы только узнаете, выполнив поиск, чтобы увидеть, где FieldD
инициализируется. Это просит ошибок.
Мое эмпирическое правило заключается в том, что функции должны обращаться к полю объекта только в том случае, если всегда безопасно для доступа к этому полю. Лучше всего, если это поле инициализируется во время создания, но поле, которое хранит ссылку на объект соавтора или что-то, что может со временем измениться, тоже хорошо.
Но если не допустимо вызывать одну функцию, за исключением случаев, когда другая функция выдала какой-либо вывод, этот вывод должен быть передан, а не сохранен в состоянии. Если вы рассматриваете каждую функцию как независимую и избегаете побочных эффектов, ваш код будет более понятным и понятным.