본문 바로가기
프로그래밍 놀이터/디자인 패턴, 리펙토링

[책 정리] 29. 클린 임베디드 아키텍처 - Clean Architecture

by 돼지왕 왕돼지 2022. 11. 10.
반응형

 

-

소프트웨어는 닳지 않지만, 펌웨어와 하드웨어에 대한 의존성을 관리하지 않으면 안으로부터 파괴될 수 있다.

 

 

-

ROM 에 상주하는 코드만이 펌웨어는 아니다.

저장되는 위치가 펌웨어를 정의하지는 않는다.

이보다는 무엇에 의존하는지, 그리고 하드웨어 발전에 맞춰 수정하기가 얼마나 어려운지에 따라 정의된다.

하드웨어는 발전할 수밖에 없고, 그러한 현실을 염두에 두고 임베디드 코드를 구조화할 수 있어야 한다.

 

 

-

펌웨어는 더 적게 만들고, 소프트웨어는 더 많이 만들어내야 한다.

 

 

 

앱-티튜드 테스트

 

-

캔드 백(Ketn Back)은 소프트웨어를 구축하는 세 가지 활동을 다음과 같이 기술했다.

1. "먼저 동작하게 만들어라."

2. "그리고 올바르게 만들어라"

    코드를 리펙토링해서 타인이 이해하기 쉽게 만들고, 요구가 변경되거나 요구를 더 잘 이해하게 되었을 때 코드를 개선할 수 있게 만들어라.

3. "그리고 빠르게 만들어라."

    코드를 리펙토링해서 '요구되는' 성능을 만족시켜라

 

 

-

프로그래머가 오직 앱이 동작하도록 만드는 일만 신경 쓴다면 자신의 제품과 고용주에게 몹쓸 짓을 하는 것이다.

 

 

 

타깃-하드웨어 병목현상

 

-

임베디드가 지닌 특수한 문제 중 하나는 타깃-하드웨어 병목현상(target-hardware bottleneck)이다.

임베디드 코드가 클린 아키텍처 원칙과 실천법을 따르지 않고 작성된다면, 대개의 경우 코드를 테스트할 수 있는 환경이 해당 특정 타깃으로 국한될 것이다.

그리고 그 타깃이 테스트가 가능한 유일한 장소라면 타깃-하드웨어 병목현상이 발생하여 진척이 느려질 것이다.

 

 

* 클린 임베디드 아키텍처는 테스트하기 쉬운 임베디드 아키텍처다.

 

** 계층

 

-

소프트웨어와 펌웨어가 서로 섞이는 일은 안티 패턴(anti-pattern)이다.

 

 

** 하드웨어는 세부사항이다.

 

-

소프트웨어와 펌웨어 사이의 경계는 잘 정의하기가 힘들다.

임베디드 소프트웨어 개발자가 해야 할 일 하나는 이 경계를 분명하게 만드는 것이다.

소프트웨어와 펌웨어 사이의 경계는 하드웨어 추상화 계층(Hardware Abstraction Layer, HAL)이라고 부른다.

HAL 은 자신보다 위에 있는 소프트웨어를 위해 존재하므로 HAL 의 API 는 소프트웨어의 필요에 맞게 만들어져야 한다.

 

 

* HAL 사용자에게 하드웨어 세부사항을 드러내지 말라

 

 

* 프로세서는 세부사항이다.

 

-

마이크로 컨트롤러를 사용할 떄, 펌웨어가 저수준 함수들을 프로세서 추상화 계층(Processor Abstraction Layer, PAL)의 형태로 격리시켜줄 수 있다.

PAL 상위에 위치하는 펌웨어는 타깃-하드웨어에 관계없이 테스트 할 수 있게 되어 펌웨어 자체도 덜 딱딱(firm)해질 수 있다.

 

 

* 운영체제는 세부사항이다.

 

-

HAL 은 필수적이다.

코드가 운영 환경에 깊숙이 종속되지 않도록 만드는 데 HAL 만으로도 충분할 것이다.

하지만 임베디드 시스템에서 실시간 운영체제(Real-Time Operating System, RTOS)를 사용하거나, 임베디드 버전의 리눅스/윈도우를 사용한다면?

작성한 코드의 수명을 늘리려면, 무조건 운영체제를 세부사항으로 취급하고 운영체제에 의존하는 일을 막아야 한다.

 

클린 임베디드 아키텍처는 운영체제 추상화 계층(Operating System Abstraction Layer, OSAL)을 통해 소프트웨어를 운영체제로부터 격리시킨다.

 

 

-

코드 비대화(code bloat) 문제가 염려되기 시작할 수 있다.

OSAL 은 테스트 지점을 만드는 데 도움이 되며, 그 덕분에 소프트웨어 계층의 귀중한 앱 코드를 타깃이나 OS 에 관계없이 테스트할 수 있게 된다.

클린 임베디드 아키텍처를 따른 소프트웨어는 타깃 운영체제에 관계없이 테스트할 수 있다.

 

 

* 인터페이스를 통하고 대체 가능성을 높이는 방향으로 프로그래밍하라.

 

-

HAL, OSAL 뿐만 아니라, 주요 계층(소프트웨어, OS 펌웨어, 하드웨어) 내부에는 이 책에서 설명한 각종 원칙들을 적용할 수 있다.

이들 원칙은 관심사를 분리시키고, 인터페이스를 활용하며, 대체 가능성을 높이는 방향으로 프로그래밍하도록 유도한다.

 

 

-

계층형 아키텍처(layered architecture)는 인터페이스를 통해 프로그래밍하자는 발상을 기반으로 한다.

모듈들이 서로 인터페이스를 통해 상호작용한다면 특정 서비스 제공자를 다른 제공자로 대체할 수 있다.

 

 

-

인터페이스 정의는 헤더 파일에 해야 한다.

하지만 이 경우 헤더 파일에 무엇을 포함시켜야 할지는 신중하게 정해야 한다.

헤더 파일에는 함수 선언과 그 함수에서 사용하는 상수와 구조체 이름만 포함시켜야 한다.

오직 구현체에서만 필요한 데이터 구조, 상수, 타입 정의들로 인터페이스 헤더 파일을 어지럽히지 말라.

이는 단순히 어수선해지는 문제로 끝나지 않고, 결국 원치 않는 의존성을 만들어낼 것이다.

구현 세부사항의 가시성을 제한하라.

 

 

* DRY 원칙: 조건부 컴파일 지시자를 반복하지 말라

 

-

$ifdef 와 같은 조건부 컴파일 블록은 DRY(Don't Repeat Yourself)를 위배한다.

 

 

 

결론

 

-

모든 코드가 펌웨어가 되도록 내버려두면 제품이 오래 살아남을 수 없게 된다.

오직 타깃 하드웨어에서만 테스트할 수 있는 제품도 마찬가지다.

클린 임베디드 아키텍처는 제품이 장기간 생명력을 유지하는 데 도움을 준다.

 

 

반응형

댓글