В конкретном случае с турникетом и оплатой — надо копить стейт, как я написал прямо в тексте, чтобы можно было бросить 10 жетонов, а потом пройти вдесятером.
Так это же и есть инкапсуляция.
Вот у вас есть Турникет.
У него есть два состояния - Открыт, Закрыт.
И события - Жетон, Карта, Пассажир.
Есть внутренние данные (инкапсулированные) - Кол-во проходов.
Работает просто:
Открыт + Жетон или Карта -> Открыт (кол-во проходов +1)
Закрыт + Жетон или Карта -> Открыт (кол-во проходов +1)
Открыт + Пассажир -> Открыт или Закрыт (в зависимоти от врутренних/инкапсулированных данных)
Закрыт + Пассажир -> Исключение!
Вот и получается, что наружу "кол-во проходов" не торчит, т.е. инкапсулированно.
При этом вролне нормально иметь метод displayInfo где мы можем показать сколько проходов отсталось. Или добавить метод reset если у нас бывают какие-то ситуации, что турникет заглючил и его нужно перезагрузить.
Это откуда вы такое взяли? Может он перестал быть крайне рентабельным и стал очень рентабельным, но до нерентабельности там еще огого сколько
Последние лет 10 я работал в стартапах. Так вот, они все проедали деньги инвесторов (даже так-называемые "единороги"). У этих компаний были оценки в миллиарды, они показывали рост "клюшкой", но ни одна не могла себя обеспечивать без инвестиций.
Вся "рентабельность" была очень простой - берем бесплатные деньги, вкладываем, показываем перспективу, продаем.
Если известное решение было неудобно, делали адаптер, к примеру MindboxValidation на базе FluentValidation — под капотом была технология, с которой все на рынке умели работать, а снаружи — привычный API.
Интересно было-бы пример посмотреть. Особенно - что было "неудобным" и как выглядит "привычный API".
Мне интересно сколько прособеседовали, чтобы хоть одного нанять. Я когда работал в компании которая жила "на свои", а не на инвестиции у нас тоже была статистика найма 1-2 на 100. Это как раз нормально когда у вас нет показателя найма и совсем небольшая текучка.
То, что вы описываете называется капитализм. Есть теория, что капитализма больше нет и мы в чем-то новом. Один товарищь называет это - техно-феодализм.
Я не говорю, что это правда, но по крайней мере объясняет почему это так работает.
Вы говорите о том, что написание тестов — это дополнинельная работа, которая требует инвестиций. Я тоже так раньше думал, но теперь считаю, что тесты уменьшают время разработки, да еще и повышают качество продукта.
И я с вами абсолютно согласен, что это ответственность работодателя инвестировать в культуру тестирования. И это не время на написание тестов, а обучение, встраивание в процесс доставки, в оценку качества продукта, анализ и т.д.
Объяснить и внедрить это, действительно требует коллосальных усилий, особенно если работодатель не понимает или не видит смысла.
Для маленьких проектов посмотрите в сторону Outside In тестов. Т.е. пишите только очень высокоуревнивые тесты, они быстро пишутся и покрывают очень большую площать кода.
Последние лет 5 я пишу только такие тесты и мне кажется, что их достаточно. Вот пример тестов которые пишу:
Суть Outside In тестов, то вы ничего не мокаете и просто дергаете API и потом проверяете то, что должно произойти, т.е поведение системы.
Получается, что тут не важно как все реализовано, какие методы вызывались. Просто проверяете: если я отправил вот такой JSON на такой URL, то мне пришел ответ 200 и данные которые я ожидаю.
"Да, конечно делай, если это не увеличит время выполнения задачи."… И зачем оно мне тогда?
Видимо вы еще руку не набили на написание тестов. Я вот даже не знаю как код начать писать если нет теста. Я не говорю, что TDD это маст хэв, по мне это просто механический навык, как печать вслепую, как шорткаты.
С on-call, по крайней мере где я работал, проблем небыло, правда есть четкие правила как время на on-call компенсируется (бывают выходные, бывают премии и тд).
Поработать в нерабочие часы тоже могут, но это исключительно личная инициатива, а просить поработать вне графика… тут тебя просто не поймут, нет такого. Хм… получается это и правда табу.
Хотя я всего в 3х компаниях работал, так что все мои рассуждения — это довольно маленькая выборка.
Вон в Испании, 35 часов в неделю, и куча проблем, если надо кого-то вызвать на овертайм или вне рабочего времени.
Не, в Испанском IT работают по 40 часов в неделю и увольняют одним днем.
За 5 лет в Испании я еще не встречал компанию которая работает по сокращенной неделе.
Почему вы считаете, что по фэн-шую в TDD должны быть именно модульные тесты?
Я понимаю, что Дядя Боб рассказывает, что TDD это когда вы пишете сначала очень простой тест (за минутку), потом супер простоую имплементацию (опять за минутку) чтобы тест стал зеленым. И повторяете такие же маленькие итерации многократно, потихоньку усложняя тесты и соответственно имплементацию.
Для обучения TDD в домашних условиях — это норм подход, но практиковать его на реальном проекте — боль, т.к. при изменениях слишком много тестов нужно будет постоянно переписывать.
Outside in подход такой — пишете один высокоуровневый тест, который конечно-же не проходит, т.к. нет имплементации, а потом пишете-пишете-пишете имплементацию (хоть час, хоть день, сколько нужно) пока этот тест не станет зеленым.
Получается такое — разработка через тестирование пользовательских историй.
По моему мнению TDD — это когда сначала тест, потом код. И все, больше нет никаких дополнительный условий.
И с другой стороны, почему мой тест не модульный? Я просто тестирую сервис (вместе с БД, очередью, кэшем и т.д) как один независимый модуль.
Ведь что угодно может быть модулем — функция, класс, библиотека, сервис, множество сервисов как единая система.
Не до конца я понял вашу идею. Как-то очень запутанно получилось.
Я бы сделак что-то вроде:
# инкапсулируем логику работы с API в отдельный класс
class Api:
def fetch_data(): ...
def save_data(data:): ...
# это по сути основная бизнес логика приложения
def update_data(data):
return [fileld.upper() for field in data]
# ну а это наш контроллер
def do_work():
api = Api()
data = api.fetch_data()
updated_data = update_data(data)
api.save(updated_data)
Тестировал бы используя подход outside-in, т.е. мокировал бы библиотеку requests и проверял бы, что мы отправляем то, что API ожидает.
Ну и если `data` это достаточно сложный объект, мжно добавиь `dataclass` и дополнительно сериализацию/десериализацию, в таком случае из `Api` будем возвращать готовые объекты, а не словарь, соответственно можно будет в этот класс добавить функции манипуляции с объектом.
Так это же и есть инкапсуляция.
Вот у вас есть Турникет.
У него есть два состояния - Открыт, Закрыт.
И события - Жетон, Карта, Пассажир.
Есть внутренние данные (инкапсулированные) - Кол-во проходов.
Работает просто:
Открыт + Жетон или Карта -> Открыт (кол-во проходов +1)
Закрыт + Жетон или Карта -> Открыт (кол-во проходов +1)
Открыт + Пассажир -> Открыт или Закрыт (в зависимоти от врутренних/инкапсулированных данных)
Закрыт + Пассажир -> Исключение!
Вот и получается, что наружу "кол-во проходов" не торчит, т.е. инкапсулированно.
При этом вролне нормально иметь метод
displayInfo
где мы можем показать сколько проходов отсталось. Или добавить методreset
если у нас бывают какие-то ситуации, что турникет заглючил и его нужно перезагрузить.Последние лет 10 я работал в стартапах. Так вот, они все проедали деньги инвесторов (даже так-называемые "единороги"). У этих компаний были оценки в миллиарды, они показывали рост "клюшкой", но ни одна не могла себя обеспечивать без инвестиций.
Вся "рентабельность" была очень простой - берем бесплатные деньги, вкладываем, показываем перспективу, продаем.
Интересно было-бы пример посмотреть. Особенно - что было "неудобным" и как выглядит "привычный API".
Насколько я понимаю у нас ресурсов на земле не сильно много, учитывая текущий уровень потребления, врятли ресурсов на 1000 лет хватит.
Мне интересно сколько прособеседовали, чтобы хоть одного нанять. Я когда работал в компании которая жила "на свои", а не на инвестиции у нас тоже была статистика найма 1-2 на 100. Это как раз нормально когда у вас нет показателя найма и совсем небольшая текучка.
То, что вы описываете называется капитализм. Есть теория, что капитализма больше нет и мы в чем-то новом. Один товарищь называет это - техно-феодализм.
Я не говорю, что это правда, но по крайней мере объясняет почему это так работает.
Вы говорите о том, что написание тестов — это дополнинельная работа, которая требует инвестиций. Я тоже так раньше думал, но теперь считаю, что тесты уменьшают время разработки, да еще и повышают качество продукта.
И я с вами абсолютно согласен, что это ответственность работодателя инвестировать в культуру тестирования. И это не время на написание тестов, а обучение, встраивание в процесс доставки, в оценку качества продукта, анализ и т.д.
Объяснить и внедрить это, действительно требует коллосальных усилий, особенно если работодатель не понимает или не видит смысла.
Для маленьких проектов посмотрите в сторону Outside In тестов. Т.е. пишите только очень высокоуревнивые тесты, они быстро пишутся и покрывают очень большую площать кода.
Последние лет 5 я пишу только такие тесты и мне кажется, что их достаточно. Вот пример тестов которые пишу:
Суть Outside In тестов, то вы ничего не мокаете и просто дергаете API и потом проверяете то, что должно произойти, т.е поведение системы.
Получается, что тут не важно как все реализовано, какие методы вызывались. Просто проверяете: если я отправил вот такой JSON на такой URL, то мне пришел ответ 200 и данные которые я ожидаю.
Видимо вы еще руку не набили на написание тестов. Я вот даже не знаю как код начать писать если нет теста. Я не говорю, что TDD это маст хэв, по мне это просто механический навык, как печать вслепую, как шорткаты.
А могли бы вы рассказать как пример с if-else нарушает SOLID и какой именно принцип?
С on-call, по крайней мере где я работал, проблем небыло, правда есть четкие правила как время на on-call компенсируется (бывают выходные, бывают премии и тд).
Поработать в нерабочие часы тоже могут, но это исключительно личная инициатива, а просить поработать вне графика… тут тебя просто не поймут, нет такого. Хм… получается это и правда табу.
Хотя я всего в 3х компаниях работал, так что все мои рассуждения — это довольно маленькая выборка.
Не, в Испанском IT работают по 40 часов в неделю и увольняют одним днем.
За 5 лет в Испании я еще не встречал компанию которая работает по сокращенной неделе.
Я понимаю, что Дядя Боб рассказывает, что TDD это когда вы пишете сначала очень простой тест (за минутку), потом супер простоую имплементацию (опять за минутку) чтобы тест стал зеленым. И повторяете такие же маленькие итерации многократно, потихоньку усложняя тесты и соответственно имплементацию.
Для обучения TDD в домашних условиях — это норм подход, но практиковать его на реальном проекте — боль, т.к. при изменениях слишком много тестов нужно будет постоянно переписывать.
Outside in подход такой — пишете один высокоуровневый тест, который конечно-же не проходит, т.к. нет имплементации, а потом пишете-пишете-пишете имплементацию (хоть час, хоть день, сколько нужно) пока этот тест не станет зеленым.
Получается такое — разработка через тестирование пользовательских историй.
По моему мнению TDD — это когда сначала тест, потом код. И все, больше нет никаких дополнительный условий.
И с другой стороны, почему мой тест не модульный? Я просто тестирую сервис (вместе с БД, очередью, кэшем и т.д) как один независимый модуль.
Ведь что угодно может быть модулем — функция, класс, библиотека, сервис, множество сервисов как единая система.
Периодически слышу такое-же мнение, но не могу понять как люди пришли к этому заключению?
Вот я считаю, что 100% использую TDD в варианте "Outside In".
Это когда пишутся только высокоуровние тесты, которые тестируют пользовательские сценарии.
Вот пример стандартного теста (пример на python с pytest, т.к. на java или чем-то подобном будет лишний бойлерплэйт):
Тест делает следующее:
приводим систему в некое начальное состояние
сохраняем в БД объект Question
выполняем над ней определенное действие
отвечаем на вопрос делая PUT запрос в API
проверяем только сайд-эффекты
API вернул код 200
свойство объекта Question изменено в БД
Event был отправлен во очередь сообщений
На последнем проеке таких тестов было процентов 95, и покрывали 100% бизнес сценариев. Остальные 5% тесвов покрывали разные технические штуки.
Преимущество такого подхода в том, что вас вообще не интересует имплементация.
А главное - простота рефакторинга, можно просто выбросить текущую имплементацию и переписать заново и тесты не нужно переписывать.
Я бы сделак что-то вроде:
Тестировал бы используя подход outside-in, т.е. мокировал бы библиотеку requests и проверял бы, что мы отправляем то, что API ожидает.
Ну и если `data` это достаточно сложный объект, мжно добавиь `dataclass` и дополнительно сериализацию/десериализацию, в таком случае из `Api` будем возвращать готовые объекты, а не словарь, соответственно можно будет в этот класс добавить функции манипуляции с объектом.