Flyweight — это
Простыми словами:
▪️ Пример
// Flyweight — легковес с общим состоянием
class CharacterStyle {
private final String font; // внутреннее состояние
private final int size; // (intrinsic)
private final String color;
public CharacterStyle(String font, int size, String color) {
this.font = font;
this.size = size;
this.color = color;
}
public void render(char character, int x, int y) { // внешнее состояние
System.out.println("Рендер '" + character +
"' в позиции (" + x + "," + y + ")");
}
}
// Фабрика для переиспользования flyweight-объектов
class StyleFactory {
private Map<String, CharacterStyle> styles = new HashMap<>();
public CharacterStyle getStyle(String font, int size, String color) {
String key = font + size + color;
return styles.computeIfAbsent(key,
k -> new CharacterStyle(font, size, color));
}
}
// Использование
StyleFactory factory = new StyleFactory();
// Миллион символов используют всего несколько объектов стилей
CharacterStyle arial12 = factory.getStyle("Arial", 12, "black");
arial12.render('H', 0, 0);
arial12.render('e', 10, 0);
arial12.render('l', 20, 0);
arial12.render('l', 30, 0);
arial12.render('o', 40, 0);
▪️ Когда использовать
—
—
—
—
▪️ Минусы
—
—
#patterns
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤1🔥1
Выбор зависит от нескольких факторов:
🔹 Монолит подходит для MVP,
🔹 Модульный монолит — это компромисс. Архитектура разбита на
🔹Микросервисы выбираем, когда есть реальная необходимость:
#patterns
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥1🥰1👏1
Dependency Injection (внедрение зависимостей) — это один из основных
DI способствует:
—
—
—
Основные способы внедрения зависимостей в Spring:
🔹 Constructor Injection
Зависимости передаются через конструктор.
public class Service {
private final Repository repository;
public Service(Repository repository) {
this.repository = repository;
}
}🔹Setter Injection
Зависимости передаются через сеттеры.
public class Service {
private Repository repository;
public void setRepository(Repository repository) {
this.repository = repository;
}
}🔹 Field Injection
Зависимости внедряются напрямую в поля класса (обычно с помощью фреймворков, например Spring).
@Component
public class Service {
@Autowired
private Repository repository;
}
#patterns #лучшее2025
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥4❤2👏1
Микросервисы — это
🔹 Ключевые принципы
—
—
—
—
#patterns #лучшее2025
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥2👏1🤔1
Flyweight — это паттерн для
Объект разделяется на intrinsic state (неизменяемое, общее) и extrinsic state (изменяемое, уникальное). Общее состояние хранится в одном экземпляре.
🔹 Примеры:
—
—
—
Паттерн эффективен, когда создаётся много объектов
#patterns
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥1🤔1
Singleton гарантирует, что
public class DatabaseConnection {
private static volatile DatabaseConnection instance;
private DatabaseConnection() {}
public static DatabaseConnection getInstance() {
if (instance == null) {
synchronized (DatabaseConnection.class) {
if (instance == null) {
instance = new DatabaseConnection();
}
}
}
return instance;
}
}Реальные кейсы
—
—
—
—
Подводные камни:
#patterns
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤2🔥1
Это паттерн
Проблема: при сохранении данных в БД и отправке события в Kafka/RabbitMQ — эти две операции не атомарны. Возможны ситуации, когда данные сохранятся, но событие не уйдёт, либо наоборот.
Решение:
🔹 Ключевые свойства
—
—
—
#patterns
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤3🔥1
MVC (Model-View-Controller) — это
▪️ Model (Модель) —
▪️ View (Представление) —
▪️ Controller (Контроллер) —
Этот подход упрощает сопровождение кода, позволяет разделить ответственность между слоями и облегчает тестирование.
#patterns
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤1😁1
DDD (Domain-Driven Design) — подход к проектированию, при котором структура кода отражает структуру бизнес-домена.
Основные строительные блоки
Entity —
Value Object —
Aggregate —
Domain Service —
Repository —
Domain Event —
Bounded Context —
#patterns
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤3🔥1
✅
Сохраняй событие в таблицу outbox в той же транзакции, что и бизнес-данные. Отдельный процесс читает таблицу и публикует в Kafka.
На стороне консьюмера — идемпотентность: проверяй event_id перед обработкой.
#patterns
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤1🔥1
Strategy — это
Когда использовать:
—
—
—
Преимущества:
#patterns
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤3🔥2⚡1
Singleton — это
🔹 Основные характеристики:
—
—
—
🔹 Когда использовать:
—
—
—
—
#patterns
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4👍3🔥1
Adapter (Адаптер) — это
🔹 Когда использовать:
#patterns
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥1🤔1
Factory Method —
🔹 Когда использовать:
🔹 Как работает:
🔹 Плюсы:
—
—
—
#patterns
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤3🔥1
Abstract Factory — это
Простыми словами:
▪️ Пример:
// Абстрактные продукты
interface EmailSender {
void send(String to, String message);
}
interface SmsSender {
void send(String phone, String message);
}
// Абстрактная фабрика
interface NotificationFactory {
EmailSender createEmailSender();
SmsSender createSmsSender();
}
// AWS реализация
class AwsEmailSender implements EmailSender {
public void send(String to, String message) {
System.out.println("Отправка через AWS SES: " + to);
}
}
class AwsSmsSender implements SmsSender {
public void send(String phone, String message) {
System.out.println("Отправка через AWS SNS: " + phone);
}
}
class AwsNotificationFactory implements NotificationFactory {
public EmailSender createEmailSender() {
return new AwsEmailSender();
}
public SmsSender createSmsSender() {
return new AwsSmsSender();
}
}
// Аналогично FirebaseNotificationFactory...
// Использование
NotificationFactory factory = new AwsNotificationFactory();
EmailSender email = factory.createEmailSender();
SmsSender sms = factory.createSmsSender();
// Гарантия: оба сервиса работают через AWS
▪️ В чем отличие от Factory Method
— Factory Method создает
— Abstract Factory создает
▪️ Когда использовать
▪️ Минус
#patterns
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3👍2🔥1
Prototype — это
Простыми словами: вместо создания объекта с нуля через конструктор, вы клонируете уже существующий экземпляр.
▪️ Пример:
// Прототип
abstract class Report implements Cloneable {
protected String template;
protected DatabaseConnection dbConnection;
protected Map<String, Object> settings;
// Сложная инициализация
public Report() {
this.dbConnection = new DatabaseConnection(); // затратная операция
this.settings = loadDefaultSettings(); // загрузка из файла
}
@Override
public Report clone() {
try {
Report cloned = (Report) super.clone();
// Глубокое копирование для изменяемых полей
cloned.settings = new HashMap<>(this.settings);
return cloned;
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
abstract void generate();
}
class SalesReport extends Report {
void generate() {
System.out.println("Генерация отчета по продажам");
}
}
// Использование
Report prototype = new SalesReport(); // долгая инициализация
// Быстрое создание копий
Report report1 = prototype.clone();
Report report2 = prototype.clone();
report2.settings.put("period", "Q2"); // изменяем только нужные параметры
▪️ Когда использовать
—
—
—
▪️ Важно: Shallow vs Deep Copy
Shallow copy — копируются только примитивы, ссылки на объекты остаются теми же
Deep copy — создаются копии вложенных объектов
▪️ Альтернативы clone()
— Copy constructor: new Report(original)
— Статический метод: Report.copy(original)
— Сериализация: для очень сложных объектов
▪️ Минус
#patterns
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4❤1🔥1
Flyweight — это
Простыми словами:
▪️ Пример
// Flyweight — легковес с общим состоянием
class CharacterStyle {
private final String font; // внутреннее состояние
private final int size; // (intrinsic)
private final String color;
public CharacterStyle(String font, int size, String color) {
this.font = font;
this.size = size;
this.color = color;
}
public void render(char character, int x, int y) { // внешнее состояние
System.out.println("Рендер '" + character +
"' в позиции (" + x + "," + y + ")");
}
}
// Фабрика для переиспользования flyweight-объектов
class StyleFactory {
private Map<String, CharacterStyle> styles = new HashMap<>();
public CharacterStyle getStyle(String font, int size, String color) {
String key = font + size + color;
return styles.computeIfAbsent(key,
k -> new CharacterStyle(font, size, color));
}
}
// Использование
StyleFactory factory = new StyleFactory();
// Миллион символов используют всего несколько объектов стилей
CharacterStyle arial12 = factory.getStyle("Arial", 12, "black");
arial12.render('H', 0, 0);
arial12.render('e', 10, 0);
arial12.render('l', 20, 0);
arial12.render('l', 30, 0);
arial12.render('o', 40, 0);
▪️ Когда использовать
—
—
—
—
▪️ Минусы
—
—
#patterns
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3👍2❤1
Builder — это
Простыми словами:
▪️ Пример:
public class HttpClient {
private final String baseUrl;
private final int connectTimeout;
private final int readTimeout;
private final Map<String, String> headers;
private final int maxRetries;
private HttpClient(Builder builder) {
this.baseUrl = builder.baseUrl;
this.connectTimeout = builder.connectTimeout;
this.readTimeout = builder.readTimeout;
this.headers = builder.headers;
this.maxRetries = builder.maxRetries;
}
public static class Builder {
private final String baseUrl; // обязательный
private int connectTimeout = 5000; // значение по умолчанию
private int readTimeout = 10000;
private Map<String, String> headers = new HashMap<>();
private int maxRetries = 3;
public Builder(String baseUrl) {
this.baseUrl = baseUrl;
}
public Builder connectTimeout(int ms) {
this.connectTimeout = ms;
return this;
}
public Builder readTimeout(int ms) {
this.readTimeout = ms;
return this;
}
public Builder header(String key, String value) {
this.headers.put(key, value);
return this;
}
public Builder maxRetries(int retries) {
this.maxRetries = retries;
return this;
}
public HttpClient build() {
return new HttpClient(this);
}
}
}
// Использование
HttpClient client = new HttpClient.Builder("https://api.example.com")
.connectTimeout(3000)
.header("Authorization", "Bearer token")
.maxRetries(5)
.build();▪️ Когда использовать
—
—
—
▪️ Builder vs конструктор
— Конструктор:
— Builder:
▪️ Минус
#patterns
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3❤2🔥1
Bridge — это
Простыми словами:
▪️ Пример:
// Реализация — «как доставить»
interface MessageSender {
void send(String message, String recipient);
}
class EmailSender implements MessageSender {
public void send(String message, String recipient) {
System.out.println("Email → " + recipient + ": " + message);
}
}
class SmsSender implements MessageSender {
public void send(String message, String recipient) {
System.out.println("SMS → " + recipient + ": " + message);
}
}
// Абстракция — «что отправить»
abstract class Notification {
protected MessageSender sender; // мост к реализации
public Notification(MessageSender sender) {
this.sender = sender;
}
abstract void notify(String recipient, String message);
}
class UrgentNotification extends Notification {
public UrgentNotification(MessageSender sender) {
super(sender);
}
void notify(String recipient, String message) {
sender.send("[СРОЧНО] " + message, recipient);
sender.send("[СРОЧНО] Повторное напоминание: " + message, recipient);
}
}
class RegularNotification extends Notification {
public RegularNotification(MessageSender sender) {
super(sender);
}
void notify(String recipient, String message) {
sender.send(message, recipient);
}
}
// Использование — любая комбинация
Notification urgentSms = new UrgentNotification(new SmsSender());
urgentSms.notify("+79991234567", "Сервер упал");
Notification regularEmail = new RegularNotification(new EmailSender());
regularEmail.notify("dev@company.com", "Деплой завершён");
▪️ Когда использовать
—
—
—
▪️ Bridge vs Strategy
— Strategy:
— Bridge:
▪️ Минус
#patterns
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤3🔥1
Composite — это
Простыми словами:
▪️ Пример:
// Общий интерфейс
interface OrganizationUnit {
String getName();
long getSalary();
}
// Лист — отдельный сотрудник
class Employee implements OrganizationUnit {
private final String name;
private final long salary;
public Employee(String name, long salary) {
this.name = name;
this.salary = salary;
}
public String getName() { return name; }
public long getSalary() { return salary; }
}
// Композит — отдел, содержит другие элементы
class Department implements OrganizationUnit {
private final String name;
private final List<OrganizationUnit> units = new ArrayList<>();
public Department(String name) {
this.name = name;
}
public void add(OrganizationUnit unit) {
units.add(unit);
}
public String getName() { return name; }
public long getSalary() {
return units.stream()
.mapToLong(OrganizationUnit::getSalary)
.sum();
}
}
// Использование
Department dev = new Department("Разработка");
dev.add(new Employee("Анна", 200_000));
dev.add(new Employee("Борис", 180_000));
Department company = new Department("Компания");
company.add(dev);
company.add(new Employee("CEO Иван", 500_000));
System.out.println(company.getSalary()); // 880000
▪️ Когда использовать
—
—
▪️ Минус
#patterns
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤1🔥1