Компонента предоставляет интерфейс, модель данных и инварианты над моделью.
Это похоже на описание хорошего класса :)
В статье призывается не делать тестов на появляющиеся внутренние классы, спрятанные за публичным API. Нет это не компонента, это деталь реализации компоненты.
Почему одна компонента не может быть деталью реализации другой?
Что такое компонента? В статье призывается не создавать новых тестов когда мы выносим что-то в отдельный класс. Этот отдельный класс это компонента или нет? По какомй криетрию?
Дело в том, что любая система состоит из подсистем. Если не покрывать тестами более нижние слои абстракции то нужно тестировать их логику везде.
То есть любой код который выполняет операцию конкатенации строк, должен проверять все их значимые варианты, а не надеяться на то, что они протестированны на более нижнем уровне.
С другой стороны ваша система в целом тоже является деталью реализации для кого-то (может как часть чьего-то бизнеса).
Когда вы рефакторите код и у вас выделился какой-то слой абстракции, если это делать осмысленно то получится типа "поддержка работы с URL" или "дополнительные методы работы со строками".
Это аналогично тому, что вы в требованиях выделили главу "В целом с URL надо обращаться вот так" или "Вот так должно происходить слияние строк через одну" и далее ссылаетесь на эту главу.
Иначе вам придется повторять одни и те же вещи что в требованиях, что в коде, что в тестах.
Я не знаю, что такое redis, но полагаю, ято это какой-то свой продукт, со своей технической предметной областью который будут покрывать свои тесты.
Ваши тесты могут покрыть только требование "rate limiting" чего бы это ни значило. Возможно у вас будет hexagonal artchitecture со своими focused integration tests по rate limiting и отдельно протестированным тестовым адаптером. Вам не надо будет повторять тесты redis в своих тестах.
Я не согласен. И структура тестов и структура кода должна быть отражением требований. Если тесты по организации не похожи на код, то код или тесты не отражает требований.
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.
Можно сделать более специфичный контракт который унаследует поддерживаемые операции у другого контракта и добавит свои.
Кстати, каждому классу концептуально соотвествует свой наиболее специфичный контракт. Типа "Поток-в-памяти это такой поток вообще, который обязуется еще и хранить то, что в него запихали в ОЗУ и предоставлять потом по требованию"
Но зачем в таком случае абстракция над перебором списка, если она не позволяет нам повторно использовать код?
Она нам позволяет повторно использовать код. Но не весь. Какого поведения вы хотите от нее? Чтобы выполняла параллельно? Чтобы ждала выполнения каждого шага? Это и надо специфицировать. То есть передавать ей функцию, которая не возвращает task, а что-то делает.
Я не очень понял. Нельзя как-нибудь поподробнее объяснить?
Мне кажется, 1-1 обертки это и есть дублирование, нет?
Я стараюсь, чтобы такие компоненты либо были сформулированны в терминах предметной области либо обладали своей внутренней предметной областью.
Иногда я не тестирую очень тесно связанные компоненты (например итератор отдельно от коллекции).
Были ли тесты хорошим кодом? Содержали ли они дублирование?
Это похоже на описание хорошего класса :)
Почему одна компонента не может быть деталью реализации другой?
Что такое компонента? В статье призывается не создавать новых тестов когда мы выносим что-то в отдельный класс. Этот отдельный класс это компонента или нет? По какомй криетрию?
Дело в том, что любая система состоит из подсистем. Если не покрывать тестами более нижние слои абстракции то нужно тестировать их логику везде.
То есть любой код который выполняет операцию конкатенации строк, должен проверять все их значимые варианты, а не надеяться на то, что они протестированны на более нижнем уровне.
С другой стороны ваша система в целом тоже является деталью реализации для кого-то (может как часть чьего-то бизнеса).
Когда вы рефакторите код и у вас выделился какой-то слой абстракции, если это делать осмысленно то получится типа "поддержка работы с 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
Приведите пожалуйста пример кода, который разбивать неудобно, но нужно, с указанием причины, почему неудобно
Им позволяет. Просто им не надо, потому, что строчка короткая
А вторую редактор не позволяет? :))))
При этом вы сами, небось, предпочитаете писать
вместо
да?
Mob programming
О вреде премирования
Умножение — вещь, неочевидная для первоклассника. Надо ли делать язык без умножений или учить первоклассников умножению?
Это суждение — следствие опыта разработки на котлине, или вы просто посмотрели пазлеры?
Можно сделать более специфичный контракт который унаследует поддерживаемые операции у другого контракта и добавит свои.
Кстати, каждому классу концептуально соотвествует свой наиболее специфичный контракт. Типа "Поток-в-памяти это такой поток вообще, который обязуется еще и хранить то, что в него запихали в ОЗУ и предоставлять потом по требованию"
Она нам позволяет повторно использовать код. Но не весь. Какого поведения вы хотите от нее? Чтобы выполняла параллельно? Чтобы ждала выполнения каждого шага? Это и надо специфицировать. То есть передавать ей функцию, которая не возвращает task, а что-то делает.
Это уже не она. Никто не мешает оставить старую, просто абстрагировать перебор оттуда
Если надо последовательно объединить асинхронные функции просто воспользуйтесь другой функцией