참고
좋은 객체 지향 프로그래밍이란?
NOTE
컴퓨터 프로그램을 명령어 목록이 아닌 여러 개의 독립된 단위인 객체들의 모임으로 파악하자!
•
각각의 객체는 메시지를 주고 받고 데이터를 처리할 수 있다. (협력)
•
객체 지향 프로그래밍은 프로그램을 유연하고 변경이 용이하게 만들기 때문에 대규모 프로젝트에서 사용함!
•
유연하고 변경이 용이하다는 의미?
◦
레고 블럭을 조립하듯이, 부품을 갈아 끼우듯이 컴포넌트를 쉽고 유연하게 개발할 수 있다는 뜻이다.
•
객체 지향 특징
◦
추상화
◦
캡슐화
◦
상속
◦
다형성
다형성의 특징
NOTE
다형성 ⇒ 역할과, 구현으로 세상을 구분하여 예시를 들어보자!
역할(인터페이스) ⇒ 자동차
구현(구현체) ⇒ k3, 아반떼, 테슬라
역할(인터페이스) ⇒ 로미오 / 줄리엣
구현(구현체) ⇒ 장동건, 원빈 / 김태희, 송혜교
•
이렇게 역할과 구현으로 구분하면 세상이 단순해지고 유연해지며 변경도 편리해진다.
◦
클라이언트는 대상의 역할(인터페이스)만 알면된다.
◦
클라이언트는 대상의 내부 구조를 몰라도 된다.
◦
클라이언트는 구현 대상의 내부 구조가 변경되어도 영향을 받지 않는다.
◦
클라이언트는 구현 대상 자체를 변경해도 영향을 받지 않는다.
MemberRepository를 다른 구현체로 바꾸어도 사용에 문제가 없음..
public class MemberService {
// private MemberRepository memberRepository = new MemoryMemberRepository();
private MemberRepository memberRepository = new JdbcMemberRepository();
}
Java
복사
구현체가 바뀌어도, 인터페이스의 save()를 호출하는데 지장없다.
•
실제 동작하는 로직은 구현체에 맞게 오버라이딩된 메서드이며, 클래스는 인터페이스를 구현한것이므로 유연하게 객체를 변경할 수 있다.
⇒ 즉 다형성의 본질은, 인터페이스를 구현한 객체 인스턴스를 실행 시점에 유연하게 변경할 수 있다는 점!
좋은 객체 지향 설계의 5가지 원칙(SOLID)
NOTE
클린코드로 유명한 로버트 마틴이 정리한 5가지 원칙!
•
SRR : 단일 책임 원칙
•
OCP : 개방 폐쇄 원칙
•
LSP : 리스코프 치환 원칙
•
ISP : 인터페이스 분리 원칙
•
DIP : 의존관계 역전 원칙
•
5원칙을 관통하는 것은 ‘다형성’ 이다.
◦
하지만 다형성 만으로는 쉽게 부품을 갈아 끼우듯 개발할 수 없다
SRP(Single Responsibility Principle) - 단일 책임 원칙
NOTE
하나의 클래스는 하나의 책임만 가져야 한다
클래스는 오직 하나의 책임만!
•
하나의 책임을 구분하는 기준은 변경이다.
•
변경이 있을 때 파급효과가 적으면 SRP를 잘 따른것이다.
OCP(Open Closed Principle) - 개방 폐쇄 원칙
NOTE
클래스는 확장에는 개방적이고, 변경에는 폐쇄적이어야 한다!
자르는 기능 → 색칠하는 기능 (변경)
자르는 기능 → 자르고 색칠하는 기능 (확장)
LSP(Liskov Subsitution Principle) - 리스코프 치환 원칙
NOTE
프로그램의 객체는 프로그램의 정확성을 깨드리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다
Shape가 다른 Frame, Rectangle, Circle등으로 변경할 수 있어야 한다.
•
자식 클래스가 부모클래스의 기능을 똑같이 수행할 수 없을때, 버그를 발생시킨다!
•
EX) 자동차 인터페이스가 있다. 구현체A 자동차는 전진 기능을 제공하는 ‘엑셀 메서드’를
구현해야 한다
◦
엑셀 메서드를 호출하면 +10을 구현해야하는데 -10을 구현함
◦
이것은 LSP를 위반한 것 ( 엑셀은 ‘전진 기능’을 제공해야 하기 때문 )
◦
단순 컴파일에서 성공하는 것을 넘어서는 이야기(메소드의 존재 의미에 맞게 구현)
ISP(Interface Segregation Principle) - 인터페이스 분리 원칙
NOTE
특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다
•
자동차 인터페이스 하나만 있으면, 하나의 큰 덩어리가 된다
•
자동차 인터페이스를 운전, 정비 인터페이스로 분리하면 정비와 운전이 서로 분리되고
서로 영향을 끼치지 않는다
•
인터페이스도 적당한 규모로 쪼개는것이 좋다는 것
DIP(Dependency inversion Principle) - 의존관계 역전 원칙
NOTE
프로그래머는 추상화에 의존해야지, 구체화에 의존해서는 안된다.
•
의존성 주입은 이 원칙을 따르는 방법 중 하나이다.
•
구현 클래스에 의존하지 않고, 인터페이스에 의존하라는 의미. (역할에 의존해라)
객체 지향 설계와 스프링
NOTE
•
스프링 이야기에 왜 객체지향 원칙이 나오는가?
◦
스프링은 다음 기술로 다형성, OCP, DIP를 가능하게 지원하기 때문
▪
‘DI’ : 의존 관계, 의존성 주입
▪
‘DI 컨테이너’ 제공
◦
클라이언트 코드의 변경 없이 기능을 확장할 수 있다. 쉽게 부품을 교체하듯이 개발할 수
있게 도와준다.
•
[정리] 모든 설계에 역할과 구현을 분리하자
◦
이상적으로는 모든 설계에 인터페이스를 부여하는것이 좋다
◦
하지만 인터페이스를 도입하면 추상화라는 비용이 발생한다
◦
기능을 확장할 가능성이 없다면, 구체 클래스를 직접 사용하고 향후 꼭 필요할 때 리팩토링해서 인터페이스를 도입하는 것도 방법이다.