← Назад к вопросам

Какие знаешь современные стили написания кода?

2.0 Middle🔥 171 комментариев
#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Какие современные стили написания кода знаешь?

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

1. Functional Programming Style (Функциональный стиль)

Начиная с Java 8, появилась поддержка функционального программирования через Lambda expressions и Stream API:

public class FunctionalStyle {
    static class User {
        private String name;
        private int age;
        private List<String> skills;
        
        // Конструктор и геттеры опущены
    }
    
    // ❌ Императивный стиль (старый)
    public List<String> getSkillsOld(List<User> users) {
        List<String> result = new ArrayList<>();
        for (User user : users) {
            if (user.getAge() > 25) {
                for (String skill : user.getSkills()) {
                    if (!result.contains(skill)) {
                        result.add(skill);
                    }
                }
            }
        }
        return result;
    }
    
    // ✅ Функциональный стиль (современный)
    public List<String> getSkillsNew(List<User> users) {
        return users.stream()
            .filter(user -> user.getAge() > 25)
            .flatMap(user -> user.getSkills().stream())
            .distinct()
            .sorted()
            .collect(Collectors.toList());
    }
}

2. Records (Java 16+)

Records — это краткий способ создания immutable data classes:

// ❌ Старый способ
public class PersonOld {
    private final String name;
    private final int age;
    private final String email;
    
    public PersonOld(String name, int age, String email) {
        this.name = name;
        this.age = age;
        this.email = email;
    }
    
    public String getName() { return name; }
    public int getAge() { return age; }
    public String getEmail() { return email; }
    
    @Override
    public boolean equals(Object o) { /* ... */ }
    
    @Override
    public int hashCode() { /* ... */ }
    
    @Override
    public String toString() { /* ... */ }
}

// ✅ Новый способ с Records
public record Person(
    String name,
    int age,
    String email
) {
    // Всё генерируется автоматически!
    // equals, hashCode, toString, getters
}

// Использование
public class RecordExample {
    public static void main(String[] args) {
        Person person = new Person("Иван", 30, "ivan@example.com");
        System.out.println(person.name());
        System.out.println(person);
    }
}

3. Sealed Classes (Java 17+)

Sealed classes позволяют контролировать, какие классы могут наследовать:

// Определяем, какие классы могут наследовать Shape
public sealed class Shape permits Circle, Rectangle, Triangle {
    abstract double getArea();
}

public final class Circle extends Shape {
    private double radius;
    
    @Override
    double getArea() {
        return Math.PI * radius * radius;
    }
}

public final class Rectangle extends Shape {
    private double width, height;
    
    @Override
    double getArea() {
        return width * height;
    }
}

public final class Triangle extends Shape {
    private double a, b, c;
    
    @Override
    double getArea() { /* ... */ }
}

// Использование
public class SealedExample {
    public static void main(String[] args) {
        Shape shape = new Circle();
        // Компилятор знает все возможные типы!
    }
}

4. Pattern Matching (Java 16+, улучшается в каждой версии)

Pattern Matching упрощает работу с instanceof и switch:

// ❌ Старый способ
public void processOld(Object obj) {
    if (obj instanceof String) {
        String str = (String) obj;
        System.out.println("Строка: " + str.toUpperCase());
    } else if (obj instanceof Integer) {
        Integer num = (Integer) obj;
        System.out.println("Число: " + (num * 2));
    }
}

// ✅ Новый способ с Pattern Matching
public void processNew(Object obj) {
    if (obj instanceof String str) {
        System.out.println("Строка: " + str.toUpperCase());
    } else if (obj instanceof Integer num) {
        System.out.println("Число: " + (num * 2));
    }
}

// ✅ Switch с Pattern Matching (Java 17+)
public String getTypeInfo(Object obj) {
    return switch (obj) {
        case String str -> "Строка длины " + str.length();
        case Integer num -> "Число: " + (num * 2);
        case Double d -> "Дробь: " + d.toString();
        case null -> "null";
        default -> "Неизвестный тип";
    };
}

5. Domain-Driven Design (DDD)

Структура приложения, ориентированная на бизнес-логику:

// Domain Layer
public record OrderId(String value) {}
public record Money(BigDecimal amount, Currency currency) {}

public class Order {
    private OrderId id;
    private List<OrderItem> items;
    private Money totalPrice;
    
    public void addItem(OrderItem item) {
        // Бизнес-логика в домене
        if (items.size() >= 100) {
            throw new DomainException("Максимум 100 товаров");
        }
        items.add(item);
        recalculateTotal();
    }
}

// Application Layer
@Service
public class CreateOrderUseCase {
    private OrderRepository repository;
    
    public void execute(CreateOrderCommand cmd) {
        Order order = new Order(/* ... */);
        // Бизнес-логика выполнена, сохраняем
        repository.save(order);
    }
}

// Infrastructure Layer
@Repository
public class OrderRepositoryJpa implements OrderRepository {
    private JpaRepository<OrderEntity, Long> jpa;
    
    @Override
    public void save(Order order) {
        // Трансляция в JPA сущность
        jpa.save(toEntity(order));
    }
}

6. Clean Architecture / Hexagonal Architecture

Отделение бизнес-логики от деталей реализации:

// Core business logic (не зависит от DB, HTTP и т.д.)
public class PaymentService {
    private PaymentRepository repository;
    
    public void processPayment(Payment payment) {
        if (payment.getAmount().isNegative()) {
            throw new InvalidPaymentException();
        }
        repository.save(payment);
    }
}

// Adapter for Database
@Repository
public class PaymentRepositoryPostgres implements PaymentRepository {
    private JdbcTemplate jdbc;
    
    @Override
    public void save(Payment payment) {
        // PostgreSQL специфичный код
    }
}

// Adapter for HTTP
@RestController
@RequestMapping("/api/payments")
public class PaymentController {
    private PaymentService service;
    
    @PostMapping
    public ResponseEntity<?> create(@RequestBody PaymentRequest req) {
        service.processPayment(/* ... */);
        return ResponseEntity.ok().build();
    }
}

7. Convention over Configuration

Вместо явной конфигурации используются соглашения (Spring Boot подход):

// ✅ Современный подход (Spring Boot)
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

@RestController
@RequestMapping("/users")
public class UserController {
    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        return /* ... */;
    }
}

// Всё работает без явной конфигурации!

8. Immutability by Default

Современный подход — делать объекты неизменяемыми по умолчанию:

public record Config(
    String host,
    int port,
    boolean ssl
) {}

public class User {
    private final String name;      // final
    private final List<String> tags; // Неизменяемый список
    
    public User(String name, List<String> tags) {
        this.name = name;
        this.tags = List.copyOf(tags); // Защита от изменений
    }
    
    // Вместо setters используем copy() для создания новых объектов
    public User withName(String newName) {
        return new User(newName, this.tags);
    }
}

Резюме современных трендов

  1. Функциональное программирование — Stream API, Lambda
  2. Records — краткий синтаксис для data classes
  3. Sealed classes — контроль наследования
  4. Pattern Matching — упрощение работы с типами
  5. DDD/Clean Architecture — организация по бизнес-логике
  6. Immutability — неизменяемость объектов
  7. Convention over Configuration — минимум явной конфигурации
  8. Dependency Injection — слабая связанность через DI контейнеры

Эти подходы делают код более читаемым, поддерживаемым и менее подверженным ошибкам.

Какие знаешь современные стили написания кода? | PrepBro