ООП: Передача объекта против передачи атрибутов в метод - PullRequest
4 голосов
/ 21 февраля 2011

С точки зрения чистого дизайна, что предпочтительнее?

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

Внутри класса A ...

B.doStuff(this);

2) Вместо этого передайте атрибуты объекта и либо присвойте возвращаемое значение атрибутам, либо передайте по ссылке.

Внутри класса A ...

this.var1 = B.doStuff(this.var1);

Недостатком первого метода является неоднозначность, неясно, что B изменяет в A. Недостатком второго метода является то, что если атрибуты не передаются по ссылке / указателям, то массивдолжен быть возвращен, а также будет представлять собой более длинный вызов функции, если в итоге вы передадите много атрибутов.Я предполагаю, что правильный выбор зависит от ситуации, но есть ли другие преимущества / недостатки, которые кто-либо еще может придумать, прежде чем я приму решение?

РЕДАКТИРОВАТЬ: В связи с тем,что во второй класс будет передано большое количество атрибутов (я делегирую ему определенные задачи), я думаю, в этом случае это оправдывает использование первого метода.Другим недостатком, с которым я столкнулся, было то, что класс B может получать доступ только к общедоступным атрибутам и методам в классе A, тогда как второй метод позволял классу B манипулировать закрытыми атрибутами, которые класс A может не захотеть открывать для публики.Но еще раз, использование второго метода является более распространенным и, безусловно, более предпочтительным в случаях, когда будут доступны только несколько переменных.

Ответы [ 3 ]

1 голос
/ 21 февраля 2011

Я бы предпочел второй подход, тогда класс B не имел бы никакой зависимости от класса A.

1 голос
/ 21 февраля 2011

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

Я думаю, что этот вопрос сводится к тому, передавать ли значение по ссылке или по значению.

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

Например, когда вы берете ссылку на графические объекты в событии рисования Forms (в C #), известно, что манипулирование будет выполняться на переданной ссылке на объект (но, конечно, это зависит от ваших требований иРеализация).

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

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

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

1 голос
/ 21 февраля 2011

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

public void addChild(Child child) {
    children.add(child);
    child.setParent(this);
}

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

...