20240205_SOLID원칙

2024. 2. 5. 22:33IT/TIL

오늘의 TIL은 저번주의 객체지향과 관련된 내용으로 SOLID 원칙에 관한 내용이다.

 

SOLID 원칙

SOLID 원칙이란 객체지향 프로그래밍 설계 원칙으로,

유지 보수가 가능하고 확장 가능한 소프트웨어를 만들기 위해 사용하는 원칙이다.

 

1. S : 단일 책임 원칙(Single Responsibility Principle)

하나의 클래스는 하나의 책임만 가져야 한다는 원칙이다.

각 클래스는 한 가지 목적을 위해 존재하고, 변경의 이유는 하나이어야 한다는 뜻이다.

 

하나의 클래스에 너무 많은 기능을 갖게 한다면 해당 클래스에 대한 의존도가 강해지게 되므로

연결되 기능이 너무 많아지게 된다면 해당 기능들을 총괄하는 클래스를 만들고,

각 기능들을 각각의 클래스로 만들어서 관리하도록 작업해야한다.

 

예를 들어서 Player의 클래스를 만드는 경우,

Player의 클래스 안에 Audio, Input, Movement 등의 기능이 전부 들어가야한다면

각각의 기능들을 함수로 만들어 따로 보관하고,

Player는 해당하는 컴포넌트들을 들고 필요한 경우에 이들을 호출하는 방식으로 만들어야 한다.

 

 

2. O : 개방-폐쇄 원칙(Open-Closed Principle)

확장에는 열려있지만, 수정에는 닫혀있어야 된다는 원칙이다.

기존의 코드를 변경하지 않고도 새로운 기능을 추가할 수 있도록 설계되어야 한다는 뜻이다.

이 경우에는 추상 클래스 혹은 인터페이스를 활용하면 좋다.

 

 

3. L : 리스코프 치환 원칙(Liskov Substitution Principle)

하위 클래스는 상위 클래스의 기능을 완전히 대체할 수 있어야 한다는 원칙이다.

이는 상속 관계에서 어떤 클래스든지 자신의 부모 클래스로 취급될 수 있어야 함을 의미한다.

(상속을 통해서 함수가 달라지면 안된다는 뜻이다)

 

리스코프 치환 원칙을 어기는 사례

  1. 자식 클래스를 만들면서 피처를 제거하는 경우
  2. 자신 클래스의 일부를 예외로 처리하는 경우
  3. 구현은 있으나 구현이 공백인 경우

리스코프 치환 원칙을 지키는 방법

  1. 추상화를 간단하게 유지
  2. 하위 클래스에서 public 멤버 추가를 지양
  3. 현실의 분류에 몰두하지 않는다.
  4. 컴포지션을 적극적으로 활용한다.
  5. 인터페이스를 사용한다.

 

 

I : 인터페이스 분리 원칙(Interface Segregation Principle)

클라이언트는 자신이 사용하지 않는 인터페이스에 의존하지 않아야 한다는 원칙이다.

여러 개의 인터페이스로 분리함으로써 클라이언트는 필요한 기능에만 의존할 수 있다.

 

범용의 인터페이스 하나보다 특정 클라이언트를 위한 여러 개의 인터페이스 분리가 좋다.

 

예를 들어서 핸드폰을 만드는 경우에

전화 기능, 블루투스 기능, 생체인식 기능, 와이파이 기능 등이 있는 경우

각각의 기능들을 인터페이스로 분리하여 구현한 뒤에

핸드폰에서 이들을 사용하는 상속받아서 사용하는 것이 좋다는 의미이다.

 

이렇게 구현한다면 새로운 기능이 추가되었을 때, 그 기능을 추가할 수도 있으며

반대로 기능을 덜어내고 적은 기능을 갖고 있는 핸드폰도 만들 수 있다.

 

 

D : 의존 역전 원칙(Dependency Inversion Principle)

의존 관계는 추상화에 의존해야하며, 구체화에는 의존해서는 안된다는 원칙이다.

즉, 상위 수준의 모듈은 하위 수준의 모듈에 의존해서는 안되며,

추상화(인터페이스)에 의존해야 한다는 뜻이다.

다시 말해서 구현 클래스(구현체)가 아니라 인터페이스(역할)에 의존하라는 뜻이다.

 

예를 들어서 야구에서 4번 타자를 기용하는 경우에

특정 선수를 써야한다는 것이 아니라 장타율이 높고 홈런을 잘 치는 선수를 써야한다는 뜻이다.

 

또다른 예로 Switch와 Door를 들 수 있는데,

Switch의 Toggle 상태에 따라서 Door가 Open 되거나 Close되게 되어 있다.

(Switch - 4번 타자라는 자리(혹은 타순), Door - 기용되는 선수)

(Switch - HigherLevel, Door - LowerLevel)

이후에 다른 Switch를 사용하는 것(Laser, Button 등)이 추가된다면

ISwitchable이라는 새로운 interface를 만들어서 나눠주는 것이 좋다.

 

 

 

오늘까지해서 CS지식의 기초라고할 수 있는

 

클래스와 객체, 객체지향 프로그래밍, SOLID 원칙을 알아봤는데,

 

두번째 정리하고 있지만 아직까지도 정확하게 이해하지 못한 부분이 있다고 느껴진다.

 

추후에 다시 정리하면서 지금은 이해하지 못했던 부분을 다시 이해할 수 있는 시간을 갖도록 할 예정이다.