TIL

[250324 TIL] SOLID 원칙과 Spring의 객체 지향 설계 원칙

도원좀비 2025. 3. 24. 20:38

✅ SOLID 원칙이란?

SOLID 원칙은 유지보수성, 확장성, 유연성을 갖춘 소프트웨어를 만들기 위한 5가지 설계 원칙

원칙이름설명

원칙 이름 설명
SRP 단일 책임 원칙 하나의 클래스는 하나의 책임만 가져야 한다
OCP 개방-폐쇄 원칙 확장에는 열려 있고, 변경에는 닫혀 있어야 한다
LSP 리스코프 치환 원칙 부모 타입은 자식 타입으로 대체 가능해야 한다
ISP 인터페이스 분리 원칙 하나의 범용 인터페이스보단, 여러 개의 작은 인터페이스가 낫다
DIP 의존관계 역전 원칙 구체적인 구현보다 추상화에 의존해야 한다

1️⃣ SRP - 단일 책임 원칙

하나의 클래스는 오직 하나의 책임만 가져야 한다.

더보기

🚫 위반 예시

public class User {
    public void login() { /* 로그인 */ }
    public void saveUser() { /* DB 저장 */ }
}

 

적용 예시

public class User { /* 사용자 정보 */ }

public class AuthService {
    public void login(User user) { ... }
}

public class UserRepository {
    public void saveUser(User user) { ... }
}

2️⃣ OCP - 개방/폐쇄 원칙

소프트웨어 요소는 확장에 열려 있고, 변경에는 닫혀 있어야 한다

더보기

🚫 위반 예시

public double calculate(Shape shape) {
    if (shape.type.equals("circle")) ...
}

 

 적용 예시

public interface Shape {
    double calculateArea();
}

public class Circle implements Shape {
    public double calculateArea() { ... }
}

3️⃣  LSP - 리스코프 치환 원칙

더보기

🚫 위반 예시

class ElectricCar extends Car {
    @Override
    public void accelerate() {
        throw new UnsupportedOperationException();
    }
}

 

 적용 예시

interface Acceleratable { void accelerate(); }

class Car implements Acceleratable { ... }
class ElectricCar implements Acceleratable { ... }

 

4️⃣ ISP - 인터페이스 분리 원칙

불필요한 메서드에 의존하지 않도록, 인터페이스를 작게 분리해야 한다.

더보기

🚫 위반 예시

interface Animal {
    void fly(); void run(); void swim();
}

 

 적용 예시

interface Runnable { void run(); }
interface Swimmable { void swim(); }

class Dog implements Runnable, Swimmable { ... }

5. DIP - 의존관계 역전 원칙

더보기

🚫 위반 예시

class NotificationService {
    private EmailNotifier emailNotifier = new EmailNotifier();
}

 

 적용 예시

interface Notifier { void send(String msg); }

class EmailNotifier implements Notifier { ... }
class SMSNotifier implements Notifier { ... }

class NotificationService {
    private final Notifier notifier;
    public NotificationService(Notifier notifier) {
        this.notifier = notifier;
    }
}

🍃  SOLID만으로 부족하다? → Spring의 역할

다형성으로는 OCP, DIP를 완벽하게 구현하기 어렵다.

이때 등장한 것이 바로 Spring Framework


🌱 Spring과 객체 지향 설계

1️⃣ Spring의 등장 배경

  • OCP, DIP를 직접 구현하려면 설정과 객체 관리가 너무 많아진다.
  • 그래서 Spring이 등장

2️⃣ Spring의 역할

Spring  기능설명
IoC 객체의 제어권을 개발자가 아닌 Spring이 가지도록
DI 필요한 의존성을 자동으로 주입 (의존 관계 관리)
Bean 관리 객체 생성, 주입, 소멸 등 생명주기를 관리

 


☕ Spring Container와 Bean

3️⃣ Spring Container

  • BeanFactory: 가장 기본적인 컨테이너
  • ApplicationContext: 실무에서 주로 사용하는 확장형 컨테이너

일반적으로 Spring Container = ApplicationContext


4️⃣ Spring Bean

  • Spring Container가 관리하는 객체
  • 대부분 Singleton으로 생성됨

5️⃣ Bean 등록 방법

 

방법 설명
XML <bean> 태그로 등록
Annotation @Component, @Service, @Repository, @Controller 등
Java Config @Configuration, @Bean 메서드 사용