티스토리 뷰
# 이 게시글은 "토비의 스프링" 책을 보고 정리를 위해 기록해둔 게시글입니다.
그 유명한 토비의 스프링 책을 도서관에서 빌려왔다.. 두께부터 엄청나게 두꺼운게 압도당하는 기분이다.
과연 이걸 다 읽을 수 있을지 걱정되긴 하지만 되는데까지 한번 읽어보고 기록해두고자 한다. 화이팅!
# 스프링이란 무엇인가?
자바 애플리케이션 개발에 사용되는 애플리케이션 프레임워크로 개발을 빠르고 효율적으로 할 수 있도록 틀과 API를 제공한다.
* 스프링 컨테이너(=애플리케이션 컨텍스트) - 스프링 런타임 엔진
- 설정 정보를 참고로 애플리케이션을 구성하는 오브젝트를 생성 및 관리한다
- 웹 모듈에서 동작하는 서비스나 서블릿으로 등록해서 사용한다.
* IoC/DI: 오브젝트의 생명주기와 의존관계에 대한 프로그래밍 모델
* AOP: 애플리케이션 코드에 산재한 공통기능을 독립적으로 모듈화하는 프로그래밍 모델
스프링이라는 단어는 3가지 의미로 사용된다
1. 스프링 컨테이너
2. 스프링 프레임워크
3. 스프링 부트, 스프링 프레임워크 등을 포함한 스프링 생태계 전반
* 프레임워크의 목적 = 개발자가 일정한 틀을 따라 효과적으로 애플리케이션을 개발하도록 돕는것.
* 스프링은 좋은 객체지향 애플리케이션을 개발할 수 있도록 지원하는 프레임워크이다.
[1장]
[1-1] 초난감 DAO
* DAO(Data Access Object): DB를 사용해 데이터를 조회하거나 조작하는 기능을 전담하도록 만든 오브젝트
* 자바빈, (빈)(JavaBean): 관례를 따라 만들어진 오브젝트(컴포넌트) - 일반적으로 클래스를 의미함
- DTO(Data Transfer Object)나 DAO 클래스의 객체를 JSP에서 사용하기 위해 사용됨
- 아래 두가지 조건을 만족해야함
-> 디폴트 생성자: 파라미터가 없는 생성자를 갖고있어야 함 (NoArgsConstructor)
-> 프로퍼티: 자바빈이 노출하는 이름을 가진 속성, set으로 시작하는 수정자 메소드(setter)와 get으로 시작하는 접근자 메소드(getter)를 이용해 수정 및 조회
[JDBC를 이용하는 작업의 일반적인 순서]
1. DB 연결을 위한 Connection을 가져온다
2. SQL을 담은 Statement를 만든다
3. 만들어진 Statement 실행
4. 조회의 경우 SQL 쿼리의 실행 결과를 ResultSet으로 받아서 정보를 저장할 오브젝트에 옮겨준다 (Mapping)
5. 작업 중에 생성된 Connection, Statement, ResultSet과 같은 리소스는 작업 종료 이후 닫아준다
6. JDBC API 예외는 잡아서 직접 처리하거나, 메소드에 throws를 선언해 메소드 밖으로 던져버린다.
[1-2] DAO의 분리
객체를 설계할 때 가장 중요한 것은 "미래의 변화를 어떻게 대비할 것인가"이다.
-> 변화의 폭을 최소한으로 줄여 변화에 효과적으로 대처할 수 있도록 해야한다.
-> HOW? = 분리와 확장을 고려한 설계. <관심사의 분리>
* 리팩토링 (refactoring): 기존의 코드를 외부의 동작방식에는 변화 없이 내부 구조를 변경해서 재구성하는 작업.
- 코드 내부의 설계를 개선하여 유지보수를 용이하게 하고 변화에 효율적으로 대응. 견고하면서 유연한 제품 개발.
* 디자인 패턴: 소프트웨어 설계 시 특정 상황에서 자주 만나는 문제를 해결하기 위해 사용할 수 있는 재사용 가능한 솔루션.
- 패턴 이름만으로도 설계의 의도와 해결책을 설명할 수 있다는 장점.
- 주로 객체지향 설계에 관한 것, 객체지향적 설계 원칙을 이용한 문제 해결. (대표적으로 클래스 상속 or 오브젝트 합성)
[템플릿 메소드 패턴] - DIP
- 상속을통해 슈퍼클래스의 기능을 확장할 때 사용되는 대표적인 방법.
- 상위 클래스는 처리의 흐름을 제어하고, 하위 클래스에서 처리의 내용을 구체화하는 것.
- 변하지 않는 기능은 슈퍼 클래스에 만들어두고, 자주 변하고 확장될 기능은 서브 클래스에서 만들도록 한다.
- 슈퍼 클래스에는 미리 추상 메소드 및 오버라이드 가능한 메소드를 정의해두고, 이를 활용한 알고리즘을 담고 있는 템플릿 메소드를 만들어둔다.
- 서브 클래스에서는 추상 메소드 및 훅 메소드를 오버라이딩 하여 슈퍼 클래스의 기능을 확장해서 사용.
(+) 훅(Hook) 메소드: abstract 키워드를 붙이지 않아 "선택적"으로 오버라이딩 해 사용할 수 있는 메소드
-> 추상 메소드는 서브 클래스에서 "반드시" 오버라이딩 해야한다.
[팩토리 메소드 패턴] - DIP
- 템플릿 메소드 패턴과 마찬가지로 상속을 통해 기능을 확장하게 하는 패턴.
- 팩토리 메소드: 객체를 생성 및 반환하는 메소드
- 팩토리 메소드 패턴: 하위 클래스에서 팩토리 메소드를 오버라이딩해 객체를 생성, 반환하게 하는 것.
-> 객체를 생성하기 위해 인터페이스를 정의하지만, 어떤 클래스의 인스턴스를 생성할 것인지에 대한 결정은 서브 클래스에서 이뤄지도록 한다.
-> 슈퍼 클래스의 코드를 수정하지 않고도 확장 가능. 의존성을 제거하고 결합도를 낮춘다
[1-3] DAO의 확장
관심사의 분리는 변화의 성격에 따라서 진행한다
- 변화의 성격이 다르다는 것은 변화의 이유와 시기, 주기 등이 다르다는 뜻이다.
- 변화의 성격이 다른 것을 분리해서 서로 영향을 주지 않고 독립적으로 변경할 수 있도록 해야한다.
=> 특정 클래스에 종속적이지 않게 해야한다.
==> 클래스 간 추상적인 연결고리를 사용하자(=인터페이스)
* 추상화: 어떤 것들의 공통적인 성격을 뽑아내 이를 따로 분리하는 작업
* 이때, 런타임 시 클래스 간 관계 설정은 제 3자에게 맡기고 (객체의 생성(new), 생성자 주입), 각 클래스들은 자기에게 맡겨진 역할에만 집중할 수 있도록 한다.
Bad: 클래스가 직접 다른 클래스를 new를 통해 직접 생성 및 사용 (특정 클래스에 종속적인 코드)
Good: 인터페이스 사용, 생성자를 통해 인터페이스 구현 클래스를 주입받아 사용. 클라이언트는 구현 클래스가 어떻게 정의되었는지 알 필요 없이 인터페이스의 정의에만 따르면 된다.
(이때 주입은 제 3자가 한다 --> 나중에 나옴(팩토리 및 컨테이너))
역할(인터페이스)과 구현(구현 클래스)을 분리하자! = 객체지향의 다형성
- 클라이언트는 대상의 역할만 알고 있으면 된다(인터페이스)
- 클라이언트는 구현 대상의 내부 구조를 몰라도 되고, 변경되어도 영향을 받지 않는다 = 갈아끼울 수 있다
--> 확장에는 열려있고, 변경에는 닫혀있는 설계.
========================
[단일 책임 원칙, Single Responsibility Principle]
하나의 클래스는 하나의 책임만을 가져야 한다.
하나의 책임이라는 것은 상대적임 -> 변화의 성격이 동일한 것 끼리 묶는다.
★★★ [개방 폐쇄 원칙, Open-Closed Principle] ★★★
클래스나 모듈은 확장에는 열려있어야 하고 변경에는 닫혀있어야 한다.
= 다형성을 활용해 개발해라(역할과 구현의 분리)
[리스코프 치환 원칙, Liskov Substitution Principle]
자식 클래스는 언제나 부모 클래스로 치환(교체)될 수 있어야 한다.
-> 단순히 컴파일이 잘 되도록 해라는 것이 아니라 책임까지 동일하게 치환이 되야 한다.
- 다형성을 지원하기 위한 원칙 중 하나 (갈아끼울 수 있으려면 대체가 가능해야지)
[인터페이스 분리 원칙, Interface Segregation Principle]
클래스는 자신이 사용하지 않는 메소드와 의존관계를 맺으면 안된다.
= 특정 클라이언트를 위한 인터페이스 여러개가 범용 인터페이스 하나보다 낫다
= 인터페이스 최소주의 원칙
[의존관계 역전 원칙, Dependency Inversion Principle]
고수준 모듈은 저수준 모듈의 구현에 의존하지 않아야 한다.
= 자기보다 변하기 쉬운것에 의존하지 마라.
= 클래스는 클래스 보다 인터페이스에 의존해야 한다.
= 구체화에 의존하지 말고, 추상화에 의존하라
==> SOLID(OCP, DIP)를 지키기 위해서는 다형성, 그리고 제3자의 역할이 필요하다. 그것을 스프링이 해준다.
========================
높은 응집도와 낮은 결합도를 지향하자
* 응집도: 변화가 일어날 때 해당 모듈에서 변하는 부분이 크다.
* 결합도: 하나의 오브젝트가 변경이 일어날 때 관계를 맺고있는 다른 오브젝트에게 변화를 요구하는 정도.
[전략 패턴, Strategy Pattern]
자신의 기능 컨텍스트에서 필요에 따라 변경이 필요한 알고리즘을 인터페이스를 통해 통째로 외부로 분리시키고, 이를 구현한 구체적인 알고리즘 클래스를 필요에 따라 바꿔 사용할 수 있도록 하는 디자인 패턴.
'웹 > Spring' 카테고리의 다른 글
스프링 볶음밥 - 1장 - 7(IoC/DI/DL) (0) | 2022.07.01 |
---|---|
스프링 볶음밥 - 1장 - 4,5,6 (0) | 2022.07.01 |
SpringBoot 환경에서 MQTT 통합 사용해보기 (1) | 2022.05.02 |
SpringBoot | DataIntegrityViolationException 해결 (0) | 2022.04.05 |
JPA에 대해 공부해보자 (6) - JPQL (0) | 2022.03.24 |