Обновить
26
ApeCoder@ApeCoder

Разработчик

6
Подписчики
Отправить сообщение

Я не очень понял. Нельзя как-нибудь поподробнее объяснить?


1-1 обертки над api в которых создавались нужные зависимости

Мне кажется, 1-1 обертки это и есть дублирование, нет?

Она является внутренней по отношению к предметной области и требованиям.

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


Иногда я не тестирую очень тесно связанные компоненты (например итератор отдельно от коллекции).

Если бы не было тестов или они тестировали конкретные «юниты» — никогда бы не взялся за такой рефакторинг.

Были ли тесты хорошим кодом? Содержали ли они дублирование?

Компонента предоставляет интерфейс, модель данных и инварианты над моделью.

Это похоже на описание хорошего класса :)


В статье призывается не делать тестов на появляющиеся внутренние классы, спрятанные за публичным API. Нет это не компонента, это деталь реализации компоненты.

Почему одна компонента не может быть деталью реализации другой?

Что такое компонента? В статье призывается не создавать новых тестов когда мы выносим что-то в отдельный класс. Этот отдельный класс это компонента или нет? По какомй криетрию?

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


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


С другой стороны ваша система в целом тоже является деталью реализации для кого-то (может как часть чьего-то бизнеса).


Когда вы рефакторите код и у вас выделился какой-то слой абстракции, если это делать осмысленно то получится типа "поддержка работы с URL" или "дополнительные методы работы со строками".


Это аналогично тому, что вы в требованиях выделили главу "В целом с URL надо обращаться вот так" или "Вот так должно происходить слияние строк через одну" и далее ссылаетесь на эту главу.


Иначе вам придется повторять одни и те же вещи что в требованиях, что в коде, что в тестах.

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


Ваши тесты могут покрыть только требование "rate limiting" чего бы это ни значило. Возможно у вас будет hexagonal artchitecture со своими focused integration tests по rate limiting и отдельно протестированным тестовым адаптером. Вам не надо будет повторять тесты redis в своих тестах.

Имхо.


Какая угодно реализация может быть. Хорошая реализация внутри должна быть отражением предметной области. (см. Ubiquitous Language)


То есть микросервисы на марсе должны быть отражением какой-то части требований.

Я не согласен. И структура тестов и структура кода должна быть отражением требований. Если тесты по организации не похожи на код, то код или тесты не отражает требований.

Обычно рекомендуют делать код лучше понемножку.
http://jbazuzicode.blogspot.com/2017/08/refactor-lot-but-only-when-its.html


Don't just refactor for fun. Refactor in service of delivering business value. If there's some terrible code that you never need to touch, then there's no reason to change it. Leave it terrible.

So, when are the right times to refactor?
  • When you're changing code. Refactor to make it well-designed for its new purpose.
  • When you're reading code. Every time you gain some understanding, refactor to record that understanding. Lots of renames.
  • When you're afraid of code. If there's code you should be changing or reading, but you avoid because it's such a mess, then you should definitely refactor it.


Note that this refactoring is a small improvement each time, not a dramatic major rewrite. >The goal is Better, not Good.

Приведите пожалуйста пример кода, который разбивать неудобно, но нужно, с указанием причины, почему неудобно

Им позволяет. Просто им не надо, потому, что строчка короткая

А вторую редактор не позволяет? :))))

При этом вы сами, небось, предпочитаете писать


items.Where(x => x.Price > 10).Count()

вместо


Count(Where(items, x => x.Price > 10))

да?

«Неочевидная вещь» – это проблема дизайна

Умножение — вещь, неочевидная для первоклассника. Надо ли делать язык без умножений или учить первоклассников умножению?


На сколько помню, целью Котлина было облегчение разработки и защита от глупых ошибок. А в результате одни глупые ошибки заменили на другие.

Это суждение — следствие опыта разработки на котлине, или вы просто посмотрели пазлеры?

Что значит «наследовать контракт»?

Можно сделать более специфичный контракт который унаследует поддерживаемые операции у другого контракта и добавит свои.


Кстати, каждому классу концептуально соотвествует свой наиболее специфичный контракт. Типа "Поток-в-памяти это такой поток вообще, который обязуется еще и хранить то, что в него запихали в ОЗУ и предоставлять потом по требованию"

Но зачем в таком случае абстракция над перебором списка, если она не позволяет нам повторно использовать код?

Она нам позволяет повторно использовать код. Но не весь. Какого поведения вы хотите от нее? Чтобы выполняла параллельно? Чтобы ждала выполнения каждого шага? Это и надо специфицировать. То есть передавать ей функцию, которая не возвращает task, а что-то делает.

Но раньше-то она скрывала список и действия!

Это уже не она. Никто не мешает оставить старую, просто абстрагировать перебор оттуда


let printList = List.iter printItem

Хорошо, что ошибочный код не скомпилируется. Но плохо что он при этом не будет работать.

Если надо последовательно объединить асинхронные функции просто воспользуйтесь другой функцией

Информация

В рейтинге
Не участвует
Откуда
Россия
Дата рождения
Зарегистрирован
Активность