62 lines
6.4 KiB
Markdown
62 lines
6.4 KiB
Markdown
|
---
|
|||
|
aliases:
|
|||
|
tags:
|
|||
|
- maturity/🌱
|
|||
|
date: 2024-11-24
|
|||
|
---
|
|||
|
Часто в программировании дублирование кода считается антишаблоном, и существует стремление избежать его с помощью [[efficiency/Рефакторинг кода|рефакторинга]] и выделения общего функционала в отдельные методы или классы.
|
|||
|
|
|||
|
Однако не каждое дублирование кода — это плохо, и иногда оно может быть оправдано. Например, ==дублирование может быть оправдано, когда участки кода выполняют похожие задачи, но с потенциалом для различного развития в будущем==, или когда абстракция добавит ненужную сложность и снизит [[Читаемый код|читаемость]].
|
|||
|
|
|||
|
Одним из примеров, когда дублирование кода не является ошибкой, является ситуация, когда код выполняет похожие, но не идентичные задачи. Такие ==дублирующиеся участки могут иметь разные цели и эволюционировать независимо, в зависимости от требований==. Например, методы обработки данных для разных типов клиентов могут развиваться с учетом специфики каждого случая, сохраняя свою уникальность.
|
|||
|
|
|||
|
**Когда дублирование допустимо**
|
|||
|
- **Независимое развитие логики**. Если два участка кода имеют потенциал для разного развития в будущем, лучше оставить их отдельно.
|
|||
|
- **Простота понимания**. Иногда небольшое дублирование делает код проще для понимания, поскольку каждый модуль содержит всю необходимую информацию для выполнения своей задачи, без излишней зависимости от общего функционала.
|
|||
|
- **Отсутствие преждевременной абстракции**. Преждевременная оптимизация и создание абстракций могут привести к созданию излишне сложных конструкций, которые сложно поддерживать. Дублирование кода может помочь избежать преждевременного усложнения архитектуры.
|
|||
|
|
|||
|
Рассмотрим ситуацию, когда в системе обработки заказов существует два похожих метода для расчета скидок, но для разных типов клиентов. Допустим, у нас есть метод расчета скидок для розничных клиентов и метод расчета скидок для корпоративных клиентов:
|
|||
|
|
|||
|
```java
|
|||
|
public class RetailCustomerDiscountCalculator {
|
|||
|
public double calculateDiscount(Order order) {
|
|||
|
// Логика расчета скидки для розничного клиента
|
|||
|
double discount = 0;
|
|||
|
if (order.getTotalAmount() > 100) {
|
|||
|
discount = 10;
|
|||
|
}
|
|||
|
// Дополнительные условия и правила
|
|||
|
return discount;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public class CorporateCustomerDiscountCalculator {
|
|||
|
public double calculateDiscount(Order order) {
|
|||
|
// Логика расчета скидки для корпоративного клиента
|
|||
|
double discount = 0;
|
|||
|
if (order.getTotalAmount() > 500) {
|
|||
|
discount = 15;
|
|||
|
}
|
|||
|
// Дополнительные условия и правила, уникальные для корпоративных клиентов
|
|||
|
return discount;
|
|||
|
}
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
Методы `calculateDiscount` в обоих классах имеют схожую логику, и на первый взгляд их можно объединить в один общий метод. Однако, правила расчета скидок для розничных и корпоративных клиентов могут измениться и развиваться в разных направлениях. Например, для корпоративных клиентов могут добавиться специфические условия, такие как скидки за объем или специальные акции, в то время как для розничных клиентов будут учитываться другие критерии, такие как лояльность или сезонные предложения.
|
|||
|
|
|||
|
Объединение этих методов в один общий могло бы создать ненужную сильную [[architecture/Связанность|связанность]] между разными бизнес-правилами, что усложнило бы внесение изменений и тестирование. Это может привести к тому, что изменения в одной части логики скидок затр онут другую, даже если для этого нет необходимости, что затруднит дальнейшее развитие. В таких случаях лучше оставить дублирование, чтобы обеспечить гибкость и независимость развития каждой части системы.
|
|||
|
***
|
|||
|
## Мета информация
|
|||
|
**Область**:: [[../meta/zero/00 Эффективная разработка|00 Эффективная разработка]]
|
|||
|
**Родитель**::
|
|||
|
**Источник**::
|
|||
|
**Создана**:: [[2024-11-24]]
|
|||
|
**Автор**::
|
|||
|
### Дополнительные материалы
|
|||
|
-
|
|||
|
|
|||
|
### Дочерние заметки
|
|||
|
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
|
|||
|
|