[C++] 전문가다운 디자인이란?
🌈 프로그래밍/C++

[C++] 전문가다운 디자인이란?

반응형

 

안녕하세요? 수구리입니다.

 

지난 포스팅에서는 3장에 대한 내용을 알아보았었죠?

 

2021.08.29 - [프로그래밍/C++] - [C++] 코딩 스타일에 대하여

 

[C++] 코딩 스타일에 대하여

안녕하세요? 수구리입니다 지난 포스팅에서는 동적 스트링에 대한 마무리를 했습니다..! 2021.08.26 - [프로그래밍/C++] - [C++] 동적 스트링 Part 3 [C++] 동적 스트링 Part 3 안녕하세요! 드디어 이번 포스

tasddc.tistory.com

 

이번 포스팅에서는 디자인과 관련된 내용 총정리입니다..!

 

예시 코드가 많이 없는 부분이라 지루하더라구요..ㅠ

 

그래도 코딩하기 전에 디자인을 가장 중요시해야 한다!라는 점은 명확히 알게 되었습니다!

 

바로 본문으로 가시죠!

 

 

 

4.1 프로그램 디자인의 정의

 

요구사항 분석 단계

  • 프로젝트를 시작하거나 기존의 프로그램을 개선하기 위해서 가장 먼저 할 일은 요구사항을 분석하는 것이다.
  • 요구사항 : 이해 당사자와 논의하는 것
    • 요구사항 분석 단계의 결과는 기능 요구사항 문서이다.
    • 비기능 요구사항 문서도 나올 수 있음
  • 요구사항을 수집한 후, 프로젝트 디자인 단계로 넘어간다.

 

프로젝트 디자인 단계

디자인?

  • 프로그램의 구현 계획을 정리한 것
  • 앞서 도출한 요구사항(기능, 비기능)을 모두 만족하는 프로그램을 구현하기 위한 구조에 대한 명세서
  • 대체로 일반적인 문서로 작성한다.
    • 프로그램을 구성하는 서브시스템 : 인터페이스와 서브시스템 사이의 의존성, 서브시스템 사이의 데이터 흐름, 서브시스템에 대한 입출력, 기본 스레드 활용 모델
    • 서브시스템별 세부사항 : 클래스 구성, 클래스 계층도, 데이터 구조, 알고리즘 등등..
  • 디자인 문서는 대체로 클래스 간의 상호작용을 보여주기 위해서 UML 다이어그램을 사용하기도 한다.

 

 

디자인 과정에서의 핵심은.. 프로그램 작성 전에 생각해보는 것이다!

  • 대표적인 소프트웨어 공학 프로세스 : 스크럼(scrum) 에자일 방법론
    • 스크럼에서는 스프린트(sprint)라는 순환 주기에 따라서 개발 과정을 반복함.
    • 각 스프린트마다 디자인이 변경되거나 새로운 요구사항이 추가되기도 함.

 


 

4.2 프로그램 디자인의 중요성

  • 보통 필자는 여태까지 디자인의 중요성에 대한 내용을 이론과목에서 많이 들었지만, 사실상 디자인을 한 뒤 프로그래밍을 직접 한 경험이 매우 적다..
  • 우선 타이핑을 해보고 수정하고를 반복하기 마련일 것이다.
  • 하지만 위와 같은 방식에는 매우 간단한 프로젝트라도 문제가 발생하기 마련이다.
  • 모든 팀원이 공통적으로 따르는 디자인을 반드시 문서 형태로 마련하고 디자인 패턴에 대한 이해가 충분해야 한다.
  • 프로그램은 요구사항을 만족하기 위해 서브시스템을 구성하고 상호작용하는 방식을 프로그램 디자인으로 표현한다.
  • 디자인 단계를 거치지 않으면 주어진 작업을 처리하기 위한 쉬운 방법을 놓칠 수 있다!!

 


 

4.3 C++에 적합한 디자인 방법

 

C++ 언어의 특성

  • 객체지향 언어이다 그러므로 디자인 단계에서 클래스 계층, 인터페이스, 상호작용을 결정해야 함.
  • 범용성과 재사용성을 높이는 기능을 제공한다.
  • 유용한 표준 라이브러리를 제공한다.
  • 다양한 디자인 패턴이나 널리 알려진 문제 해결 기법을 바로 적용하기 좋다.

 

 

