OOP 원칙이란?
소프트웨어를 설계함에 있어 이해하기 쉽고, 유연하고, 유지보수가 편하도록 도와주는 5가지 원칙을 말한다.
1. Single Responsibility Principle ( SRP : 단일 책임 원칙 )
어떤 클래스를 변경해야 하는 이유는 오직 하나뿐이어야 한다" - 로버트 C. 마틴
모든 클래스는 하나의 책임만 가지며, 클래스는 그 책임을 완전히 캡슐화해야 함을 말한다.
만약, 새를 생각하고 Animal클래스를 하나 만들었다고 가정하자
public class Animal {
public void cry(){};
public void eat(){};
public void run(){};
public void fly(){};
}
물론 이렇게 단순한 클래스에선 말이 안되지만 예를 들기 위함이다.
public static void main(String[] args) {
Animal bird = new Animal();
Animal dog = new Animal();
bird.fly(); // ok
dog.fly(); // ??? dogs can not fly
}
이렇게 만들게되면 강아지도 날아야 한다...
따라서 Animal 클래스를 추상하여 공통인 속성만 가져야한다.
public abstract class Animal {
abstract void cry();
abstract void eat();
abstract void move();
}
개와 새를 만들자
public class Bird extends Animal{
@Override
void cry(){}
@Override
void eat(){}
@Override
void move(){
// fly
}
}
public class Dog extends Animal {
@Override
void cry() {}
@Override
void eat() {}
@Override
void move() {
// run
}
}
public static void main(String[] args) {
Animal bird = new Bird();
Animal dog = new Dog();
bird.move(); // fly
dog.move(); // run
}
이런식으로 '추상화'를 이용하여 속성과 메서드를 설계할 때 단일 책임 원칙을 고려해야 한다.
2. Open-Closed Principle ( OCP : 개방-폐쇄 원칙 )
기존의 코드를 변경하지 않고(Closed) 기능을 수정하거나 추가할 수 있도록(Open) 설계해야 한다.
이는 위의 소스에서 만약 Animal 클래스의 move()함수가 fly라고 정의된다면 강아지를 생성할때 날 수 없기 때문에 move가 수정되어야 하며 Animal 클래스를 상속받은 모든 클래스에 영향이 간다.
따라서, Animal 클래스를 인터페이스로 만들어주고 move()함수의 내용은 각각 구현받은 클래스에서 정의하게 되면 OCP를 만족한 변경에 유연하고 유지보수 비용을 줄여주는 효과를 얻을 수 있다.
3. Liskov Substitution Principle ( LSP : 리스코프 치환 원칙)
자식 클래스는 부모클래스에서 가능한 행위를 수행할 수 있어야 한다.
위으 Animal 클래스를 상속받은 개와 새^^ Dog, Bird를 가지고 예를 들어보자.
( cry(), eat(), run(), fly() )
1). 새는 운다.
2) 새는 먹는다.
3) 새는 달린다.
4) 새는 난다.
자식 클래스인 Bird는 모두 성립하지만 강아지는 4번이 성립이 되지 않는다.
4) 강아지는 난다.
따라서 이는 LSP를 만족하지 않은 설계이므로 성립하도록 리펙토링을 하여 설계를 해야한다.
4. Interface Segregation Principle ( ISP : 인터페이스 분리 원칙 )
한 클래스는 자신이 사용하지 않는 인터페이스는 구현하지 말아야 한다.
하나의 일반적인 인터페이스보다 여러개의 구체적인 인터페이스가 낫다.
이는 인터페이스를 분리하여 다중상속을 이용하여 자신이 사용하지 않는 기능의 인터페이스의 영향을 받지 말자는 이야기이다.
여러기능을 넣어둔 인터페이스 하나를 상속받으면 인터페이스가 수정될때 영향이 너무 크므로인터페이스를 분리하여 내가 쓰지 않는 기능을 구현하지 않도록하여 영향이 없도록 하는것을 말한다.
5. Dependency Inversion Principle ( DIP : 의존 역전 원칙 )
의존 관계를 맺을 때, 변화하기 쉬운것 보단 변화하기 어려운 것에 의존해야 한다는 원칙이다.
이 원칙은 2가지 중요한 요소가 있다.
1) 상위 모듈은 하위 모듈에 종속되어서는 안된다. 둘 다 추상화에 의존해야 한다.
2) 추상화는 세부사항에 의존하지 않는다. 세부사항은 추상화에 의해 달라져야 한다.
=> 상위 클래스, 인터페이스, 추상클래스 일수록 변하지 않고 변화하기 어려운것이기에 하위 클래스나 구체클래스가 아닌 상위를 의존하라는것이다.
'Java' 카테고리의 다른 글
[Java] 컬렉션 프레임워크 (0) | 2021.01.23 |
---|---|
[Java] 예외처리 (0) | 2021.01.17 |
[Java] 인터페이스(interface) (0) | 2020.12.30 |
[Java] 오버로딩 VS 오버라이드 (0) | 2020.12.27 |
[Java] OOP의 특징 (0) | 2020.12.27 |