클래스는 하나의 기능만 있으며, 클래스를 변경할 이유는 오직 하나다.
예)
변경 전 : Robot 클래스에 청소하다() , 총을쏘다() , 배달하다() 메서드가 있음
변경 후 :
청소기로봇 - 청소하다()
전투용로봇 - 총을쏘다()
배달용로봇 - 배달하다()
등으로 하나의 클래스가 하나의 책임만 가지도록 한다.
클래스는 확장에는 열려있고 변경에는 닫혀있다.
이는 추상화나 다형성(polym)을 통해서 구현이 가능하다.
즉, 특정 클래스에 종속하지 않고 독립적으로 끼워 넣을 수 있도록한다.
예) 탈것 클래스 <- 상속 ( 기차 , 자동차 , 버스 )
탈것 클래스에 각 기차, 자동차 , 버스를 업캐스팅해서 확장이 가능하다.
이 때 탈것 클래스 자체는 변동이 되지 않는다.
서브 타입은 언제나 기반타입으로 대체 될 수 있어야 한다.
즉, 상속 관계에서 하위 클래스는 상위 클래스는 기능을 모두 갖춰야 하며,
상위 클래스에서 정의된 기능을 무시하거나 다른 방식으로 구현하면 안된다.
예)
class Bird {
void fly() {
sout("날아요~");
}
}
class 펭귄 extends Bird {
@Override //메서드 재정의를 해서 상위 클래스에 정의된 기능과 다른 형태로 구현
void fly() {
throw new Exception("펭귄은 못 날죠");
}
}
## LSP 적용 방안 - 오버라이딩을 해도 상위 클래스가 기대하는 동작을 벗어나지 않게 한다.
abstract class Bird {
abstract void move() ;
}
class 펭귄 extends Bird {
@Override
public void move() { //움직이는 행위 = 상위 클래스가 기대한 동작 (예외 말고)
sout("헤엄쳐요");
}
}
class 독수리 extends Bird {
@Override
public void move() { //움직이는 행위 = 상위 클래스가 기대한 동작 (예외 말고)
sout("날아요~");
}
}
인터페이스에 너무 많은 기능이 들어가면 필요없는 메서드도 구현해야 한다.
그렇지 않게 나누자
DIP ( Dependency Inverseion Principle )
고수준 모듈이 저수준 모듈에 의존하지 않고, 추상화된 인터페이스 등에 의존해야한다.
예를 들어 컨트롤러가 서비스 구현체에 의존하지 않고 서비스 인터페이스에 의존해야한다는 것
[클린 아키텍처 구조도]

출처 : https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html
핵심 비즈니스 로직과 데이터 상태를 담당 , 외부 변화에 민감하지 않아야 함
외부 변화란 DB , UI , 프레임워크 와는 독립적으로 외부 시스템과 무관하게 독립 동작을 의미
모델(model) : 비즈니스 개념을 나타내고 상태와 행동을 포함 , 가벼운 변경 메서드도 가능
예) Order 의 상태와 행동 (필드 , 메서드)
서비스(service) : 도메인 모델과 관련되며 도메인 객체가 표현하기 어려운 비즈니스 규칙 담당
(실제 비즈니스 로직이 처리됨을 의미)
애플리케이션의 특정 기능을 구현하는 곳으로 엔터티를 활용해 비즈니스 로직을 구현함
비즈니스 규칙 자체 처리보다는 전체적인 흐름 및 트랜잭션 관리
, 하지만 트랜잭션은 가급적 service 레벨로 내리는 것이 좋음
(범위를 최소화 하면 좋겠다는 의미 , 너무 트랜잭션이 길어져도 좋지 않으니까 )
usecase 와 facade 의 차이점은 ??
예) usecase : 비즈니스 시나리오 별로 유즈케이스 처리
예) facade : 복잡한 비즈니스 로직을 단순화된 인터페이스로 제공함으로써
클라이언트가 여러 서비스와 상호작용하지 않도록 함
facade는 여러 서비스나 usecase를 조합해 단순한 인터페이스를 제공한다.
따라서 비즈니스 시나리오에 대해 더 추상화 할 수 있는 개념이며
usecase는 보통 하나의 특정 기능에 집중한다.
예) controller 는 사용자의 요청을 받는 역할
예) dto 는 사용자의 요청 및 반환할 응답 데이터를 처리하는 역할
기술적인 구현 세부사항을 처리
DB와의 상호작용 , 외부 API 호출 , 보안 설정 등 애플리케이션 동작에 필요한 기술적 부분을 처리
도메인계층과 독립적으로 동작
인터페이스 계층과 프레임워크 계층 둘다 외부시스템과 연결하는 거 아닌가?
무슨 차이가 있는거지?