Developer's mind
583 subscribers
16 photos
18 links
Программирую, обучаю, делюсь опытом
java/kotlin, spring boot, clean code, databases
обратная связь:
@Hcd5opza9bdcjid26fg
https://t.me/developers_mind
Download Telegram
sOlid

OCP или Open-Closed Principle довольно интересная штука. На моей практике этот принцип в целом довольно редко применяется. Возможно это связано с довольно быстрым современным миром и быстро меняющимися требованиями в agile-процессах. Тем не менее умственными упражнениями такое вполне достижимо и в реальной разработке можно (и нужно) к этому стремиться.
👉 OCP - это принцип при котором классы закрыты для изменений, но открыты для расширений.
💥 Итак, идея вот в чем. Представьте что архитектура и код в вашем проекте имеют такое свойство, что вы не можете никогда менять старый код ради нового функционала - только писать новое поведение, новые классы и т.д. Разумеется, ради исправления реальных багов, старый код можно править. А ради изменения поведения каких то классов вам нужно будет заново имплементировать какой-либо интерфейс и написать это поведение с нуля. К чему это приведет? Это приведет к тому что весь код работающий в вашем проекте будет без багов и проблем (разумеется - если ваши интерфейсы протестированы).
☝️ Более того, стремление к реализации такого принципа приведет к более лаконичной и аккуратной архитектуре - представьте, что перед стартом задачи вам скажут, что после релиза вы не сможете изменять существующие строки в классах проекта, а только дописывать новые методы и классы. Вы сразу более активно начнете пользоваться интерфейсами, абстракциями, сделаете ваши классы низкосвязанными - ведь вам не захочется в будущем переписывать весь проект ради реализации новой прихоти менеджера из-за очень высокой связности классов внутри проекта.
🧠 Попробуйте взглянуть на вашу последнюю задачу или реализованный модуль с точки зрения OCP - сможете ли вы изменить поведение части бизнес-логики не внося изменения в основные файлы? Сможете ли реализовать дополнительную функциональность не добавляя IF-ы, а лишь только добавляя новые методы и классы? В следующей задаче попробуйте найти решение такое, чтоб любое будущее изменение функциональности требовало вносить минимальные изменения в существующие классы.

#SOLID #Principles #OCP
soLid

LSP (Liskov Substitution Principle) - Принцип подстановки Барбары Лисков.
Меня лично всегда “конфьюзило” это неочевидное название принципа. Но - “так исторически сложилось”. Итак, о чем же он?
Он про наследование - в основном он призывает нас к тому, чтоб мы организовывали наш код таким образом, что в каком-либо месте подстановка одного объекта вместо объекта другого класса, но имплементирующего тот же интерфейс, - не приводило бы к изменению поведения методов где эти эти объекты используются. Иными словами - вызывающие методы не должны ничего знать о конкретных реализациях используемых ими интерфейсов и уж тем более как-то изменять свое поведение в зависимости от того, объект какого типа они получили на входе.

Пример:
interface Animal {
String getSound();
}
class Dog implements Animal {
public String getSound() {
return "woof";
}
}
class Cat implements Animal {
public String getSound() {
return "meow";
}
}
void doSomething(Animal animal) {
String sound = animal.getSound();
if (sound.equals("woof")) {
System.out.print("Dog");
} else {
System.out.print("Cat");
}
System.out.println(" says " + sound);
}


В примере выше можно было бы заменить и проверку по звуку на, например, проверку по instanceof. В любом случае в методе doSomething после этого появляется знание о деталях реализации интерфейса. Более того так мы нарушили и принцип #OCP - теперь для добавления новой имплементации Animal нам придется и обновлять метод doSomething.



Правильно так:

interface Animal {
String getSound();
String getName();
}
class Dog implements Animal {
public String getSound() {
return "woof";
}
public String getName() {
return "Dog";
}
}
class Cat implements Animal {
public String getSound() {
return "meow";
}
public String getName() {
return "Cat";
}
}
void doSomething(Animal animal) {
System.out.println(animal.getName() + " says " + animal.getSound());
}