Сколько аргументов - разумное число, большие объекты против атомарных аргументов.OOP - PullRequest
4 голосов
/ 08 января 2011

Я - разработчик новинок, и я хотел бы узнать из вашего опыта, как лучше подходить, когда ваши методы построения класса, и если нет лучшего подхода, как сбалансировать ваши решения в отношении:

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

Что лучше для кода, который будет развиваться?а как вы думаете, есть ли разумное количество аргументов?

Ответы [ 2 ]

1 голос
/ 08 января 2011

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

Почему?

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

Обратите внимание, что это не обязательноКЛАСС как таковой, в смысле наличия методов.Просто контейнер для хранения (или гетерогенная карта / словарь, или для безопасности типов, структура в языках типа C, которые его поддерживают).

Пример (я буду использовать псевдокод, не стесняйтесь, какой язык (языки))он основан на:


Сначала давайте рассмотрим старый и новый код с использованием списков аргументов

Старый код:

function f1(arg1, arg2, arg3, arg4, arg5) {
    res = f2(arg1, arg2, arg3, arg4);
}
function f2(arg1, arg2, arg3, arg4) {
    res = f3(arg1, arg2, arg4);
}
function f3(arg1, arg2, arg4) {
    res = f4(arg1, arg4);
}
function f4(arg1, arg4) {
    return arg1 + arg4;
}

Новый код (необходимо добавить arg6в f4 ()):

function f1(arg1, arg2, arg3, arg4, arg5, arg6) {       // changed line
    res = f2(arg1, arg2, arg3, arg4, arg6);             // changed line
}
function f2(arg1, arg2, arg3, arg4, arg6) {             // changed line
    res = f3(arg1, arg2, arg4, arg6);                   // changed line
}
function f3(arg1, arg2, arg4, arg6) {                   // changed line
    res = f4(arg1, arg4, arg6);                         // changed line
}
function f4(arg1, arg4, arg6) {                         // changed line
    return arg1 + arg4 + arg6;                          // changed line
}

Как видите, для вложенных вызовов 4-го уровня мы изменили ВСЕ 4 функции, с объемом не менее 2 строк на функцию.YIKES.Таким образом, для вложенных вызовов с 10 уровнями добавление 1 параметра приводит к изменению всех функций TEN и 20 строк.


Теперь, пример того же изменения, за исключением того, что список arg теперь является объектом (или, для динамическогоязыки, гетерогенная карта подойдет :)

class args_class {
    public: 
        int arg1, arg2, arg3, arg4, arg5;
    }
}
args_class arg_object;

function f1(arg_object) {       
    res = f2(arg_object);             
}
function f2(arg_object) {       
    res = f3(arg_object);                   
}
function f3(arg_object) {                   
    res = f4(arg_object);                         
}
function f4(arg_object) {                         
    return arg_object.arg1 + arg_object.arg4;                          
}

И что мы можем изменить, чтобы добавить arg6?

class args_class {
    public: 
        int arg1, arg2, arg3, arg4, arg5, arg6;                 // line changed
    }
}
// f1..f3 are unchanged
function f4(arg_object) {                         
    return arg_object.arg1 + arg_object.arg4 + arg_object.arg6; // line changed
}

Вот и все.Для 4-уровневых вложенных методов или для 10-уровневых вложенных методов вы ТОЛЬКО меняете две строки на две.

Какую из них выполнять меньше работы?

0 голосов
/ 08 января 2011

Я думаю, что все зависит от контекста самих параметров функции. Если вы полагаетесь на элементы некоторой вещи , то я бы передал ссылку на эту некоторую вещь в качестве параметра (будь то ссылка / указатель на интерфейс этого объекта или ссылка / указатель на само определение объекта является подробностью реализации).

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

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

...