когда передавать параметр и когда использовать переменную экземпляра - PullRequest
78 голосов
/ 06 декабря 2008

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

Я обычно предпочитаю переменные экземпляра, хранящиеся в списке в конце класса. Но по мере того, как мои программы становятся все более и более сложными, этот список становится все длиннее и длиннее ... Я полагаю, что если что-то проходит достаточно часто, это должно быть видно всем мальчикам и девочкам, которые в этом нуждаются, но потом я начинаю удивляться: «Почему бы просто не обнародовать все! Тогда больше не нужно будет ничего передавать!»

Ответы [ 5 ]

46 голосов
/ 06 декабря 2008

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

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

  • Локальные переменные используются в рамках методов, чтобы помочь им завершить свою работу. Обычно метод должен иметь цель получить некоторые данные, вернуть некоторые данные и / или обработать / запустить алгоритм на некоторых данных. Иногда это помогает думать о локальных переменных как о способах помочь методу пройти от начала до конца.

  • Область действия переменной экземпляра предназначена не только для безопасности, но и для инкапсуляции. Не думайте, что "цель должна состоять в том, чтобы все переменные были приватными". В случаях наследования создание переменных как защищенных обычно является хорошей альтернативой. Вместо того, чтобы помечать все данные экземпляра как общедоступные, вы создаете методы получения / установки для тех, кому необходимо получить доступ к внешнему миру. Не делайте их доступными - только те, которые вам нужны. Это будет происходить на протяжении всего жизненного цикла разработки - с самого начала трудно догадаться.

Когда дело доходит до передачи данных по классу, трудно сказать, что вы делаете, это хорошая практика, не видя некоторого кода. Иногда работать напрямую с данными экземпляра нормально; в других случаях это не так. По моему мнению, это то, что приходит с опытом - вы будете развивать некоторую интуицию по мере улучшения ваших навыков объектно-ориентированного мышления.

38 голосов
/ 06 декабря 2008

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

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

15 голосов
/ 06 декабря 2008

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

Вот пример:

myCircle = myDrawing.drawCircle(center, radius);

Теперь давайте представим, что класс myDrawing использует 15 вспомогательных функций для создания объекта myCircle, и каждой из этих функций потребуется центр и радиус. Они по-прежнему не должны устанавливаться как переменные экземпляра класса myDrawing. Потому что они никогда не понадобятся снова.

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

myCircle.move(newCenter);
myCircle.resize(newRadius);

Чтобы объект myCircle знал, каковы его радиус и центр, когда эти новые вызовы выполняются, они должны храниться как переменные экземпляра, а не просто передаваться в функции, которые в них нуждаются.

Таким образом, переменные экземпляра - это способ сохранить «состояние» объекта. Если переменная не обязана знать состояние объекта, она не должна быть переменной экземпляра.

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

4 голосов
/ 06 декабря 2008

ИМХО:

Если переменная является частью состояния экземпляра, то это должна быть переменная экземпляра - переменная экземпляра класса HAS-A.

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

Надеюсь, это поможет

3 голосов
/ 06 декабря 2008

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

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

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

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

Это сводится к здравому смыслу. Точно подумайте, где и почему вы объявляете каждую новую переменную, какой должна быть ее функция, и оттуда принимаете решение относительно того, в какой области она должна жить.

...