С какими паттернами работал
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Design Patterns — опыт использования
Design patterns — это не просто теория, это практический инструмент, который я использую каждый день в production коде. Вот мой опыт с основными паттернами.
Creational Patterns
Singleton Используется осторожно, только для stateless объектов. В Spring это управляется через @Bean.
Factory pattern Для создания объектов в зависимости от условий:
public interface PaymentProcessor {
void process(Payment payment);
}
public class PaymentProcessorFactory {
public static PaymentProcessor create(PaymentType type) {
switch (type) {
case CREDIT_CARD:
return new CreditCardProcessor();
case PAYPAL:
return new PayPalProcessor();
case BITCOIN:
return new BitcoinProcessor();
default:
throw new IllegalArgumentException("Unknown type: " + type);
}
}
}
Builder pattern Для создания сложных объектов с большим количеством параметров:
@Data
@Builder
public class Order {
private Long id;
private User customer;
private List<OrderItem> items;
private BigDecimal total;
private LocalDateTime createdAt;
private String notes;
private OrderStatus status;
}
Order order = Order.builder()
.customer(user)
.items(items)
.total(BigDecimal.valueOf(100.0))
.status(OrderStatus.PENDING)
.build();
Dependency Injection Spring делает его стандартом для управления зависимостями.
Structural Patterns
Decorator pattern Для добавления функциональности без изменения исходного класса:
public interface DataSource {
InputStream getInputStream();
}
public class EncryptionDecorator implements DataSource {
private DataSource source;
public EncryptionDecorator(DataSource source) {
this.source = source;
}
@Override
public InputStream getInputStream() {
InputStream raw = source.getInputStream();
return new DecryptionInputStream(raw);
}
}
Adapter pattern Для совместимости между несовместимыми интерфейсами.
Facade pattern Для упрощения сложных систем:
public class OrderFacade {
private UserService userService;
private PaymentService paymentService;
private InventoryService inventoryService;
public void createOrder(CreateOrderRequest request) {
User user = userService.getUser(request.getUserId());
paymentService.charge(user, request.getAmount());
inventoryService.reserve(request.getItems());
}
}
Behavioral Patterns
Strategy pattern Для выбора алгоритма во время runtime:
public interface SortingStrategy {
void sort(List<Integer> list);
}
public class Sorter {
private SortingStrategy strategy;
public Sorter(SortingStrategy strategy) {
this.strategy = strategy;
}
public void execute(List<Integer> list) {
strategy.sort(list);
}
}
Observer pattern Для event-driven архитектуры:
public class OrderEventPublisher {
private List<OrderEventListener> listeners = new ArrayList<>();
public void subscribe(OrderEventListener listener) {
listeners.add(listener);
}
public void publish(OrderEvent event) {
listeners.forEach(l -> l.onOrderEvent(event));
}
}
Template Method pattern Для определения скелета алгоритма в базовом классе:
public abstract class ReportGenerator {
public void generate() {
fetchData();
processData();
formatOutput();
saveReport();
}
protected abstract void fetchData();
protected abstract void processData();
}
Chain of Responsibility Для обработки запроса цепочкой обработчиков:
public abstract class AuthenticationHandler {
protected AuthenticationHandler next;
public void setNext(AuthenticationHandler next) {
this.next = next;
}
public abstract boolean handle(AuthenticationRequest request);
}
public class BasicAuthHandler extends AuthenticationHandler {
@Override
public boolean handle(AuthenticationRequest request) {
if (isBasicAuth(request)) {
return validateBasicAuth(request);
}
return next != null && next.handle(request);
}
}
Architecture Patterns
Repository pattern Для абстракции доступа к данным:
public interface UserRepository {
User findById(Long id);
List<User> findAll();
void save(User user);
void delete(Long id);
}
Circuit Breaker pattern Для защиты от cascading failures в микросервисах.
CQRS (Command Query Responsibility Segregation) Для разделения read и write моделей:
@Service
public class OrderCommandService {
public void createOrder(CreateOrderCommand cmd) {
Order order = new Order(cmd);
orderRepository.save(order);
eventBus.publish(new OrderCreatedEvent(order));
}
}
@Service
public class OrderQueryService {
private OrderReadRepository readRepository;
public OrderDTO getOrder(Long id) {
return readRepository.findById(id);
}
}
Итого: Design Patterns — это не просто абстрактная теория, это практические инструменты. Я использую их целенаправленно, выбирая правильный паттерн для правильной проблемы. Главное правило: не переусложняй без необходимости, но знай паттерны достаточно хорошо, чтобы применить когда они реально нужны.