본문 바로가기
Software Engineering

객체 지향 프로그래밍의 5원칙(SOLID)

by Doromi 2019. 4. 24.
728x90
반응형

객체 지향 설계를 위해서는 5가지 원칙이 따른다.
(앞글자를 따서 SOLID라고 한다)

 

 

 

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

 

객체는 오직 하나의 책임을 가져야 한다.
(객체는 오직 하나의 변경의 이유만을 가져야 한다.)
다시 말하면 클래스를 수정할 필요가 오직 하나여야한다는 뜻.

예를 들어, 사칙연산 함수를 가지고 있는 계산 클래스가 있다.
이 상태의 계산 클래스는 오직 사칙 연산 기능만을 책임진다.
만일 프로그램이 대대적으로 공사를 들어가게 되더라도 계산 클래스가 
수정될만한 사유는 누가 봐도 사칙연산 함수와 관련된 문제 뿐이다.

이처럼 단일 책임 원칙은 클래스의 목적을 명확히 함으로서 구조가 난잡해지거나
수정사항이 불필요하게 넓게 퍼지는 것을 예방하고 기능을 명확히 분리할 수 있게 한다.

하나의 클래스가 두 가지 이상의 책임을 지니게 되면 클래스의 목적이 모호해지고
기능을 수정할 때 영향을 받는 범위도 커져서 유지보수가 힘들어지며
결국 작성한 본인조차도 이게 정확히 뭐하는 클래스인지 명확히 설명할 수가 없게 된다.


 

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

 

객체는 확장에 대해서는 개방적이고 수정에 대해서는 폐쇄적이어야 한다는 원칙이다.
즉, 객체 기능의 확장을 허용하고 스스로의 변경은 피해야 한다.

예를 들어, 스타크래프트의 유닛을 만든다고 친다.
이동 메소드를 구현하였고, 대상 위치를 인수로 받아 속도에 따라 대상 위치까지 유닛을
길찾기 인공지능을 사용해 이동한다.
하지만 브루들링 같은 유닛의 기묘한 움직임을 구현할 때 애로사항이 꽃필 것이다.
고민하다가 이동 메소드에서 이동 패턴을 나타내는 코드를 별도의 메소드로 분리하고,
구현을 하위 클래스에 맡긴다. 그러면 브루들링 클래스에서는 이동 패턴 메소드만 재정의하면
유닛 클래스의 변경 없이 색다른 움직임을 보여줄 수 있다.

'유닛'클래스의 '이동' 메소드는 수정할 필요조차 없다(수정에 대해선 폐쇄)

'브루들링' 클래스의 이동 패턴 메소드만 재정의하면 그만인 것(확장에 대해선 개방)


 

L - LSP(Lsikov Substitution Principle)  리스코프 치환 원칙


자식 클래스는 언제나 자신의 부모 클래스를 대체할 수 있다는 원칙이다.
즉 부모 클래스가 들어갈 자리에 자식 클래스를 넣어도 계획대로 잘 작동해야 한다는 것.
상속의 본질이다.
이를 지키지 않으면 부모 클래스 본래의 의미가 변해서 다형성을 지킬 수 없게 된다.


 

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


클라이언트에서 사용하지 않는 메소드는 사용해서는 안된다.
그러므로 인터페이스를 다시 작게 나누어 만든다.
ISP를 잘 지키면 OCP도 잘 지키게 될 확률이 비약적으로 증가한다.

예를 들어, 게임을 만드는 데 충돌 처리와 이팩트 처리를 하는 서버를 각각 두고 
이 처리 결과를 모두 클라이언트에게 보내야 한다고 가정한다.
그러면 아마 Client라는 인터페이스를 정의하고 그 안에 충돌전달() 과 이펙트 전달(이펙트)를
넣어 놓을 것이다. 그리고 충돌 서버와 이펙트 서버에서 이 인터페이스를 구현하는 객체를 모아두고
있으며, 때에 따라 적절히 신호를 보낸다.
하지만 이렇게 해두면 충돌 서버에겐 쓸모없는 이펙트 전달 인터페이스가 제공되며,
이펙트 서버에겐 쓸모없는 충돌전달 인터페이스가 제공된다.
이를 막기 위해선 Client 인터페이스를 쪼개 이펙트전달 가능 인터페이스와 충돌전달가능 인터페이스로 나눈 뒤,
충돌에는 충돌만, 이펙트에는 이펙트만 전달하면 된다.
또한 Client 인터페이스는 남겨두 되 이펙트전달가능과 충돌전달가능 이 둘을 상속하면 된다.

 

 

 

D - DIP(Dependency Inversion Principle)  의존성 역전 원칙

추상성이 높고 안정적인 고수준의 클래스는 구체적이고 불안정한 저수준의 클래스에
의존해서는 안된다는 원칙이다.

일반적으로 객체지향의 인터페이스를 통해서 이 원칙을 준수할 수 있게 된다.
상대적으로 고수준인 클라이언트는 저수준의 클래스에서 추상화한 인터페이스만을 바라보기 때문에,

이 인터페이스를 구현한 클래스는 클라이언트에 어떤 변경도 없이 얼마든지 나중에 교체될 수 있다.

 

728x90
반응형

'Software Engineering' 카테고리의 다른 글

Architecture patterns  (0) 2024.04.18
객체 지향 vs 절차 지향  (0) 2019.04.25
Architectural Views  (0) 2019.04.20
Architectural Design  (0) 2019.04.20
System Modeling  (0) 2019.04.20