객체 지향적 설계 원칙 : SOLID
- 앞서 포스팅했던 객체 지향적 사고를 5가지 원칙으로 정의.
- 5가지 항목이 서로 연관되어있어 특정 원칙을 나눠 이해하기보단 종합적으로 이해하는 것이 도움이 됨.
(1) 단일 책임 원칙 (Single responsibility principle; SRP) | 클래스는 단 한 가지의 책임만을 가져야 한다.
* 미 적용 시 문제점 : 하나의 클래스가 여러가지 책임을 가지고 있다면, 수 많은 커스터마이징을 필요로 하는 유지보수 작업들을 처리할 때 이곳 저곳 소스를 헤집어 여러 군데를 수정해야 하는 상황을 초래할 수 있음.
-> 비효율적인 커스터마이징 업무.
* 적용 방안 : 구현 할 당시에는 기능(함수)을 수행하는 역할 별로 세분화하여 코딩하고(ex, MVC), 각 기능에 상세한 명세를 주석으로 추가.
(2) 개방-폐쇄 원칙 (Open-closed principle; OCP) | 기능을 변경하거나 확장할 수 있으면서, 그 기능을 사용하는 코드는 수정하지 않는다.
* 미 적용 시 문제점
1) 다운 캐스팅(이미 캐스팅된 객체를 다시 원래의 상태로 캐스팅하는 작업)을 하게됨.
-> 캐스팅된 객체의 자료형이 모호해짐.
2) 단위 별 수정 사항이 들어왔을 때 마다 실제 기능을 수행하는 함수에서의 수정이 불가피해짐.
-> 수정되야할 부분이 중구난방식이 됨.
* 적용 방안 : 결국은 코드 수정의 유연함을 담아야 하기 때문에, 변화가 예상되는 기능을 추상화(오버로딩, 오버라이딩 등)하여야 함.
(3) 리스코프 치환 원칙 (Liskov substitution principle; LSP) | 상위 타입의 객체를 하위 타입의 객체로 치환해도 상위 타입을 사용하는 프로그램은 정상적으로 동작해야 한다.
* 미 적용 시 문제점 : 상위 타입의 객체 자체가 가지고 있는 기능이 하위 타입으로 인해 변경되어 상위 타입의 객체를 사용하던 기능들이 전체적으로 변경되는 에러가 발생.
-> 기능 변경에 있어 유연함이 떨어져 '개발-폐쇄 원칙'과 같이 중구난방적으로 수정이 필요한 상황을 초래함.
* 적용 방안 : 상위 타입의 객체를 사용하는 기능들을 확인하고나서 고정시켜야 할 공통적인 기능은 상위 타입에 세팅하고 나머지 세부적인 변경 사항들은 하위 타입을 여러 케이스로 만듦. 하위 타입의 세부적인 기능들을 세팅 할 하나의 기준을 잡아 상위 타입에 세팅하는 방법도 있음.
(4) 인터페이스 분리 원칙 (Interface segregation principle; ISP) | 인터페이스는 그 인터페이스를 사용하는 클라이언트를 기준으로 분리해야 한다.
* 미 적용 시 문제점 : Java에선 .class 파일을 로딩하는 과정에 동적으로 링크 과정을 발생시키지만, C/C++ 에서는 링크시키는 과정을 컴파일 시 항상 거치기 때문에, 인터페이스가 분리되어 있지 않으면 하나의 인터페이스에 링크되어있는 소스들 전부가 재 컴파일을 해야하는 상황이 발생.
-> 재 컴파일이 될 필요가 없는 클래스들의 지속적인 재 컴파일로 인한 컴파일 속도 이슈와 '단일 책임 원칙'을 거슬러 각 인터페이스의 책임에 대한 정의가 모호해짐.
* 적용 방안 : '단일 책임 원칙'을 인터페이스에 부여해 각 클래스(클라이언트)의 역활에 따라 인터페이스를 만들어줌.
(5) 의존 역전 원칙 (Dependency inversion principle; DIP) | 고 수준 모듈은 저 수준 모듈의 구현에 의존해서는 안 된다. 저 수준 모듈이 고 수준 모듈에서 정의한 추상 타입에 의존해야 한다.
* 미 적용 시 문제점 : 일정 수준 안정화가 된 프로그램에서의 수정에 있어서 고 수준 모듈(상위 타입, 큰 틀에서의 프로세스)은 최대한 변경을 피하고 저 수준 모듈(하위 타입, 실제 기능을 동작시키는 프로세스)을 변경하여 대처해야 '리스코프 치환 원칙'을 위배하는 경우를 줄이고 변경 범위가 작아질텐데 '의존 역전 원칙'을 어길 시, 개발 수정 범위가 다양한 범위로 늘어남.
-> '리스코프 치환 원칙'과 마찬가지로 개발 수정 범위가 중구난방식으로 유연함이 떨어지고, 작은 단위의 수정 사항에도 패키지 단위로 확장되어 배포해야할 상황의 소프트웨어를 만들어내게 됨.
* 적용 방안 : '리스코프 치환 원칙'을 따라 설계하여 상위 타입은 수정없이 기능을 고정하되, 기능 변경에 대한 요청 사항이 있을 시 하위 타입의 수정을 통해 유연한 기능 변경을 할 수 있도록 추상화를 적절히 사용할 수 있도록 설계해야 함.
※ "코드 변화에 있어 유연한 대처가 가능하도록 설계를 해야한다." - SOLID 원칙
다음 포스트에서는 SOLID 원칙과 더불어 사용되는 DI와 서비스 로케이터에 대해 알아보도록 하자.
출처: 최범균, 『개발자가 반드시 정복해야 할 객체 지향과 디자인 패턴』, 인투북스(2014)
'IT > Design Pattern' 카테고리의 다른 글
객체 지향(Object Oriented) 이란? (0) | 2018.09.18 |
---|---|
디자인 패턴 (Design Pattern) 이란? (0) | 2018.09.17 |