NGMsoftware

NGMsoftware
로그인 회원가입
  • 매뉴얼
  • 학습
  • 매뉴얼

    학습


    기타 2부 - 개발자라면 알아야 하는 기본 원칙. (SOLID)

    페이지 정보

    본문

    안녕하세요. 엔지엠소프트웨어입니다. 오늘은 OOP 개발 방법론에서 설계 단계에서 적용해야 하는 기본 원칙에 대해 알아보도록 하겠습니다. SLOID에 대해 검색해보면 수많은 글들이 검색될겁니다. 그만큼 보편화된 개념이기도하고, 실무에서도 많이 사용되고 있습니다. 개발자라면 은연중에 이미 습관적으로 사용하고 있기도 합니다. 그렇지만, 객체 지향 개발 방법론을 제대로 이해하고, 설계해 나간다면 한단계 발전한 프로그램을 만들 수 있을겁니다. 가볍게 읽어보세요^^

    Tw9O8lK.jpg

     

     

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

    클래스(또는 모듈, 함수등등...)는 하나의 기능만 제공하고 책임질 수 있어야 합니다. 코드를 변경할 때 여러 기능이 하나의 클래스에 구현되어 있으면 변경할 필요가 없는 기능에 문제가 발생할 수 있습니다. 예를들어 급여라는 클래스가 있다고 가정해봅시다. 이 클래스는 직원들에게 기본급을 주고, 직급에 따라 보너스 적용율을 달리해서 지급합니다. 여기서 급여 클래스는 2가지 책임을 가지고 있습니다. 기본급과 보너스죠. 회사가 급성장해서 CEO는 기본급을 10% 올려주고 싶어합니다. 하지만, CFO(재무 책임자)는 1회성인 보너스를 10% 올려주길 바랍니다. 여기서 기본급에 연동해서 보너스 요율이 적용되도록 만든 급여 클래스는 문제가 발생할 확률이 높습니다. 이런 문제를 방지하기 위해 기본급과 보너스를 분리해야 합니다. 다른 예시로 출력이라는 클래스가 있다고 가정해봅시다. 문서 내용과 문서 디자인이 하나의 클래스로 구성되어 있는데요. 여기서 디자인을 변경하면서 내용에 영향을 주면 안됩니다. 이 클래스도 내용과 디자인으로 분리할 수 있습니다. 내용과 디자인은 엄연히 다른 책임을 담당하고 있기 때문입니다.


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

    개방 폐쇄 원칙은 확장에 대해 열려 있어야 하고, 수정에 대해서는 닫혀 있어야 한다는 OOP의 핵심 원칙중 하나입니다. 이 원칙은 클래스 또는 모듈의 동작을 확장할 수 있다는 것을 의미하며 소프트웨어의 요구 사항이 변경될 때 새로운 동작을 추가해서 기능을 확장할 수 있어야 합니다. 수정에 대해서는 클래스 또는 모듈의 소스 코드를 직접 수정하지 않아도 기능을 확장하거나 변경할 수 있어야 한다는 뜻입니다. 즉, 코드 수정이 없이 확장될 수 있도록 작성되어야 합니다. C++, C#과 Java에서는 추상화를 통해 이 원칙을 지킬 수 있습니다. 추상 클래스를 정의하고, 상속 받아서 확장합니다. 폐쇄는 추상 클래스 또는 클래스에서 동작에 추상 메소드(Abstract)와 가상 메소드(Virtual)로 처리가 가능합니다. 변경은 재정의(Override)와 New로 구현합니다. OCP는 객체 지향 프로그래밍의 핵심 원칙이지만, 이 원칙을 따르지 않는다고 해서 객체 지향 언어(C++, C#, Java등등)로 구현이 불가능한건 아닙니다. 이 원칙을 잘 지키면 유연성, 재사용성, 유지보수성을 얻을 수 있습니다.


    3. LSP(Liskov Substitution Principle, 리스코프 치환 원칙)

    OOP에서 가장 난해한 원칙입니다. 우리가 개발하면서 자주 겪게(경험) 되는 문제 상황이 리스코프 치환 원칙을 지키지 않으므로 발생합니다. 일반적으로 프레임워크 또는 공통 모듈에서 제공하는 함수를 사용하게 됩니다. 이 때 개방 폐쇄 원칙에 따라 함수를 제정의해서 사용합니다. 상속 받은 함수를 제정의할 때 제약사항을 자식도 따라야 한다는 원칙입니다. 일반적으로 많이 사용하는 예제가 직사각형과 정사각형입니다. 정사각형은 4변의 길이가 같다는 제약사항이 존재합니다. 이를 직사각형으로 치환하면 4변의 길이에 대해 차이가 발생하므로 기존 프로그램에서 에러가 발생할 수 있습니다. 좀 더 자세한 내용은 아래 잘 정리된 블로그가 있으니 참고하시면 좋을듯합니다.

    [ 리스코프 치환 원칙 ]


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

    큰 인터페이스들을 작게 나눠서, 고객들이 관심있는 인터페이스에만 연결 되도록 해야 한다는 원칙입니다. 큰 인터페이스는 불필요한 메소드를 구현하게 강제하거나 의존성을 높여 리팩토링, 수정, 재배포를 어렵게 만듭니다. 핸드폰을 만든다고 생각해봅시다. 2G부터 5G까지 통신할 수 있는 핸드폰이라면 어떻게 해야 할까요? SRP에 따르면 통신이라는 기능에 2G~5G까지 연결할 수 있는 메소드를 제공할것입니다. 하지만, ISP 입장에서는 2G, 3G, 4G, 5G를 연결할 수 있는 각각의 인터페이스를 제공해야 합니다. 항상 최신폰만 사용하는건 아니기 때문인데요. 4G까지만 지원하는 구형 핸드폰을 사용할수도 있기 때문입니다. 만약, 모든 인터페이스를 묶어놓으면 2G폰이나 3G폰도 4G와 5G를 모두 구현해야 합니다. 물론, 내용이 없는 메소드를 만들겠지만요. 현업에서 이런 경우가 비일비제하게 발생합니다.


    5. DIP(Dependency Inversion Principle, 의존성 역전 원칙)
    의존 관계를 갖는 클래스 또는 모듈이 추상화에 의존하는 것을 말합니다. 의존성 역전 원칙은 여러가지 방법으로 구현할 수 있습니다. 일반적으로 많이 사용하는게 인터페이스 주입(Interface Injection)입니다. 저도 인터페이스 주입을 많이 사용하는 편입니다. 이외에도 생성자 주입(Constructor Injection), 속성 주입(Property Injection), 메소드 주입(Method Injection)이 있습니다. 자바 스프링의 경우 어노테이션 주입(Annotation Injection)을 사용합니다.

     

    객체 지향 개발 방법론은 SOLID말고도 수없이 많은 방법론들이 존재합니다. 대표적인 5가지를 묶어서 SOLID로 표현하고 있는데요. 솔리드만 잘 지키더라도 상당히 좋은 품질의 프로그램을 작성할 수 있게됩니다. 물론, 현업에서 원칙들을 어떻게 적용시켜야할지 잘 모를겁니다. 오랬동안 운영해온 시스템이고 대부분의 업무가 파악되었다면 적용시킬 수 있는 부분들이 눈에 보일겁니다. 그래서, 새로운 프로젝트의 경우 소통이 가장 중요한 덕목중에 하나입니다. 대부분의 프로젝트가 실패하는 원인은 소통의 부제라고 생각하기 때문입니다. 다음 시간에는 객체 지향 프로그래밍의 5대 원칙에서 벗어나지만, 실제로 코딩 단계에서 작용할 수 있는 DRY, KISS, YAGNI에 대해 알아보겠습니다.

     

    개발자에게 후원하기

    MGtdv7r.png

     

    추천, 구독, 홍보 꼭~ 부탁드립니다.

    여러분의 후원이 빠른 귀농을 가능하게 해줍니다~ 답답한 도시를 벗어나 귀농하고 싶은 개발자~

    감사합니다~

    • 네이버 공유하기
    • 페이스북 공유하기
    • 트위터 공유하기
    • 카카오스토리 공유하기
    추천0 비추천0

    댓글목록

    등록된 댓글이 없습니다.