일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- JPA
- 임팩트커리어스터디
- 스프링컨테이너
- til
- 노개북
- 노마드코더
- Machine Learing
- 인텔리제이
- spring
- 스프링프레임워크
- 객체지향특징
- IntelliJ
- 개발필독서
- 인공신경망
- 클린코드
- valid
- 북클럽
- REST API
- 머신러닝
- 북스터디
- NullCheck
- requestbody
- 스프링어노테이션
- springboot
- 개발서적
- Deep Learning
- Dao
- 딥러닝
- mysql
- 스프링스터디
Archives
- Today
- Total
dev.jaieve 공부기록
[Spring] 다형성과 SOLID 본문
1. 다형성(polymorphism)
- 실제 세상을 비유로 들었을 때, 세상은 역할과 구현으로 구분할 수 있다.
- 키보드라는 개념과 다양한 모델들, 마우스라는 개념과 다양한 제품 모델들 과 같은 세상의 표준 인터페이스들
- 공연 무대 남주 및 여주(역할)에 더블캐스팅된 배우들(구현)
- 운전자(역할)와 자동차(역할). 그리고 다양한 자동차 모델(구현)
a. 다형성 장점
- 프로그램을 사용하는 클라이언트는 대상의 역할만 알면된다.
- 클라이언트는 구현 대상의 내부 구조를 몰라도 된다.
- 클라이언트는 구현 대상의 내부 구조가 변경되어도 영향을 받지 않는다.
- 클라이언트는 구현 대상 자체를 변경해도 영향을 받지 않는다.
b. 객체지향언어인 자바의 다형성
- 역할 = Interface / 구현 = 구현객체(Class implements Interface)
- 객체를 설계할 때부터 역할과 구현을 명확히 분리하고, 역할을 먼저 부여한 다음, 그 역할을 수행하는 구현객체를 만든다.
c. @Overriding in java
- 다형성 개념을 이용하여 인터페이스를 구현한 객체는 실행 시점에서 유연하게 제 2의 구현객체로 변경할 수 있다.
- 다형성의 본질은 클라이언트를 변경하지 않고, 서버의 구현기능을 유연하게 변경할 수 있는 것이다.
d. 한계
- 역할(interface)가 변하면 클라이언트, 서버 모두에 큰 변경이 발생하기 때문에 인터페이스를 안정적으로 잘 설계하는 것이 중요하다.
2. 좋은 객체 지향 설계의 5가지 원칙 SOLID
SRP
- 한 클래스는 하나의 책임만 가져야 한다.
- 하나의 책임이라는 것은 모호해서, 클 수도 있고, 작을 수도 있다. 문맥과 상황에 따라 정의가 달라진다.
- 중요한 기준은 변경이다. 변경이 있을 때 파급 효과가 적으면 책임이 분명해지기 때문에, 변경에 의한 연쇄작용에서 자유로워질 수 있다.
- ex. UI변경, 객체의 생성과 사용을 분리
OCP
- 소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다.
- 다형성을 활용하면 역할(인터페이스)를 구현한 새로운 클래스(구현체)를 만들어 새로운 기능을 구현할 수 있다.
- 변경을 위한 비용은 가능한 줄이고, 확장을 위한 비용은 가능한 극대화해야 한다.
- 요구사항의 변경이나 추가사항이 발생하더라도, 기존 구성요소에는 수정이 일어나지 않고, 기존 구성요소를 쉽게 확장해서 재사용한다.
클린코드를 읽고 공부하며 정리했던 예제코드
class PaymentController {
@RequestMapping(value="/api/payment", method=RequestMethod.POST)
public void pay(@RequestBody ShinhanCardDto.PaymentRequest req) {
shinhanCardPaymentService.pay(req);
}
}
class ShinhanCardPaymentService {
public void pay(ShinhanCardDto.PaymentRequest req){
shinhanCardApi.pay(req);
}
}
새로운 카드사가 추가된다면?
class PaymentController {
@RequestMapping(value="/api/payment", method=RequestMethod.POST)
public void pay(@RequestBody CardPaymentDto.PaymentRequest req) {
if(req.getType() == CardType.SHINHAN){
shinhanCardPaymentService.pay(req);
} else if(req.getType() == CardType.WOORI) {
wooriCardPaymentService.pay(req);
}
}
}
이 예제코드는 확장에 유연하지 않은 코드이다. 다음과 같이 바꾸면 OCP 원칙을 지키게 된다.
public interfaceCardPaymentService{
void pay(CardPaymentDto.PaymentRequest req));
}
class PaymentController {
public void pay(@RequestBody CardPaymentDto.PaymentRequest req){
finalCardPaymentServicecardPaymentService =
cardPaymentFactory.getType(req.getType());
cardPaymentService.pay(req);
}
}
class ShinhanCardPaymentService implementsCardPaymentService{
@Override
public void pay(CardPaymentDto.PaymentRequest req){
shinhanCardApi.pay(req);
}
}
LSP(리스코프 치환 원칙)
- 프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다.
- 다형성에서 하위 클래스는 인터페이스 규약(접근제한자, 예외 포함)을 다 지켜야 한다. 이러한 다형성의 원칙은 인터페이스 구현체를 믿고 사용하기 위해서 필요하다.
- ex. 자동차 인터페이스의 엑셀 기능은 앞으로 가는 것인게 구현체에서 뒤로 간다면 LSP 위반!
ISP
- 특정 클라이언트를 위한 인터페이스 여러개가 범용 인터페이스 하나보다 낫다.
- 자동차 인터페이스 → 운전 인터페이스, 정비 인터페이스로 분리
- CarRepository → DriveService, RepairService
- 사용자 클라이언트 → 운전자 클라이언트, 정비사 클라이언트로 분리
- UserService → DriverService, RepairService
- 인터페이스를 여러개로 나누면 명확해지고, 대체 가능성이 높아진다.
DIP
- “추상화에 의존해야지, 구체화에 의존하면 안된다”는 원칙을 따르기 위해 의존성 주입을 활용한다. 즉, 구현 클래스에 의존하지 말고 인터페이스에 의존하라는 뜻이다.
- 객체 세상은 클라이언트가 인터페이스에 의존해야 유연하게 구현체를 변경할 수 있다.1. 다형성(polymorphism)1. 다형성(polymorphism)1. 다형성(polymorphism)
3. 객체 지향 설계와 스프링
스프링은 DI컨테이너를 제공함으로써 다형성 + OCP, DIP를 가능하게 만들어준다. 덕분에 클라이언트 코드의 변경없이 기능 확장, 쉽게 부품을 교체하듯이 개발이 가능하다.
스프링의 진짜 핵심은
- 스프링은 자바 언어 기반의 프레임워크이다.
- 자바 언어의 가장 큰 특징 객체지향언어
- 스프링은 객체지향언어가 가진 강력한 특징을 살려내는 프레임워크
- 스프링은 좋은 객체지향 애플리케이션을 개발할 수 있게 도와주는 프레임워크
반응형
'Back > Springboot' 카테고리의 다른 글
[Springboot] 갑자기 발생한 dependency error (0) | 2022.03.22 |
---|---|
[Spring] 스프링 stereotype 어노테이션 (0) | 2022.02.20 |
[Spring] 스프링 컨테이너란? (0) | 2022.02.19 |
[SpringBoot] API 개발시 @RequestBody 객체 와 @Valid 어노테이션 (0) | 2021.07.24 |
[SpringBoot/Java] JSP를 하다가 JPA를 처음 접하면서 생긴 의문 - JPA의 DTO와 JSP의 DAO의 차이점 (0) | 2021.07.24 |