The Open Closed Principle says that “Software Entities (classes, modules, functions, etc) should be open for extension, but closed for modification”.
OCP에 따르면,
Software Entities는 확장할 수 있어야 하지만, 변경할 수는 없어야 한다.
class Person {
private let name: String
private let age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
class House {
private var residents: [Person]
init(residents: [Person]) {
self.residents = residents
}
func add(_ resident: Person) {
residents.append(resident)
}
}
protocol Resident {}
class Person: Resident {
// ...
}
class House {
private var residents: [Resident]
init(residents: [Resident]) {
self.residents = residents
}
func add(_ resident: Resident) {
residents.append(resident)
}
}
왼쪽 예시를 보면, Person이라는 타입과는 다른 타입이 필요해서 NewPerson 타입을 만든다면,
House에서는 내부에 있는 Person 타입들을 모두 NewPerson 타입으로 바꾸어야 함
즉, NewPerson으로 확장하려 하는데, House 에서는 변동이 생기기 때문에 OCP를 만족하지 못한다
만약, 그냥 Person 타입의 내부를 바꾼다면, 이 또한 Person 타입에 변동이 생기는 것이기 때문에 OCP를 만족하지 못한다
따라서, OCP를 따르지 않으면, 한 가지를 확장하려 할 때, 변동을 줘야 하는 요소가 생기게 된다
House 타입은 Resident라는 프로토콜을 의존하고 있고,
Person도 Resident라는 프로토콜을 받아와 사용하기 때문에,
NewPerson이라는 타입이 Resident를 따르도록 형성된다면, House에는 아무 변화를 주지 않아도 된다