Tell, don't ask

fixxxer

К.О.
Партнер клуба
Да с ифом то как раз все сразу понятно когда он есть :)

Вопрос как предсказать где он появится не в тему.
 

whirlwind

TDD infected, paranoid
Ну вот если предположить что диспатчер это транспорт, а юзер это модель, то ни там, ни там формирование масяги с ифами будет не в тему.

ЗЫ. Самый правильный пример тут имхо у триумвирата. Тока если вспомнить рекомендации korchasa про stateless service, то я бы сделал один вызов с передачей инстанса юзера и сообщения.
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Можно я попробую вставить свой «правильный вариант» Tell, Don't ask, а знающие люди скажут, в чем я могу быть неправ ?
PHP:
$message = Message_Composer(new View->get('mail.message.template.eml'), $user);
$status = MessageDispatcher->send($message, $user);
 

whirlwind

TDD infected, paranoid
Можно я попробую вставить свой «правильный вариант» Tell, Don't ask, а знающие люди скажут, в чем я могу быть неправ ?
Диспатчер это транспорт? То есть smtp, mail(), etc ? Если да, то будешь дублировать в каждой реализации? Если не транспорт, то не слишком ли жирно целый класс тока для того что бы email подставить в сообщение из user? Тогда уж MessageDispatcher->sendТакоеТоСообщение($user)
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Ну, я просто по умолчанию принял, что как бы чуть выше написано
PHP:
$MessageDispatcher->setTransport(new SmtpTransport($settings));
а что такое «целый класс!» как будто класс это такая очень тяжелая вещь, которую не надо использовать лишний раз.
Класс (грубо)— это набор функций и данных, объединенных общей предметной областью. И если есть сущность «отправщик почты» — почему бы не иметь для этого класс, даже если там будет вообще одно свойство и один метод, для начала?
Это создаст здоровую абстракцию, и позволит легко его расширять, не ломая существующей функциональности, и не имея никаких негативных последствий.
 

whirlwind

TDD infected, paranoid
Видишь ли, каждый лишний класс аукается при инстанцировании. Тут уже затрагивали вопрос IoC, DI и прочее - это как раз оно самое. Для меня инстанцирование по месту вещь неприемлимая в принципе - она просто не дает тестировать. Да и mutable я не очень жалую. Все это есть у тебя в одной строчке. И здоровая абстракция у тебя класс, а у меня интерфейс. Так что я полагаю на примере сферических коней мы с тобой можем обсуждать бесконечно.

Что касается примера, то зависит опять же от того, где этот код. Если это в сервисном слое выполняется, то в принципе нормальный вариант. Предположим, что MessageDispatcher->send легаси и оно не работает по принципу T,DA. В этом случае сервисный слой будет анализировать результат транспорта и в случае ошибки возбуждать свое исключение, независимо от реализации транспорта. Вполне нормально. Но если это в контроллере такое, то сразу возникает масса вопросов, которые я частично выше описывал.
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Видишь ли, каждый лишний класс аукается при инстанцировании. Тут уже затрагивали вопрос IoC, DI и прочее - это как раз оно самое. Для меня инстанцирование по месту вещь неприемлимая в принципе - она просто не дает тестировать.
У вас просто неправильный мед™. ;)
Как подсказывает ВикиПедия — «[In unit testing,] a unit is the smallest testable part of an application.»
Понимаешь, одинокий класс/объект не можно и не нужно тестировать — как ты будешь тестировать тот же почтовый транспорт, который бессмыслен в отрыве от отправщика почты, который использует этот транспорт?
Что касается примера, то зависит опять же от того, где этот код. Если это в сервисном слое выполняется, то в принципе нормальный вариант. ... Но если это в контроллере такое, то сразу возникает масса вопросов, которые я частично выше описывал.
Это зависит от того лишь, на какой слой приходится бизнес-логика принятия решений, и от уровня влияния этих решений, отправка почты может быть с таким же успехом и в модели, (если результат этого действия важен только для модели, например, поставить отметку об отправке письма), но если ты на основании этого действия собираешься изменить текущий контроллер, например, сделав перенаправление на другую страницу — это нормально ловить это исключение в контроллере.

Для меня Tell, Don't ask заключается в простом принципе — никакой объект для выполнения действия не должен запрашивать никакие данные извне, а пользоваться только теми данными, которые ему передал объект стоящий выше него в иерархии приложения. Соответственно, обязанность «старшего» объекта — передать ему нужные данные.

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

Активист

Активист
Команда форума
QBasic! Алах Акбар!

ЗЫ: может ветку сделать? Так и назовем, "Holy War ООП"
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Активист, ты о чем? Нормальная, взрослая дискуссия.
 

whirlwind

TDD infected, paranoid
Понимаешь, одинокий класс/объект не можно и не нужно тестировать — как ты будешь тестировать тот же почтовый транспорт, который бессмыслен в отрыве от отправщика почты, который использует этот транспорт?
Вот давай тока не будем мне про это :) Почтовый транспорт реализует интерфейс. Мне не нужно тестировать 100500 раз почтовый транспорт в тех классах, где он используется. Для этого придумали моки.

легаси - legacy

PS. Больше упор делайте на пользовательский код (use cases), и все встанет на свои места ;)
 

флоппик

promotor fidei
Команда форума
Партнер клуба
use case — по-русски ближе всего будет «пример использования» подразумевая некоторый минимальный код, необходимый для того, что бы однозначно отразить поставленную задачу.
mock, mock object — по-русски, объект-«заглушка», объект, не реализующий реальный функционал, но позволяющий произвести тест для другого кода, который имеет зависимость от этого объекта, который эмулируется.
Что такое legacy в этом контексте, я не знаю, и википедия тоже не подсказала ничего. Возможно, это ускоспециализированный, либо самовведенный термин.

Возможно whirlwind ответит на этот вопрос. ;)
 

AmdY

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

p.s. у нас здесь энтузиасты перевели agile manifesto на родной, получилось у них "Маніфест Шпаркага праграмавання", если по русски - "манифест быстрого программирования", думаю разницу объяснять не надо.
http://agilemanifesto.org/iso/by/
мне нравится
Хацелася б падзякаваць праекту Беларуская IT-тэрміналогія ў межах якога прафесійныя лінгвісты, праграмісты і проста добрыя людзі ствараюць нацыянальную IT-тэрміналогiю.
 

whirlwind

TDD infected, paranoid
ыыы. В гугле по запросу "что такое мок" на 1й странице по теме тока agiledev и древняя статья на моем сайте. Неужели никто ничего нового с тех пор не написал по-русски?! :confused:
 
Сверху