Каковы лучшие способы создать метод, который принимает много аргументов?(10+?) - PullRequest
5 голосов
/ 30 марта 2012

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

Есть ли другой / более предпочтительный способ сделать это (другими словами, как лучше это исправить и объяснить, почему)?

public long Save (
    String today, 
    String name, 
    String desc, 
    int ID, 
    String otherNm, 
    DateTime dt, 
    int status, 
    String periodID, 
    String otherDt, 
    String submittedDt
)

игнорировать мои плохие имена переменных - это примеры

Ответы [ 5 ]

5 голосов
/ 30 марта 2012

Это сильно зависит от языка.

В языке без проверки типов во время компиляции (например, python, javascript и т. Д.) Вы должны использовать аргументы ключевого слова (обычно в python: youможет получить к ним доступ как словарь, переданный в качестве аргумента) или объекты / словари , которые вы вручную передаете в качестве аргументов (часто встречается в javascript).

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

2 голосов
/ 30 марта 2012

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

1 голос
/ 30 марта 2012

Использование объектов.

class User { ... }
User user = ...
Save(user);

Это решение обеспечивает простой способ добавления новых параметров.

1 голос
/ 30 марта 2012

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

0 голосов
/ 31 марта 2012

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

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

  1. Вещь : сущность с состоянием, обычно неизменяемая (т.е. только получатели)
  2. ThingBuilder : фабричный класс, создает сущность Thing и устанавливает ее значения.
  3. ThingDAO : необязательно для использования шаблона Builder, но отвечает на ваш вопрос.

Взаимодействие

/* 
ThingBuilder is a static inner class of Thing, where each of its 
"set" method calls returns the ThingBuilder instance being worked with
while the final "build()" call returns the instantiated Thing instance.
*/
Thing thing = Thing.createBuilder().
                .setToday("2012/04/01")
                .setName("Example")
                // ...etc...
                .build();

// the Thing instance as get methods for each property
thing.getName();

// get your reference to thingDAO however it's done
thingDAO.save(thing);

В результате вы получаете именованные аргументы и неизменный экземпляр.

...