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

Я заметил, что даже когда я уважаю принцип единой ответственности OOD, иногда классы все еще растут. Иногда доступ к переменным-членам непосредственно в методах кажется похожим на глобальное состояние, и в текущей области существует много материала. Просто взглянув на метод, который в настоящее время работает, теперь невозможно определить, откуда происходят невидимые переменные, доступные в текущей области.

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

Является ли эта плохая практика?

edit: example:

class AddNumbers {
public:
    int a, b;
    // ...
    int addNumbers {
        // I could have called this without arguments like this:
        // return internalAlgorithmAddNumbers();
        // because the data needed to compute the result is in members.
        return internalAlgorithmAddNumbers(a,b);
    }

private:
    int internalAlgorithmAddNumbers(int sum1, int sum2) { return sum1+sum2; }
};

Ответ 1

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

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

Ответ 2

Да, определенно плохая практика. Передача переменной-члена в функцию-член не имеет никакого смысла, с моей точки зрения. Он имеет несколько недостатков:

  • Уменьшить читаемость кода.
  • Затраты в связи с производительностью для копирования параметра в стеке

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

EDIT:

Отвечайте на свой комментарий. Если функция может выполнять свое задание только с использованием нескольких параметров, переданных явно, и не нуждается в каком-либо внутреннем состоянии, то, вероятно, нет причин объявлять, что она имеет функцию-член. Используйте простой вызов функции C-стиля и передайте ему параметры.

Ответ 3

Я понимаю проблему, мне пришлось поддерживать большие классы в коде, который я изначально не написал. В С++ у нас есть ключевое слово const, чтобы помочь определить методы, которые не меняют состояние:

void methodA() const;

Использование этого помогает поддерживать работоспособность, потому что мы можем видеть, может ли метод изменять состояние объекта.

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

this->mMemberVariable = this->someMethod();

Вместо

void someMethod()
{
   this->mMemberVariable = 1; // change object state but do so in non transparent way
}

На протяжении многих лет я обнаружил, что это упрощает ведение кода.