프로그래밍 기초

SOLID 원칙

hs-archive 2023. 8. 17. 22:28

SOLID 원칙

SOLID는 객체 지향 프로그래밍의 원칙을 정리한 것으로, 객체 지향 설계의 품질과 유지보수성을 향상시키기 위해 개발된 원칙의 집합입니다. 단순하게 말하자면 객체 지향 프로그래밍을 사용하여 유연한 코드를 작성하기 위해 지키면 좋은 것들을 모아놓은 것이 SOLID입니다. 

 

Single Responsibility Principle(SRP, 단일 책임 원칙)

클래스는 오직 한 가지 일만 해야 하고, 클래스를 수정해야 하는 상황이 생긴다면 바꾸려는 이유가 하나여야 한다는 원칙입니다. 

 

한마디로 한 클래스 내에서 너무 많은 일을 하지 말라는 것입니다. 하나의 클래스에서 프로그램의 모든 문제를 해결한다면 클래스 내부에서 서로 다른 역할을 수행하는 코드끼리 강하게 결합될 가능성이 있고 이러한 상황에서 기능 변경을 하면 이곳 저곳에서 수정이 연쇄적으로 발생할 수 있습니다. 따라서 SRP을 통해 이를 방지하자는 것입니다.

 

Open-Closed Principle(OCP, 개방-폐쇄 원칙)

확장에는 열려있고(개방) 수정에는 닫혀(폐쇄)있어야 한다는 원칙입니다. 다시 말해, 클래스 기존 코드 수정 없이 동작을 확장할 수 있어야 한다는 의미입니다. 상속과 다형성이 좋은 예시 입니다.

 

// 이 메서드는 새로운 동물이 추가될 때마다 클래스를 수정해야 합니다.
// 개방-폐쇄 원칙을 지킬 수 없습니다.
public void speak(Animal animal) {
	if (animal.type == Animal.DOG) {
    	System.out.println("월월");
    } else if (animal.type == Animal.CAT) {
    	System.out.println("야옹");
    } else if (animal.type == Animal.SHEEP) {
    	System.out.println("sheep");
    } 
}

// 이 메서드는 새로운 동물이 추가되더라도 클래스를 수정할 필요가 없습니다.
// 개방-폐쇄 원칙을 지킬 수 있습니다.
public void speak(Animal amimal) {
	System.out.println(animal.speak());
}

 

Liskov Subsitution Principle(LSP, 리스코프 치환 원칙)

부모가 할 수 있는 일은 자식도 다 할 수 있어야 한다는 원칙입니다. 생각해보면 당연합니다. 이 원칙이 있어야 다형성이 제대로 동작합니다. 이 원칙이 지켜지지 않는다면, 개방-폐쇄 원칙의 예제 코드에 있는 animal.speak(); 같은 코드가 동작하지 않을 수 있습니다.

 

Interface Segregation Principle(ISP, 인터페이스 분리 원칙)

큰 인터페이스 보다 작은 인터페이스 여러개가 좋다라는 원칙입니다. 다시 말해, 인터페이스를 각각 사용에 맞게 잘게 분리해야 한다는 원칙입니다. SRP이 클래스의 단일 책임을 강조한다면 ISP는 인터페이스의 단일 책임을 강조하는 느낌입니다. 각 클래스의 목적과 용도에 적합한 인터페이스만을 제공하기 위함입니다.

 

Dependency Inversion Principle(DIP, 의존 역전 원칙)

DIP는 객체에서 다른 객체에 대한 참조를 가질 때 그 class 를 직접 의존하지 말고 그 클래스의 상위 요소(추상 클래스, 인터페이스)를 참조하라는 원칙입니다.

 

public class Kid {
	private Robot robot;
    
    public void setToy(Robot robot) {
    	this.robot = robot;
    }
    
    public void play() {
    	System.out.println(robot.toString());
    }
}

public class Main {
	public static void main(String[] args) {
    	Robot r = new Robot();
        Kid k = new Kid();
        k.setToy(r);
        
        k.play();
    }
}

 

위와 같은 상황에서 kid 가 갖고 노는 장난감이 robot이 아니라 lego로 바뀌면 kid 클래스를 변경해야 할 것입니다. 이처럼 구체적인 Class Robot에 참조를 갖는 것이 아니라 Robot의 상위 개념인 toy라는 interface 혹은 abstract class를 만들어서 해당 interface/abstract class를 참조하라는 말입니다. 그러면 가지고 노는 장난감이 아무리 추가되고 삭제되더라고 Kid 클래스는 변경하지 않아도 됩니다.

'프로그래밍 기초' 카테고리의 다른 글

AWS S3에 파일 업로드: pre-signed URL  (0) 2023.08.28
GraphQL 맛보기  (0) 2023.08.24
PostgreSQL vs MySQL  (0) 2023.08.12
Socket.IO 소개 3 - adapter  (0) 2023.07.28
Socket.IO 소개 2 - Event  (0) 2023.07.28