좋은 객체지향이란?
- 객체 지향 특징
- 추상화, 캡슐화, 상속, 다형성
- 프로그램을, 객체들의 모임으로 파악하고자 하는것. 각각의 객체는 메시지를 주고받고 데이터를 처리하는것.(협력) 유연하고 변경이 용이하기 때문에 대규모개발에서 많이사용
- 유연하다?
- 레고블럭 조립하듯이
- 컴포넌트를 쉽고 유연하게 변경하면서 개발할 수 있는 방법이라는 뜻
- 이를 다형성이라고 부름(Polymorphism)
- 다형성
- 역할과 구현으로 세상을 구분하는식으로 비유해보자
- 예시1) 운전자-자동차
- 운전자라는 역할, 자동차라는 역할이 있음
- 자동차 구현으로 k3, 아반테, 테슬라모델3를 제작
- 자동차 역할을 3개의 다른자동차들로 구현을 함
- k3를 운전자가 타다가 아반떼로 차를 바꾼다하더라도 운전을 할 수 있음. 어차피 자동차로서의 역할은 똑같이 가졌기때문에 운전자에게 어떠한 영향도 미치지 않음
- 왜 이게 가능하냐면, 자동차 역할 interface에 따라서 자동차를 만들었음. 운전자는 자동차 interface에만 의존해있기때문에 상관없음.
- 왜 이렇게 개발했냐면, 운전자를 위해서임. 운전자가 각기 다른 자동차에 대해 알필요없도록 하기 위해서임. 자동차 역할만 지키도록한다면 어떤차가 나와도 운전자는 계속 운전할 수 있기때문에, 자동차 시장은 무한히 확장할 수 있음. 대상을 바꾸지 않고 자동차를 출시할 수 있음
- 클라이언트에게 영향을 주지않고 새로운 기능을 제공할 수 있음.
- 역할과 구현으로 세상을 구분했기때문에 가능한것.
- 클라이언트는 새로운걸 배울 필요가 업슴
- 예시2) 공연무대
- 로미오 역할과 줄리엣 역할이 있음
- 배우는 누구든지 상관없음. 만약 주배우들이 다 몸이 아프다? 무명배우로라도 대체가 가능한것임
- 어떻게는 공연은 굴러갈 수 있음. 이게 바로 유연성, 대체가능성임
- 역할과 구현으로 구분하면 세상이 단순, 유연해지고, 변경도 편리
- 클라이언트는 인터페이스만 알면됨. 내부구조를 몰라도됨. 내부구조가 바뀌어도 영향을 받지 않는다. 구현 대상 자체를 변경해도 영향을 받지 않음.
- 자바언어의 다형성을 스프링은 활용함.
- 역할 = 인터페이스
- 구현 = 인터페이스를 구현한 클래스, 구현객체
- 객체 설계시 인터페이스를 먼저 부여하고, 그 역할 수행하는 구현 객체 만들기
- (상속으로도 가능하긴한데 단일상속만 가능하고 별로니까 인터페이스가 좋음)
- 객체의 협력이라는 관계를 생각해야함
- 혼자있는 객체는 없음
- 클라 - 요청, 서버-응답
- 수많은 객체 클라와 객체서버는 협력 관계를 가짐
- 크게 보면 서버와 시스템끼리로도 생각가능
- 자바 언어의 다형성
- 오버라이딩 - 기능을 넘어서 타버린다.(재정의)
- 오버로딩 - 여러개 많이 초과해서 로딩했다.(메소드 여러개)
- 오버라이딩된 메서드가 실행됨
- 다형성의 본질
- 인터페이스를 구현한 객체 인스턴스를 실행 시점에 유연하게 변경 가능
- 클라를 변경하지않고, 서버 구현기능을 유연하게 변경
- 정리
클라를 변경하지 않고 서버 구현기능을 변경하면서 유연하게 대처가 가능하므로, interface를 잘짜는게 중요 - 한계
- 역할 자체가 변하면 클라 서버 모두에게 큰 변경 발생
- 인터페이스를 안정적으로 잘 설계하는게 진짜진짜 중요
- 스프링과 객체 지향
- 객체 지향의 꽃은 다형성
- 다형성이 진짜 중요
- 스프링은 다형성을 극대화해서 이용할수있게 해줌
- ioc, di는 다형성을 활용해서 역할 구현을 편리하게 다룰 수 있도록 지원
- 근데 제대로 이해하려면 다형성말고, SOLID도 잘 알아야함. 중요중요!!! (이거 면접에 많이 나온대)
SOLID 원칙이란?
- SRP 단일 책임 원칙
- Single Responsibility Principle
- 한 클래스는 하나의 책임만
- 모호하긴 한데, 변경이 있을때 파급효과가 적으면 단일 책임 원칙을 잘 따른것.
- OCP 개방-폐쇄 원칙
- OpenClosed Principle
- 소프트웨어 요소는 확장에는 열려있으나 변경에는 닫혀있다
- 다형성을 생각하면서 이해하면됨.
- 전에 예시로 얘기했던 Memory하고 Jdbc MemberRepository 그거 보면 클라이언트쪽에서 코드를 변경함. 그러므로 걔는 다형성을 사용했지만 OCP원칙을 지킬 수 없다. 이걸 해결하려면 객체를 생성하고, 연관관계 맺어주는 별도의 조립/설정자가 필요(나중에 배울거임 Di로)
- LSP 리스코프 치환 원칙
- Liskov substitution principle
- 프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서, 하위 타입의 인스턴스로 바꿀 수 있어야한다. (정확성이라는게 그냥 컴파일이 되는것을 얘기하지 않음.)
- 다형성에서 하위클래스는 인터페이스 규약을 다 지켜야한다는것
- 예시) 자동차 인터페이스의 엑셀은 앞으로 가라는 기능임. 만약 이걸 뒤로 가게 구현한다면 LSP를 위반하는것
- ISP 인터페이스 분리 원칙
- Interface Segregation Principle
- 특정 클라이언트를 위한 인터페이스 여러개 > 범용 인터페이스 하나
- (전에 클린코드에서 얘기한거같은 느낌)
- 적당한 크기로 인터페이스를 쪼개는게 좋다는것.
- 명확해지고, 대체 가능성이 높아짐(고치는게 편해지니까)
- DIP 의존관계 역전 원칙
- 추상화에 의존해야지, 구체화에 의존하면 안됨.
- 클라이언트 코드가 실제 구현 클래스말고 인터페이스를 바라봐야한다는 말임.(전에 다형성, 역할기능분리랑 같은 얘기임)
- 아까 얘기했던 memberRepository가 DIP도 위배함. memberRepository에 클라가 잘 의존중인데, memberRepository에 MemoryMemberRepository를 선언함. 그러니까 결국 클라코드는 구현체도 알고있게되는거임. 즉, 의존중인거
- 이것도 고치는방법 다음에 배움
- 다형성을 지킨다고 OCP, DIP까지 지켜진다는 보장 없음.
'WEB > Spring' 카테고리의 다른 글
Spring MVC 패턴 [TIL] (0) | 2022.04.14 |
---|