dev
SOLID
coldmonster
2022. 9. 23. 01:05
SOLID
Single responsability principle
한번에 한가지 기능만 가져야한다. OpenAndWrite()같은 함수는 지양.
기능은 하나씩만 가져야한다. Open과 Write는 분리하자
FileOpenAndWrite() (X)
-> FileOpen()
-> FileWrite()
Open closed principle
확장은 open 수정은 close
animal클래스를 상속받는 cat클래스 외에 dog 클래스를 추가하여 확장 하는것은 허용.
하지만 이 확장으로 인해 cat, dog을 호출하는 다른 함수들을 수정하지 않아야한다.
Cow클래스 추가로인해 Hello()함수에 Cow클래스를 위한 수정은 없어야한다는 뜻.
위 그림에서는 Cow가 추가되면서 Hello() 함수에 Cow에 대한 처리를 추가해줘야한다.
Cat::hello()
run()
Dog::hello()
speak()
Cow::hello()
print(...)
fn Hello(animal)
animal.hello()
이게 꼭 정답은 아니지만 Hello()함수에 대응하는 동작은 Animal을 상속받는 동물들의 구현에 맡긴다.
Liskov substitution principle
class Animal {
run()
speak()
}
class Cat : Animal {}
class Fish : Animal {} // 물고기는 run(), speak() 불가..
Animal클래스를 상속받는 Cat클래스는 Animal클래스로 치환되어도 제 기능을 수행할 수 있어야한다.
Fish클래스에 Animal클래스를 상속받아도 제 기능을 할 수 없다.
Interface segregation principle
class Machine {
go()
stop()
turn()
}
class Car : Machine {}
class Plane : Machine {
// 공중에서..
}
인터페이스가 너무 크면 안된다. 사용하지 않는 인터페이스 메소드들이 함께 포함된다.
인터페이스를 더 세부화 하여 사용하지 않는 메소드를 상속받지 않게 한다.
// Machine을 분리해서
class Vehicle {
go()
stop()
turn()
}
class Flight {
takeoff()
land()
}
class Car : Vehicle {}
class Plane : Flight {}
Dependency inversion principle
상위클래스에서 하위클래스가 추가됨에따라 하위클래스에 의존하는 형태가 되어선 안된다.
class Animal {
virtual string run() {return "cong"}
}
class Cat : Animal {
string run() override {return "cat";}
}
class Dog : Animal {
string run() override {return "dog";}
}
class Horse : Animal {
string run() override {return "hor";}
}
동물의 run 함수를 호출해야할때 아래처럼 하위클래스를 받아 run함수를 호출하는 것이 아니라
void call(Cat* cat) {
cat->run();
}
상위클래스 Animal을 가지고 데이터 형태에 따라 각각 다른 run의 동작을 호출할 수 있도록 하는것.
void call(Animal* animal) {
animal->run();
}