Предпочитаете членов класса или передавать аргументы между внутренними методами?


39

Предположим, что в частной части класса есть значение, которое используется несколькими частными методами. Предпочитают ли люди определять это как переменную-член для класса или передавать его в качестве аргумента каждому из методов - и почему?

С одной стороны, я мог бы привести аргумент, что сокращение состояния (т.е. переменных-членов) в классе, как правило, хорошо, хотя, если одно и то же значение многократно используется во всех методах класса, кажется, что это было бы идеальным кандидат на представление в качестве состояния для класса, чтобы сделать код заметно чище, если ничего больше.

Редактировать:

Чтобы прояснить некоторые из поднятых комментариев / вопросов, я не говорю о константах, и это не относится к какому-либо конкретному случаю, а является лишь гипотетической гипотезой, о которой я говорил с некоторыми другими людьми.

На мгновение не обращая внимания на угол ООП, я имел в виду следующий конкретный случай использования (предположим, что передача делается по ссылке только для того, чтобы очистить псевдокод).

int x
doSomething(x)
doAnotherThing(x)
doYetAnotherThing(x)
doSomethingElse(x)

Так что я имею в виду, что есть некоторая переменная, которая является общей для нескольких функций - в случае, который я имел в виду, это было связано с цепочкой меньших функций. В системе ООП, если бы это были все методы класса (скажем, из-за рефакторинга посредством извлечения методов из большого метода), эту переменную можно было бы передать всем им или это мог бы быть член класса.


1
Как используется это значение? Это постоянно? Это изменится? Подлежит ли это изменениям между компиляциями?
Одед

Когда все автоматически определяется как одно и то же, легче думать, что это не имеет значения. Что если у вас есть функция, которая нуждается в скорректированном значении (x), например, x-1?
Джеффо

Ответы:


15

Если значение является свойством класса, сохраните его в классе, в противном случае оставьте его снаружи. Вы не разрабатываете свои методы класса - во-первых, вы сначала проектируете его свойства. Если вы не задумывались над тем, чтобы поместить это свойство в класс, то, вероятно, для этого есть причина.

Худшее, что вы можете сделать с точки зрения масштабируемости, это изменить ваш код для удобства. Рано или поздно вы обнаружите, что ваш код раздут и дублирован. Однако я должен признать, что иногда нарушаю это правило ... Удобство просто чертовски привлекательно.


1
Я согласен - оригинальный дизайн / назначение класса должно сказать вам, должна ли это быть переменная-член или аргумент. Также стоит подумать о зависимости инжекционного угла.
Мартейн Вербург

14

Если вам на самом деле не нужно хранить состояние между вызовами (и, по-видимому, нет, или вы не задали бы вопрос), я бы предпочел, чтобы значение было аргументом, а не переменной-членом, потому что быстрый взгляд в сигнатуре метода указывается, что он использует аргумент, хотя немного сложнее сразу сказать, какие переменные-члены используются методом. Также не всегда быстро определить, для чего нужны закрытые переменные-члены.

Поэтому обычно я не соглашусь с тем, что код, использующий переменные-члены, заметно чище, но если сигнатуры методов выходят из-под контроля, я могу сделать исключение. Это стоящий вопрос, но в любом случае проект не будет зависеть от проекта.


10

Спасибо за вопрос, я хотел спросить и это тоже.

Когда я думал об этом, есть некоторые преимущества в том, чтобы передать это в качестве аргумента

  • легче тестировать -> легче поддерживать (относится к последнему пункту)
  • не имеет побочных эффектов
  • это легче понять

Я ясно вижу вашу точку зрения, например: один из них - это анализ документа Excel (например, с использованием библиотеки POI), и вместо передачи экземпляра строки каждому методу, который должен работать с этой строкой, у автора есть переменная-член, currentRowи он работает с ней.

Я бы сказал, что для этого анти-паттерна должно быть название, не так ли? (не указан здесь )


Какой анти-паттерн вы имеете в виду?
Вахид Гадири

Короче говоря, чтобы иметь переменную-член просто для того, чтобы разделить параметр между двумя (или более) вызовами функций ...
Бетлиста

1

Возможно, вам следует извлечь новый класс, содержащий все методы, разделяющие это значение. Конечно, метод высшего уровня будет общедоступным в новом классе. Может быть полезно выставить этот метод для тестирования.

Если у вас есть два или более временных, которые всегда передаются вместе, то вы почти наверняка должны извлечь новый класс.


1

Предпочитают ли люди определять это как переменную-член для класса или передавать его в качестве аргумента каждому из методов - и почему?

Если я понимаю, что вы спрашиваете: методы в классе по определению привязаны к деталям реализации, поэтому у меня не было бы никаких сомнений относительно использования любого члена напрямую из любого метода.

С одной стороны, я мог видеть аргумент, что сокращение состояния (то есть переменных-членов) в классе, как правило, хорошо ...

В объявлении private static finalконстант нет ничего плохого . Компилятор сможет использовать это значение при рассмотрении некоторых оптимизаций и, будучи константами, они на самом деле не добавляют состояние в класс.

хотя, если одно и то же значение многократно используется в методах класса ...

Возможность ссылаться на него символически (например, BLRFL_DURATION) и не добавлять дополнительные аргументы в ваши методы сделает ваш код более читабельным и, следовательно, более понятным.


0

если значение не изменяется, оно по определению является константой и должно быть заключено в класс. В таком случае считается, что он не влияет на состояние объекта. Я не знаю ваш случай, но я думаю о чем-то вроде PI в тригонометрии. Если вы попытаетесь передать аргумент такой константы, вы можете подвергнуть результат ошибке, если клиент передает неправильное значение или значение не с той точностью, которую ожидают методы.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.