일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
Tags
- 명령-쿼리 분리
- 믹스인
- 책임주도설계
- OOP
- 유여난 설계
- 객체지향
- 합성
- 메서드를 통한 해결
- 컴파일 타임 의존성
- Apple # HIG #iOS15 #iOS14 #Human #Interface #Guidelines #Apple developer # Apple human interface guidelines
- 상속 조합 폭발적 증가
- Swift#flatMap#map#Monad#함수형 프로그래밍#Optional
- 다형성
- OCP
- 객체 생성 사용 분리
- 서브 타이핑
- 행동 호환성
- 상속
- iSP
- '기존 설계 재사용
- 알고리즘
- dip
- 의존성
- 일관성 있는 협력
- 오브젝트
- 런타임 의존성
- 유연한 설계
- 설계 재사용
- 하향식 접근
- 추상화
Archives
- Today
- Total
도니의 iOS 프로그래밍 세상
[오브젝트 2회독] 9장 - 유연한 설계 본문
1. 개방-폐쇄 원칙(OCP)
OCP
- s/w는 확장에 열려있고, 수정에 닫혀있어야 함
- 이는 기존 코드 수정 없이 동작이 추가되고 변경되어야 한다는 뜻
추상화가 핵심이다
- 추상화를 통해 핵심적인 부분만 의존하도록 해, 문맥이 변하더라도 바뀌지 않음
- 문맥에 따라 적합한 기능을 구체화 하면 된다.
2. 생성 사용 분리
- 객체가 추상화만 의존하기 위해선, 추상화의 구체 클래스를 객체 내부에서 생성해서는 안됨
- 구체 클래스를 객체가 직접 생성한다면, 기능(구체 클래스)을 변경할 때 기존 코드의 변경이 발생할 수 밖에 없고, 이는 OCP 위반
- 그리하여 유연한 설계를 위해서는 생성과 사용이라는 책임을 두 객체로 분리 한다.
Factory 추가하기
- 생성과 사용 분리를 위해 객체 생성에 특화된 Factory를 사용
3. 의존성 주입
사용하는 객체가 아닌, 외부 독립적 객체가 인스턴스 생성후 이를 전달하여 의존성을 해결하는 방식을 의존성 주입
- 생성과 사용 분리시, 객체는 인스턴스를 사용하는 책임만 남음
- 외부에서는 다른 객체가 인스턴스를 전달해야 함
3가지 주입 방식
- 생성자 주입
- setter 주입
- setter의 장점은 생성자 주입 방식과 달리 런타임때 자유롭게 의존 객체를 변경 간으
- 단점은 set하기 전까지 객체가 불완전해짐
- 메서드 주입
- 메서드에서만 의존성이 필요한 경우 사용
숨겨진 의존성은 나쁘다
Service Locator Pattern 을 활용하여 객체의 의존성을 해결할 때, 의존성이 숨겨져 있어 캡슐화를 위반할 수 있다.
- Service Locator Pattern: 의존성 해결할 객체를 보관하는 저장소
class Dependency {
let category: Cagetory
}
class Movie {
init() {
self.category = Dependency.shared.category
}
}
- 외부에서 사용시 Movie객체가 어떤 객체에 의존하는 지 할 수 없음
- 카테고리 변경을 위해선 내부 구현을 확인할 수 밖에 없고, 캡슐화를 위반한다.
결론
- 숨겨진 의존성보단 명시적 의존성을 사용할 것
- Service Locator Pattern 이 유용할 땐, 변경될 가능성이 적은 객체 or 10개의 겹으로 쌓여진 의존성을 주입하는 케이스에서 해당 패턴을 사용하여 보다 간단하게 객체를 사용할 수 있는 케이스
4. 의존성 역전 원칙
추상화와 의존성 역전
- 추상 클래스가 아닌 구현 클래스에 의존한다면 결합도가 높아 재사용성이 저해됨
- 잘 변경되지 않는 추상화에 의존함으로써 설계의 영향을 최소화 할 수 있음
- 상위 클래스가 하위 클래스에 영향을 주는 건 당연하지만, 반대는 안된다
의존성 역전 원칙이라고 부르며, 역전이라는 용어를 사용하는 이유는 기존 절차적 프로그래밍의 반대 방향이기 때문
- 절차적 프로그래밍에서는 상위 수준 모듈이 하위 수준 모듈에 의존하는게 기본 구조였기 때문이다.
의존성 역전 원칙과 패키지
- 역전은 인터페이스의 소유권과도 연결되며 모듈 설계 관점에서도 연결 가능
- 인터페이스 분리 패턴
- 특정 객체에 추상 클래스에 의존하고 있을 때, 그것들의 구체 클래스를 다른 모듈에 구현하는 것
- 추가 기능을 확장할 때 구체 클래스가 만들어지고, 이들이 만약 추상화 클래스와 함께 있다면 불필요한 re-compile 필요
- 결국 변경의 이유를 모듈로 분리하여 의존성을 관리한다는 점
5. 유연성에 대한 조언
유연한 설계는 유연성이 필요할 때만 옳다
- 설계의 미덕은 단숨함과 명확함으로써, 유연성은 복잡성을 수반한다.
- 따라서, 유연성이 필요한지 검토가 필요하며 미래의 불안감을 이유로 설계를 복잡하게 해서는 안된다.
협력과 책임은 중요하다
- 설계는 역할, 책임, 협력에 초점을 맞추고, 협력 재사용이 필요 없다면 유연성을 과도하게 추구하지 않음
- 객체 생성에 집착해 책임, 역할을 간과하지 않아야 하며, 객체 생성을 마지막 시점에 결정해야 함
결론
- OCP를 통해 다양한 기능을 추가할 때 기존 코드에 영향이 없을 수 있음
- 추상화에 의존한 형태가 기반이 되어야 OCP 원칙을 지킬 수 있음
- 추상화된 객체에 의존하기 위해선, 객체의 사용과 생성을 분리해야 함
- 객체 생성에 특화된 Factory 객체를 활용하여 객체 사용/생성을 분리할 수 있음
- 사용 객체에게 생성된 인스턴스를 주입하는 행위를 의존성 주입이라고 함
- 의존성 주입시, 숨겨진 의존성보단 명확한 의존성을 가져야 캡슐화를 위반하지 않을수 있음
- 의존성 역전 원칙이란 구체 클래스가 아닌 추상화에 의존하는 것을 의미하며, 역전이라는 용어가 붙은 이유는 기존 절차형과 상반되는 방식이기 때문
- 이 원칙은 모듈에도 적용되며, 상위 수준의 모듈과 하위 수준의 모듈을 분리할 수 있음
- 이를 통해 불필요한 re-compile등을 방지한다.
- 유연한 설계는 복잡성을 수반하기 때문에, 불필요한 설계를 만들지 않아야 함
'OOP' 카테고리의 다른 글
[오브젝트 2회독] 11장 - 합성과 유연한 설계 (0) | 2024.11.19 |
---|---|
[오브젝트 2회독] 10장 - 상속과 코드 재사용 (0) | 2024.11.19 |
[오브젝트 2회독] 8장 - 의존성 관리하기 (0) | 2024.11.19 |
[오브젝트 2회독] 7장 - 객체 분해 (0) | 2024.11.19 |
[오브젝트 2회독] 6장 - 메시지와 인터페이스 (0) | 2024.11.19 |
Comments