제대로 디자인을 하려면.. 수많은 시행착오가 필요한 것 같다. 앞으로 간단하고 바로 구현할 수 있을 지라도 디자인에 대한 생각을 무조건 해봐야겠다..!!

 


 

4.4 C++ 디자인에 관련된 두 가지 원칙

  • 가장 핵심적인 원칙은 추상화 그리고 재사용이다.
  • 프로그램을 효과적으로 디자인하는 방법을 소개할 때마다 나오는 핵심 내용이므로 잘 알아두자

 

4.4.1 추상화

  • 추상화란 내부 구현외부 인터페이스가 명확히 분리되어있다는 것을 의미한다.
  • 예를 들어 간단하게 TV를 보기 위해 리모컨이라는 인터페이스를 사용하듯이 말이다.

추상화의 장점

  • 내부 구현 방식을 이해하지 않아도 코드를 사용할 수 있다.
  • 내부 구현은 라이브러리 버전마다 달라질 수 있지만, 인터페이스만 그대로 유지된다면 기존 이 함수를 호출한 코드는 아무런 영향을 미치지 않는다.

추상화를 적용하여 디자인하기

  • 함수와 클래스를 디자인할 때는 본인뿐만 아니라 다른 사람이 봐도 내부 구현 사항을 모르더라도 쉽게 사용이 가능해야 한다.
  • 추상화와 객체지향 디자인은 추후 5장에서 자세히 다룰 예정

 


4.4.2 재사용

  • 두 번째로 중요한 원칙인 재사용은 기존 코드를 활용한다는 개념이다.
  • 디자인 단계에서 기존 코드가 있다면 이를 재사용할 수 있는지에 대한 검토가 필요하다.

재사용 가능한 코드 만들기

  • 이 원칙은 내가 작성한 코드뿐 아니라 가져다 쓰는 코드에도 마찬가지로 적용.
  • 즉, 재사용이 가능하도록 디자인해야 한다.
  • C++에서는 범용적으로 만들 수 있도록 템플릿 기능을 제공한다.
template <typename PieceType>
class GameBoard {
    public:
        // 생성자, 소멸자, 대입 연산자 생략
        void setPieceAt(size_t x, size_t y, PieceType* piece);
        PieceType* getPieceAt(size_t x, size_t y);
        bool isEmpty(size_t x, size_t y) const;
    private:
        // 멤버 데이터 생략
};
  • 위의 예시는 2차원 보드를 사용하는 게임이라면 어디서든지 적용할 수 있는 제너릭 한 게임 보드 클래스이다. (6장에서 계속..)

 

디자인 재사용

  • 하지만 앞서 알아본 바와 같이 아무리 좋은 기능, 뛰어난 기능을 제공한다고 해도 경험이 쌓이기 전까지는 결코 쉽지가 않다.
  • 따라서 기존 레시피 즉, 패턴을 활용하도록 하자.
    • 예를 들어 어떤 프로그램이 발생하는 에러를 로그파일에 기록하는 ErrorLogger 객체가 있다고 하자.
    • 프로그램 내에서 그 객체를 사용하는 컴포넌트들이 많다고 할 때, 의존성 주입(dependency injection) 패턴을 이용하면 접근하기 쉽다.
    • 이처럼 여러 패턴과 기법을 익혀두어야 한다.

 


 

4.5 코드 재사용

  • 재사용할 수 있는 코드의 형태와 코드를 재사용할 때의 장단점을 명확히 파악해야 한다.

 

코드의 재사용이 단순하게 기존 코드를 복사해서 붙이는 것이 아님을 명심하자. 정반대로 하나하나 복제하지 않도고 재사용이 가능해야 한다!

 

4.5.1 용어 정리

  • 재사용이 가능한 코드
    1. 예전에 작성했던 코드
    2. 동료가 작정한 코드
    3. 소속 회사나 조직 이외의 서드파티에서 작성한 코드

 

라이브러리와 프레임워크의 차이

 

프로그램은 라이브러리를 활용하고 프레임워크에 맞게 작성함.

라이브러리 : 특정 기능을 제공
프레임워크 : 프로그램의 디자인과 구조에 대한 토대, 뼈대를 제공
  • API(Application Programming Interface)
    • 특정 기능을 수행하는 코드나 라이브러리에 대한 interface
    • 네트워크 프로그래밍에서 소켓 API를 예로 들 수 있음. 이를 사용하기 위한 인터페이스만 제공

 

API와 라이브러리의 차이

 

둘은 서로 다른 개념임에 주의하자!

