스프링은 객체지향의 언어의 특징을 잘 살려준다고 했는데 ? 그럼 좋은 객체지향 프로그래밍은 뭘까 ?
추상화 : 기능을 간추려서 나타내는 것
캡슐화 : 내부정보를 감추는 것
상속 : 부모의 특징을 자식이 물려받는 것
다형성 : 참조형 타입에 다양한 객체 타입이 올 수 있는 것 ( 실행시점에서 유연하게 객체 변경이 가능 )
개인적으로는 다향성이 정말 좋은 특징라고 생각한다 !
역할과 구현으로 구분하면 → 세상 단순, 유연해짐
자바에서 적용하면
객체하면 빠질수 없는 5대 설계 원칙
그냥 알아두자
SRP : 단일 책임 원칙
OCP : 계방 폐쇠 원칙
LSP : 리스코프 치환 원칙
ISP : 인터페이스 분리 원칙
DIP : 의존관계 역전 원칙
이제는 스프링에서 어떻게 객체 지향 설계를 할지 알아보자
스프링은 다형성 + OCP + DIP등을 가능하게 지원합니다
어떻게 ?
DI, DI 컨테이너 제공, IOC, 코드 변경없이 확장이 가능 등등
참고) DI : https://velog.io/@jijongkwon/DI-Dependency-Injection
예를 들어보자
정책이나, 어떤 레포지토리가 올 지 아직 결정을 못한 상태입니다
그런데 이런 상태에서 DI가 있다면 ?
-> DI를 통해 외부에서 의존성을 주입 받고
-> 실행 시점에서 동적으로 객체를 주입할 수 있으니?
= 유연해지겠죠 ?
이 컨테이너가 또 객체지향을 잘 활용해서 사용합니다
이게 뭐냐 -> 의존관계 주입해주고, 객체를 생성 관리해주는 역할
-> 알아서 관리해 주니 구현시 신경 쓸 필요가 없습니다 ~
이 컨테이너는 또 싱글톤으로 객체를 관리합니다
트래픽이 많을 때 객체를 계속 생성한다면 ? -> 메모리가 엄청 낭비 되겠죠 ?
그래서 하나의 싱글톤 객체를 만들면 -> 객체를 공유하기 때문에 메모리를 아낄 수 있습니다.
public class SingleTonService {
// 딱 하나의 객체 생성
private static final SingleTonService instance = new SingleTonService();
// 객체 조회
public static SingleTonService getInstance(){
return instance;
}
// 생성자를 private 함으로써 객체 생성을 막음
private SingleTonService(){
}
public void logic(){
System.out.println("싱글톤 객체 로직 호출");
}
}
위에는 싱글톤을 어떻게 사용하는지 예시입니다.
근데 하나만 사용하면 단점이 있겠죠 ?
단점
하지만 스프링 컨테이너는 빈을 다 싱글톤으로 관리하는데 위와 같은 단점들을 보완시킵니다.
어떻게 ?
프록시(Proxy) 패턴: 싱글톤 빈에 프록시를 적용하여 실제 객체 대신 프록시를 주입 -> 이렇게 하면 스레드마다 독립적인 객체를 사용가능
ThreadLocal 사용: ThreadLocal을 사용하면 동일한 인스턴스에 대해 스레드별로 격리된 상태를 유지
빈 초기화 메서드(@PostConstruct): 빈 초기화 시점에 객체의 상태를 초기화
등등 싱글톤에 단점을 보완할 수 있다 !!!