클래스는 한 가지 이유로 변경되어야 합니다
각각의 클래스가 프로그램이 제공하는 기능의 단 하나의 부분만 책임 지도록 하세요
이 원칙의 목적은 복잡성을 줄이는 것입니다
프로그램이 성장하고 병경되면서 클래스들은 너무 커질것입니다
그렇게 될 경우 코드 탐색은 매우 느려질것이고, 클래스나 프로그램의 전체를 훑어봐야 특정 코드를 찾을 수 있게 되겠죠
또한 클래스가 너무 많은 작업을 수행 할 경우, 그 중 하나가 변경될 때마다 클래스를 변경해야 합니다. 그럴경우 변경할 생각이 없던 클래스의 다른 부분이 망가질 위험이 있습니다
당신은 세계의 다양한 요리 메뉴가 있는 음식점을 오픈했습니다
당신은 중식, 양식, 일식을 모두 다 잘하는 요리사 한명을 고용할지 각각의 요리사 세명을 고용할지 고민중입니다
결국 당신의 선택은 요리사 세명을 고용하는 것이였습니다
요리사한테 문제가 생겼을경우 한명일때보다는 세명일때 더욱 유연하게 대처할 수 있기 때문입니다
예를들면 양식 요리사한테 문제가 생겼을경우 일단 중식, 일식만 판매한다던가 양식 요리사만 교체한다든가 할 수 있겠죠
하지만 요리사가 한명일경우에는 중식, 양식, 일식을 모두 다 할 수 있는 요리사를 새로 구하기 전까지는 장사를 못할겁니다
class Handler {
func handle() {
let data = fetchData()
let newData = createNewData(data)
uploadData(newData)
}
func fetchData() -> Data {
// fetchData logic
return Data()
}
func processingData(_ data: Data) -> Data {
// processing logic
return Data()
}
func uploadData(_ data: Data) {
// uploadDatalogic
}
}
해당 클래스는 3가지 일을 한다
1. data fetch
2. fetch한 데이터로 새로운 데이터 만들기
3. 만든 새로운 데이터를 업로드
이 책임들을 각각 작은 객체로 분리하자
class Handler {
let apiHandler: APIHandler
let processingHandler: ProcessingHandler
init(apiHandler: APIHandler, processingHandler: ProcessingHandler) {
self.apiHandler = apiHandler
self.processingHandler = processingHandler
}
func fetchAndUploadProcessingData() {
let data = apiHandler.fetchData()
let processingData = processingHandler.processingData(data)
apiHandler.uploadData(processingData)
}
}
class APIHandler {
func fetchData() -> Data {
// fetch logic
return Data()
}
func uploadData(_ data: Data) {
// upload logic
}
}
class ProcessingHandler {
func processingData(_ data: Data) -> Data {
// processing logic
return Data()
}
}
모든 클래스는 하나의 책임만 가지며, 클래스는 그 책임을 완전히 캡슐화 해야 한다