SpringBoot/Spring Basic
[Spring] 객체 지향 설계의 5가지 원칙(SOLID)
myeongju
2022. 2. 5. 01:06
반응형
객체 지향 프로그래밍
- 컴퓨터 프로그램을 여러개의 독립된 단위, 즉 "객체"들의 모임으로 파악하고자 하는 것. 각각의 객체는 메시지를 주고받고, 데이터를 처리할 수 있음.
- 프로그램을 유연하고 변경이 용이하게 만들기 때문에 대규모 소프트웨어 개발에 많이 사용
객체지향의 특징
- 추상화(Abstraction)
: 여러 객체들의 공통적인 특징을 도출해 내는 것, 현실 객체를 추상화해서 클래스를 구성. - 캡슐화(Encapsulation)
: 데이터(속성)와 데이터를 처리하는 함수를 하나로 묶는 것, 데이터를 직접 노출시키지 않고 메서드를 이용해 보호. - 상속(Inheritance) : 상위클래스의 속성을 하위클래스가 물려받는 것
- 다형성(Polymorphism) : 하나의 객체가 여러 형태를 가지는 것
다형성의 실세계 비유
: 실세계와 객체 지향을 1:1로 매칭X, 이해하기에는 좋음. 역할과 구현으로 세상을 구분
다형성의 실세계 비유
- 운전자는 자동차가 바뀌어도 영향 X : 운전자가 테슬라를 산다고 해서 다른 운전면허는 따야하는 것은 아님.
이유 : 자동차 역할의 인터페이스를 따라 각각 자동차를 구현했기 때문. (역할에서만 의존)
이런 역할을 만들고 구현을 분리한 이유 : 운전자(클라이언트)를 위해서 만듦 → 자동차 세상을 무한히 확장 가능. - 클라이언트에 영향을 주지 않고, 새로운 기능을 제공할 수 있음. (역할과 구현으로 세상을 구분했기 때문)
→ 새로운 자동차가 나와도 클라이언트를 바꿀 필요 X
역할과 구현을 분리하면 ?!
→ 세상이 단순해지고, 유연해지며, 변경도 편리해진다.
- 클라이언트는 대상의 역할(인터페이스)만 알면 됨
- 클라이언트는 구현 대상의 내부 구조를 몰라도 됨
- 클라이언트는 구현 대상의 내부 구조가 변경되어도 영향을 받지 않음
- 클라이언트는 구현 대상 자체를 변경해도 영향을 받지 않음
다형성의 본질
- 인터페이스를 구현한 객체 인스턴스를 실행 시점에 유연하게 변경할 수 있음
- 다형성의 본질을 이해하려면 협력이라는 객체 사이의 관계에서 시작해야함
- 클라이언트를 변경하지 않고, 서버의 구현 기능을 유연하게 변경할 수 있음
스프링과 객체 지향
- 다형성이 가장 중요!
- Spring은 다형성을 극대화 해서 이용할 수 있게 도와줌
- Spring에서 이야기하는 IOC, DI은 다형성을 활용해서 역할과 구현을 편리하게 다룰 수 있도록 지원
좋은 객체 지향 설계의 5가지 원칙 (SOLID)
: 클린코드로 유명한 로버트 마틴이 좋은 객체 지향 설계의 5가지 원칙을 정리
- SRP : 단일 책임 원칙(single responsibility principle)
- 한 클래스는 하나의 책임만 가져야 함
- 하나의 책임이라는 것은 모호함 → 중요한 기준: 변경. 변경이 있을 때 파급 효과가 적으면 단일 책임 원칙을 잘 따른 것
- 관심사의 분리 (의존성 주입)
: 어플리케이션을 하나의 공연이라 생각하자!
ex) 기존: 남자 주인공 배우가 공연, 섭외까지 다 함(클라이언트가 의존하는 서버 구현 객체를 직접 생성하고 실행)
→ 공연을 구성하고, 담당 배우를 섭외하고 지정하는 책임을 담당할 공연 기획자(AppConfig)가 필요. (AppConfig는 애플리케이션의 전체 동작 방식을 구성하기 위해, 구현 객체를 생성하고 연결하는 책임 O.)
∴ 이제 남자 주인공은 연기에만 집중할 수 O.(클라이언트 객체는 자신의 역할 실행에만 집중, 권한이 줄어듦.)
- 관심사의 분리 (의존성 주입)
- OCP : 개방-폐쇄 원칙(Open/Closed principle)
- 소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 함
→ 확장에 열려있다 ? 새로운 변경사항이 발생했을 때, 유연하게 코드를 추가 또는 수정할 수 있어야 함
→ 변경에 닫혀있다 ? 객체를 직접 수정하지 않고도 변경사항을 적용할 수 있도록 설계해야 함 - 인터페이스를 구현한 새로운 클래스를 하나 만들어서 새로운 기능을 구현
- 애플리케이션을 사용 영역과 구성 영역으로 나눔
→ SW요소를 새롭게 확장해도 사용 영역의 변경은 닫혀있어야 함!
- 소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 함
- LSP : 리스코 치환 원칙 (Liskov substitution principle)
- 객체는 프로그램의 정확성을 깨지 않으면서 하위 타입의 인스턴스로 바꿀수 있어야 함
- ISP : 인터페이스 분리 원칙 (Interface segregation principle)
- 범용 인터페이스 하나보다는 특정 클라이언트를 위한 여러 개의 인터페이스 분리가 더 좋음
- DIP : 의존관계 역전 원칙 (Dependency inversion principle)
- 구체화가 아니라 추상화에 의존해야 함. 즉 구현 클래스(구현체)가 아니라 인터페이스(역할)에 의존해야 함
Reference
반응형