- 확장에는 열려있고 변경에는 닫혀있어야 한다.
- 기존의 코드를 변경하지 않고 기능을 추가할 수 있도록 설계해야한다.
Database의 이름에 따라서 처리를 다르게하는 DataLoader 클래스가 있다고 가정하자.
만약 여기에 새로운 이름을 가지는 Database를 추가하게 된다면 DataLoader의 load 함수의 코드를 매번 수정해야한다. 이렇게 되면 Database가 추가될때마다 코드를 계속 변경시켜줘야한다.
class DataLoader {
fun load(database: Database) {
if (database.name == "local") {
database.create()
} else if (database.name == "remote") {
database.read("data")
}
}
}
이를 추상화 클래스를 구성하고 상속하여 확장시키는 관계로 구성시켜 변경에는 닫히고 확장에는 열려있게 만들 수 있다.
이렇게 변경하면 만약 CloudDatabase라는 클래스를 추가하게 되어도 DataLoader 클래스를 변경할 필요가 없다.
따라서 DataLoader 클래스는 변경에는 닫혀있고 Database를 상속하는 클래스를 자유롭게 추가하여 기능을 확장할 수 있게되어 확장에는 열려있게 된다.
abstract class Database {
lateinit var name: String
var dataList = mutableListOf<String>()
...
abstract fun load()
}
class DataLoader {
fun load(database: Database) {
database.load()
}
}
class LocalDatabase : Database() {
override fun load() {
create()
}
}
class RemoteDatabase : Database() {
override fun load() {
read("data")
}
}