Библиотека Java разработчика
10.5K subscribers
1.17K photos
594 videos
58 files
1.51K links
📚 Лайфхаки, приёмы и лучшие практики для Java-разработчиков. Всё, что ускорит код и прокачает навыки. Java, Spring, Maven, Hibernate.


По всем вопросам @evgenycarter

РКН clck.ru/3KoGeP
Download Telegram
🏗 SOLID - Пять заповедей программиста

Почему один проект живет 10 лет и его легко дорабатывать, а другой через полгода превращается в "Legacy", к которому страшно подходить?
Разница в соблюдении принципов SOLID.

Это аббревиатура из 5 правил, сформулированных Робертом Мартином (Дядя Боб). Если вы нарушаете их - ваш код "гниет".

Давайте разберем каждую букву.

1️⃣ S - Single Responsibility Principle (Единственная ответственность)

"У класса должна быть только одна причина для изменения."


Как делают новички (God Object):
Класс OrderService делает всё:

1. Считает сумму заказа.
2. Сохраняет заказ в БД.
3. Отправляет email клиенту.
4. Генерирует PDF-чек.

Если бизнес попросит изменить формат чека — мы лезем в этот класс. Если поменяется логика БД - опять в него. Риск сломать отправку писем при правке базы данных огромен!

Как надо:
Разбиваем на маленькие классы:

OrderCalculator (считает).
OrderRepository (сохраняет).
EmailNotificationService (шлет письма).
PdfGenerator (печатает).

OrderService теперь просто дирижер, который вызывает эти компоненты.


2️⃣ O - Open-Closed Principle (Открытость/Закрытость)

"Программные сущности должны быть открыты для расширения, но закрыты для модификации."


Это значит: Не меняйте старый рабочий код, чтобы добавить новую фичу.

Плохо:
У нас есть метод расчета доставки.


if (deliveryType == "DHL") { ... }
else if (deliveryType == "Post") { ... }
// Пришла задача добавить FedEx? Придется лезть сюда и добавлять else if!



Хорошо:
Используем полиморфизм.


interface DeliveryStrategy { void deliver(); }
class DhlDelivery implements DeliveryStrategy { ... }
class PostDelivery implements DeliveryStrategy { ... }

// Нужен FedEx? Просто создаем НОВЫЙ класс, не трогая старые!
class FedExDelivery implements DeliveryStrategy { ... }




3️⃣ L - Liskov Substitution Principle (Принцип подстановки Барбары Лисков)

"Наследники должны без проблем заменять родителей."


Если у вас есть класс Bird с методом fly(), а вы создали наследника Penguin (Пингвин), который при вызове fly() бросает ошибку (потому что пингвины не летают) - вы нарушили LSP.

Суть: Если код работает с базовым классом, он должен работать и с любым его наследником, не зная об этом и не ломаясь.


4️⃣ I - Interface Segregation Principle (Разделение интерфейсов)

"Много маленьких интерфейсов лучше, чем один огромный."


Плохо:
Интерфейс Worker имеет методы work() и eat().
Мы создаем класс Robot. Роботы работают, но не едят.
Нам придется реализовать метод eat() и оставить его пустым или кинуть ошибку. Это мусор.

Хорошо:
Разбейте на Workable и Eatable.
Человек имплементирует оба. Робот - только Workable.


5️⃣ D - Dependency Inversion Principle (Инверсия зависимостей)

"Зависьте от абстракций, а не от конкретики."


Это то, что мы учили в Spring (DI).
Ваш Service не должен зависеть от PostgresRepository. Он должен зависеть от интерфейса Repository.
Тогда вы сможете легко подменить Postgres на MySQL или Mock-объект для тестов, не меняя ни строчки в Сервисе.


SOLID - это фильтр. Прежде чем закоммитить код, спросите себя:

1. Не делает ли мой класс слишком много? (S)
2. Придется ли мне переписывать этот класс, если добавятся новые условия? (O)
3. Не ломаю ли я поведение родителя? (L)
4. Не заставляю ли я других реализовывать ненужные методы? (I)
5. Завишу ли я от интерфейсов или от конкретных классов? (D)

#Architecture #SOLID #CleanCode #OODesign

📲 Мы в MAX

👉@BookJava
👍125🔥3
🏗 Порождающие паттерны: Как рождаются объекты?

Создать объект просто: User u = new User().
А если у объекта 20 полей? А если нам нужен только один экземпляр на всё приложение? А если мы не знаем заранее, какой именно класс нам нужен?
Тут на сцену выходят паттерны.

1️⃣ Singleton (Одиночка)

Суть: Гарантирует, что у класса есть только один экземпляр, и предоставляет к нему глобальную точку доступа.

Где нужен: Логгеры, Конфигурация, Пул соединений с БД.

Как реализовать:

1. Скрываем конструктор (private).
2. Создаем статическое поле с экземпляром.
3. Возвращаем его через статический метод.


public class Database {
// Единственный экземпляр
private static Database instance;

private Database() {} // Никто не создаст объект извне

public static synchronized Database getInstance() {
if (instance == null) {
instance = new Database();
}
return instance;
}
}



⚠️ Важно: В Spring Boot все бины по умолчанию - синглтоны. Вам не нужно писать этот код руками, контейнер Spring сам следит, чтобы сервис был создан один раз.


2️⃣ Builder (Строитель)

Суть: Позволяет создавать сложные объекты пошагово. Спасает от «Телескопического конструктора» (когда у вас конструктор с 10 аргументами, и вы не помните, где там age, а где height).

Было (Ужас):
new User("Alex", null, true, "admin", 25, null);

Стало (Builder):


User user = User.builder()
.name("Alex")
.age(25)
.role("ADMIN")
.active(true)
.build();



🛠 Лайфхак:
В Java не нужно писать Билдер руками (это 50 строк кода). Просто поставьте аннотацию Lombok @Builder над классом.


3️⃣ Factory Method (Фабричный метод)

Суть: Определяет интерфейс для создания объекта, но оставляет подклассам решение о том, какой класс инстанцировать.
Это реализация принципа Open-Closed. Мы добавляем новые типы продуктов, не ломая существующий код.

Пример: У нас есть "Уведомления". Сегодня это Email, завтра SMS, послезавтра Push.


// 1. Интерфейс
interface Notification { void send(String msg); }

// 2. Реализации
class EmailNotification implements Notification { ... }
class SmsNotification implements Notification { ... }

// 3. Фабрика (Решает, что создать)
class NotificationFactory {
public static Notification create(String type) {
return switch (type) {
case "EMAIL" -> new EmailNotification();
case "SMS" -> new SmsNotification();
default -> throw new IllegalArgumentException("Unknown type");
};
}
}

// Клиентский код (не знает про классы Email/Sms, знает только интерфейс)
Notification notification = NotificationFactory.create("SMS");
notification.send("Hello!");



🔥 Итог

1. Singleton - когда нужен один объект на всю систему.
2. Builder - когда объект сложный и у него много параметров.
3. Factory - когда мы не знаем заранее, какой конкретно объект понадобится, или хотим скрыть логику выбора.

#DesignPatterns #GoF #Singleton #Builder #Factory #Java

📲 Мы в MAX

👉@BookJava
👍5🔥3
🔴 Завтра тестовое собеседование с Java-разработчиком

11 февраля(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.

Как это будет:
📂 Сергей Чамкин, старший разработчик из Uzum, ex-WildBerries, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Cергей будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Сергею

Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.

Переходи в нашего бота, чтобы получить ссылку на эфир →
@shortcut_sh_bot

Реклама.
О рекламодателе.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍31