OOP
- 객체?
- 현실 세계의 실체를 모델링한 것 (차, 사람 등)
- “변수”와 변수를 조작하는 “메서드”로 이루어져 있음
- 자신 고유의 속성을 가지는 물리적, 추상적인 모든 것
- 객체지향 프로그래밍?
- 현실 세계를 모델링하고 그 모델을 사용하여 소프트웨어를 개발하는 방법론
- 객체를 중심으로 데이터(변수)와 기능(메서드)를 함께 통합하여 관리함
- 장점?
- 코드의 재사용성과 유지보수성 향상
- 상속을 통한 코드 재사용성 증가
- 캡슐화를 통한 유지보수 향상
- 생산성 향상
- 현실을 모델링하여 잘 설계한 독립적인 객체를 활용하므로 현실의 객체에 대해서 생각하고 있는 것을 자연스럽게 구현
- 단점?
- 개발 속도가 느림
- 객체가 처리하려는 것에 대한 정확한 이해가 필요
- 설계단계에서 시간이 추가적으로 소모
- 실행 속도가 느림
- 객체지향 언어(Java, Kotlin, Python 등)는 대체로 실행 속도가 느린 편에 속함
- C++의 경우 실행 속도는 빠른 편이나 Java와 달리 다중 상속을 허용하기 때문에 구조가 복잡해져 코딩 난이도가 폭등할 수 있음
- 클래스?
- 객체는 클래스의 인스턴스
- 인스턴스란? 클래스에 소속된 개별적인 객체
- 인터페이스
- 추상적인 메서드의 집합을 정의한 것으로, 구체적인 구현을 사용자가 직접 해야 함
- 클래스는 인터페이스를 구현(implements)하기 위해 인터페이스 내부에 정의된 메서드를 구현해야 한다.
- 인터페이스는 인스턴스화 할 수 없기에 생성자를 가질 수 없다.
- 추상화
- 현실의 문제를 해결하는 것은 복잡한 일
- 복잡한 현실의 개념을 단순화하고 중요한 부분만 추상적으로 저장
- 클래스와 객체는 추상화를 통해 현실의 어려운 개념을 보다 쉽게 모델링
- 캡슐화
- 변수와 메서드를 하나의 단위로 묶음
- 접근 제어자(private, protected, public 등)을 통해 클래스 외부에서의 접근에 제약을 줄 수 있음
- 변수에 대한 접근을 제한하는 것을 통해 데이터 무결성 유지
- 상속
- 부모 클래스의 변수와 메서드(속성)을 물려 받는 자식 클래스를 생성
- 자식은 부모 클래스의 변수를 활용하고 메서드를 오버라이딩하여 사용하거나, 신규 기능을 추가하는 등 확장(extends)
- 오버라이딩?
- 자식 클래스에서 부모 클래스의 메서드를 재정의하는 것
- 오버로딩?
- 클래스 내부 같은 이름을 가진 메서드가 있더라도 매개변수의 개수 또는 타입이 다르면 메서드명 중복을 허용하는 것
OOP 5원칙
- SRP: 단일 책임 원칙 (Single Responsibility)
- 클래스는 오직 하나의 책임(reason to change)만을 가진다.
- 책임이란? 클래스의 계약 및 의무
- 책임이 많아진다 = 변화의 가능성이 높아진다 = 버그가 많아진다 = 다른 클래스에도 영향을 끼친다
- OCP: 개방 폐쇄 원칙 (Open Close)
- 확장에는 열려있고 수정에는 닫혀 있다.
- 인터페이스를 활용(implement)하여 추상화로 실현한다.
- 물론 과한 추상화 및 OCP는 복잡함을 야기한다. 집착 말고 비용 등을 고려하며 유연하게 생각할 것
- LSP: 리스코프 치환 원칙 (Liskov Substitution)
- Subtype(하위클래스)은 Basetype(부모클래스)을 대체할 수 있어야 한다.
- 상속 사용 여부를 결정할 때 확인해야 할 규칙
- Queue는 List를 상속받는다고 해도 자료구조 본질적인 특성상 List와 모든 기능을 동일하게 수행하지 않기에 바람직하지 않음 → LSP 위반
- ISP: 인터페이스 분리 원칙 (Interface Segregation)
- 사용하지 않는 메서드에 의존하는 것을 강요해서는 안 된다.
- 서로 다른 클라이언트에 대한 기능을 하나의 인터페이스에 모두 우겨넣으면 클라이언트 간에 불필요한 의존성이 발생하기 때문
- DIP: 의존성 역전 원칙 (Dependency Inversion)
- 높은 수준의 모듈(interface)은 낮은 수준의 모듈(implementation)에 의존해서는 안 된다. 모두 추상화에 의존해야 한다.
- 추상화는 구체화에 의존하면 안 된다.
- 추상적이지만 스프링에서 가장 중요한 규칙
→ SOLID 설계 원칙을 통해 의존성을 관리하고 유지보수성, 유연성, 재사용성을 강화
→ 다만 반드시 지켜야 하는 것은 아니기에 규칙에 너무 목맬 필요는 없다.
Springboot
- Java Web Framework Spring을 편리하게 사용할 수 있게 돕는 서브 프로젝트
- 다양한 계층으로 구성되어 있고 모듈화를 지원하여 대형 서비스에 안정적
- 객체지향에 부합하는 설계와 그렇지 않은 설계의 차이가 선명하게 드러나는 프레임워크
- 진입장벽도 높고, 학습 깊이도 깊은 결코 쉽지 않은 백엔드 프레임워크
- 다른 사람들의 도움이 정말 필요함 (질문과 코드리뷰 등)
Springboot 주요 계층
- Domain Model: 도메인 데이터와 비즈니스 로직을 포함
- 도메인: 객체의 속성들이 가질 수 있는 값들의 집합
- 비즈니스 로직이란?
- 프로그램에서 규칙에 따라 데이터를 생성·표시·저장·변경하는 부분
- Repository: DB와 상호 작용하여 Domain model 객체를 영속화하는 역할을 담당 (DAO)
- 영속화? → 2주차에
- Service: 외부에서 요청하는 비즈니스 로직을 처리하고 도메인 모델 객체 간의 상호 작용을 통제
- Controller: HTTP 요청을 받아와 Service 계층에 전달하고 응답을 처리
- Exception: 예외 처리와 관련된 로직을 담당하며 오류 상황을 처리
- 왜 필요할까?
과제
- Java 11 이상 설치
- Git 설치
- Intellij로 Springboot 2.X.X 버전 빌드
- Github Repository 생성
- 패키지 domain, repository, dto, service, controller, util 생성
- mySQL 설치