라이브러리 : 구현을 의미.
API : 이 라이브러리를 외부에 제공하기 위한 인터페이스를 가리킴.

 

4.5.2 코드 재사용의 판단 기준

  • 실제로 적용하다 보면 애매한 부분이 존재함.
  • 다음과 같은 장단점을 잘 파악하자!

코드 재사용의 장점

  • 디자인 과정이 간결해짐
  • 대부분 디버깅 과정이 필요 없음
  • 대부분의 엄격한 테스트 과정을 거쳤으므로 검증됨
  • 해당 분야의 전문가가 작성한 코드를 사용하는 것이 안전
  • 지속적으로 개선됨

코드 재사용의 단점

  • 라이브러리를 사용하기 위한 학습 오버헤드 소요
  • 원하는 목적과 불일치
  • 성능 예측 불가
  • 라이선스 문제
  • 버그 수용 능력이 떨어짐
  • 신뢰할 수 있어야 함
  • 컴파일 업그레이드 시 호환 문제

결국 코드 재사용 여부는 주어진 상황과 목적에 따라 판단해야 한다.
언제든지 결정을 뒤집어도 된다는 것에 명심하자.
왜냐하면 프로그램을 제대로 디자인(추상화)했다면 결정을 바꾸더라도 큰 부담이 없기 때문이다.

 

4.5.3 코드 재사용 전략

  • 코드를 재사용하기 위한 몇 가지 고려사항들에 대해서 알아보자.

기능과 제약사항 파악하기

  • 해당 코드를 충분히 분석한다. 뿐만 아니라 제약사항도 파악.
  • 라이브러리면 어떤 함수가 있는지 파악
  • 프레임워크라면 코드 작성 방식을 익히고 어떤 클래스를 상속, 직접 작성해야 할 부분에 대해 파악

성능 파악하기

  • 코드의 성능이 어느 수준까지 보장되는지 파악
  • 성능에 민감하지 않더라도 특정 상황에서 문제가 없는지 정도로 분석

플랫폼 제약사항 파악하기

  • 라이브러리 코드를 사용하기 전에 그 코드를 실행할 플랫폼부터 확실히 파악
  • 라이브러리조차도 플랫폼마다 미묘한 차이가 날 수 있기 때문이다.

프로토타입

  • 라이브러리 혹은 프레임워크를 처음 사용할 때, 임시 프로그램을 구현해 보는 방법이다.
  • 프로토타입을 만드는 이뉴는 라이브러리의 기능을 파악하는 데 있다.

 

4.5.6 C++ 표준 라이브러리

  • 표준이란 명칭에서부터 예상할 수 있듯이 C++ 표준의 일부이다.
  • 표준 라이브러리는 한 덩어리가 아니라 여러 개의 독립적인 컴포넌트로 구성되어있다. (16장에서 계속)

C 표준 라이브러리

  • C++은 C의 기능을 대부분 포함한다.
  • C++에서 스트링 와 I/O를 C 스타일로 처리가 가능하지만 C++에서 제공하는 스트링과 I/O 스트림을 활용하는 것이 바람직함.

표준 라이브러리의 사용 여부 판단

  • 표준 라이브러리는 기능, 성능, 직교 성을 위주로 디자인한 것
  • 어떤 자료구조를 구현하는 과정에서 발생하는 에러들을 표준 라이브러리를 제대로 활용할 줄 안다면, 이를 쉽게 해결할 수 있다.

 

4.6 요약

  • 가장 중요한 것은 아무리 간단한 프로그램이더라도 디자인 구상을 꼭 반드시 해야 한다는 것이다!
  • 또, 두 가지 디자인 개념을 소개하였다.
  • 인터페이스와 구현을 분리하는 추상화의 원칙과 재사용 원칙이다.
  • 재사용 원칙은 코드 작성 단계뿐만 아니라 디자인 단계에서도 적용된다는 것을 잊지 말자!

 

이상으로 4장에 대한 내용을 마치겠습니다..!

 

좋아요 한 번씩만 감사합니다!

반응형

'🌈 프로그래밍 > C++' 카테고리의 다른 글

[C++] vector 컨테이너 부수기  (0) 2021.09.07
[C++] OOP 디자인의 개념  (0) 2021.09.02
[C++] 코딩 스타일에 대하여  (2) 2021.08.29
[C++] 동적 스트링 Part 3  (4) 2021.08.26
[C++] 동적 스트링 Part 2  (0) 2021.08.25