[스프링 핵심 원리]객체 지향 설계 & 스프링
본 리뷰는 인프런 김영한씨의 스프링 핵심원리 - 기본편 리뷰를 한 포스팅입니다.
목차
- 객체 지향 프로그래밍
- 스프링과 객체 지향
- 좋은 객체지향 원칙 SOLID
1. 객체 지향 프로그래밍 (Object-oriented programming)
객체 지향 프로그래밍은 컴퓨터 프로그램을 명령어의 목록으로 보는 시각에서 벗어나 여러 개의 독립된 단위, 즉 "객체"들의 모임으로 파악하고자 하는 것이다. 각각의 객체는 메시지 를 주고받고, 데이터를 처리할 수 있다. (협력)
객체 지향 프로그래밍은 프로그램을 유연하고 변경이 용이하게 만들기 때문에 대규모 소프 트웨어 개발에 많이 사용된다.
- 추상화 (Abstract)
-. 핵심적인 코드만 보여줌.
-. 불필요한 부분을 숨김.
-. 인터페이스와 구현을 분리함.
- 캡슐화 (Capsulation)
-. 데이터를 보호.
-. 필드와 메서드를 하나로 묶음.
-. 객체의 세부적인 내용이 외부로 드러나지 않기때문에, 외부에서 데이터를 접근하는 것을 방지한다.
- 상속 (Inheritance)
-. 코드의 재사용
-. 자식 클래스가 부모 클래스의 특징을 상속받는 것.
-. 상속을 받기때문에 중복적인 코드를 줄일 수 있음.
-. 부모클래스의 수정을 통하여 자식클래스 또한 수정이되는 효과를 가짐.
- 다형성 (Polymorphism)
-. 객체 변형이 용이함.
-. 어떠한 변수나 메서드가 상황에 따라서 다른 결과물을 출력하는 것.
-. 다형성이 가능하게하는 2가지
☝️오버라이딩: 부모클래스 메서드를 자식클래스에서 재정의하는 것.
오버라이딩의 경우에 인터페이스의 save를 호출하였을때, 두개의 Repository에서 실행 시점에 주석이나 기능을 통하여 인터페이스를 구현한 객체를 유연하게 변경할 수 있다.
✌️오버로딩: 한 클래스 내에서 이름은 같지만 Param의 개수나 자료형을 다르게하여 서로 다른 동작을 진행하는 것.
다형성을 비유를 했을때,
운전자는 어떠한 자동차를 타더라도 운전을 할 수 있다.
그리고, 로미오의 역할을 만약 장동건이 한다고하면 줄리엣이 누구던지 로미오의 역할만 충실하면 되기때문에 영향을 끼치지 않는다.
이렇듯 역할과 구현을 분리하여 프로그래밍을 하면된다.
이렇듯 다형성은 역할과 구현을 분리하여 편리한 컨셉을 다형성을 통해 객체의 변경을 유연하고 용이하게 확장을 한 설계이기때문에 클라이언트에 영향을 주지않으면서 개발을 진행할 수 있다.
하지만 모든 객체를 인터페이스화한다면 만약 자동차를 비행기로 대체해야한다면 자동차의 attributes와 비행기의 attributes가 다르게 동작하기 때문에 코드를 갈아 엎어야하는 단점을 가질 수 있다.
2. 스프링과 객체 지향
- 스프링에서는 제어의 역전(IoC), 의존관계 주입(DI)은 객체지향의 성질인 다형성을 활용하여 역할과 구현을 편리하게 다룰 수 있도록 도와주는 프레임워크이다.
- 인터페이스와 레포지토리, 그리고 서비스등을 따로두어 레고를 조립하듯이 조립을하여 완성된 하나의 코드로 조립을 할 수 있다. 마치 공연 무대를 선택하는 것처럼 !
- 클라이언트 코드의 변경이 필요없이 기능 확장을 구현하는데에 용이하다.
3. 좋은 객체지향 원리 SOLID
- SRP: Single Responsibility Principle
단일 책임 원칙
-. 한 클래스에는 책임을 가져야 한다. 이때, 책임의 중요한 기준은 변경이며 파급 효과가 적으면 단일 책임 원칙을 잘 따르는 것이다.
예를 들어서 UI를 변경하는데에 있어서 불필요한 코드변경이 일어나면 안되기때문이다.
- OCP: Open/Closed Principle
개방-페쇄 원칙
-. 소프트웨어 요소는 확장에는 열려있으나 변경에는 닫혀있어야한다.
-. 인터페이스를 구현한 새로운 클래스를 하나 만들어서 새로운 기능을 구현해야한다.
-. 이 그림을 보면 인터페이스에서 기능을 호출하는데에 있어서 Memory와 Jdbc두가지를 호출할 수 있지만 기존에 있는 코드들을 변경하는 것이 아니기때문에 확장에는 열려있고 변경에는 닫혀있다는 것을 확인할 수 있다. (코드를 변경할 때, 객체를 생성하고, 연관관계를 맺어주는 별도의 조립을 시켜주는 설정자가 있는경우)
-.
- LSP: Liskov Substitution Principle
리스코프 치환 원칙
-. 프로그래밍의 정확성을 깨뜨리지 않으면서 하위 인스턴스로 바꿀 수 있어야한다.
-. 단순히 컴파일을 성공하는 것이 아닌 구현을 명확히 해야한다.
-. 예를들어서 계단을 오르는 코드가 있을 경우 + val이 필요한데 -val이 들어가게된다면 계단을 내려가기때문에 리스코프 치환 원칙에 위배되는 코딩이 될 수 있다.
- ISP: Interface Segregation Principle
인터페이스 분리 원칙
-. 특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다.
-. 많은 인터페이스분리는 인터페이스가 명확해지고, 대체 가능성을 높아지게 한다.
-. 예를들어
자동차 인터페이스 -> 운전 인터페이스, 정비 인터페이스 분리
사용자 클라이언트 -> 운전자 클라이언트, 정비사 클라이언트 분리
- DIP: Depencdency Inversion Principle
의존관계 역전 원칙
-. 클라이언트 코드가 구현 클래스에 의존하지말고, 인터페이스에 의존하라는 것이다.
-. 앞서 이야기한 역할에 의존하라는 것.
운전자는 자동차 역할에 대해서 알아야 운전을 할 수 있는 것이지, 자동차의 종류(K3, 아반떼 등)의 특성까지 알아야 운전이 가능하지는 않다. 이는 역할에 의존을 해야하는 것이지 구현에 의존을 하지말아야한다는 것이다.