Бизнес-логика в конструкторах?
От: Airat Burganov Россия http://www.burganov.com
Дата: 16.05.07 19:13
Оценка:
Небольшой спор у меня возник с товарищем. Вот предположим мы делаем класс соединяющийся с Rapidshare по вебу и забирающий оттуда файлы (реальная задача другая, это просто пример).

Схема использования класса следующая
Rapidshare rp = new Rapidsharel(login, password, other parameters....);
rp.login();
Download dld = rp.downloadFile(url);

замечу, что всякий раз после создания класса Rapidshare необходимо вызывать функцию login() (которая логиниться к платному рапидшарному аку и устанавливает нужные кукисы), а потом уже можно непосредственно скачивать различные файлы
Мой товарищ утверждает, что вызов функции login() можно и нужно поместить в конструктор и соответственно работать следующим образом:
Rapidshare rp = new Rapidsharel(login, password, other parameters....);
Download dld = rp.downloadFile(url);

Я категорически с этим не согласен, но внятно аргументировать свою позицию не могу, может вы поможете?
Если же не прав я, то тоже объясните почему.
Re: Бизнес-логика в конструкторах?
От: Blazkowicz Россия  
Дата: 17.05.07 05:34
Оценка: 3 (2)
Здравствуйте, Airat Burganov, Вы писали:

Rapidshare rp = new Rapidsharel(login, password, other parameters....);
rp.login();
Download dld = rp.downloadFile(url);

В чем глубинный смысл отделять логин и пароль от метода? Я бы предпочел

Rapidshare rp = new Rapidsharel(other parameters....);
rp.login(login, password);

Хотя конечно зависит от задач.

Rapidshare rp = new Rapidsharel(login, password, other parameters....);
Download dld = rp.downloadFile(url);

AB>Я категорически с этим не согласен, но внятно аргументировать свою позицию не могу, может вы поможете?
AB>Если же не прав я, то тоже объясните почему.
ИМХО, ты прав. В схеме предложеной твоим коллегой нельзя сделать отложеный логин. Тоесть к примеру можно персистить объекты Rapidshare в базу. А потом доставая их логинить нужные. Если же логин поместить в конструктор, то все объекты в системе будут залогинеными. А вдруг между созданием инстанса и необходимостью скачать файл пройдет много времени и сессия умрет?

Немного подлумав вообще можно прийти к выводу что логин надо поместить в downloadFile.

Ну, и смотреть конечно же надо на приложение. Когда это единоразовая тулза, то можно как угодно лишь бы работало. А если в перспективе планируется использовать этот код в большом проекте, то конечно же стоит обдумать варианты
Re: Бизнес-логика в конструкторах?
От: aefimov Россия
Дата: 17.05.07 07:19
Оценка: 2 (2)
Здравствуйте, Airat Burganov, Вы писали:

AB>Я категорически с этим не согласен, но внятно аргументировать свою позицию не могу, может вы поможете?

AB>Если же не прав я, то тоже объясните почему.

Коллега прав в твоем случае, помойму. Раз конструктор принимает логи и пароль, он должен логиниться сам.
Другое дело, какую смысловую нагрузку несет класс. Например, если это коннектор, то почему бы и не логинить его в конструкторе, а если это фектори/билдер то, понятное дело, параметры логина/пароля надо убирать из конструктора, делать RapidshareSession и метод login(String l, String p) : RapidshareSession. После чего передавать этот сешен во всякие downloadFile.
Re: Бизнес-логика в конструкторах?
От: dshe  
Дата: 17.05.07 09:09
Оценка: 2 (1) +1
Здравствуйте, Airat Burganov, Вы писали:

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


AB>замечу, что всякий раз после создания класса Rapidshare необходимо вызывать функцию login() (которая логиниться к платному рапидшарному аку и устанавливает нужные кукисы), а потом уже можно непосредственно скачивать различные файлы

AB>Мой товарищ утверждает, что вызов функции login() можно и нужно поместить в конструктор и соответственно работать следующим образом:
AB>Я категорически с этим не согласен, но внятно аргументировать свою позицию не могу, может вы поможете?
AB>Если же не прав я, то тоже объясните почему.

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

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

А чтобы не писать постоянно
Rapidshare rp = new Rapidsharel(login, password, other parameters....);
rp.login();

можно эти два шага объединить в фабричном методе и пользоваться везде именно им.
--
Дмитро
Re: Бизнес-логика в конструкторах?
От: Дмитрий В  
Дата: 17.05.07 09:16
Оценка:
Если коллега настаивает, можно сделать ленивую инициализацию.
Пусть в методе downloadFile необходима какая нибудь переменная, которая инициализируется в методе login. Тогда к ней можно обращаться с помощью геттера:

private Connection connection;

private Connection getConnection() {
  if(connection==null) {
   // производим логин, инициализируем Connection
  }
  return connection;
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.