Uncle Bob's BlogPUSHER.COM을 참고했습니다.

1. What is Business Rules?

System Architecture에 대해 얘기하기 전에 Software Development에서의 Business Rule이란 무엇인지 알아보겠습니다.

"business rule"(혹은 "business logic") 이라는 것은
application의 특정 부분을 뜻하며
application이 어떻게 작동해야 하는지에 대한 핵심 행동(core behavior)을 나타냅니다.

보통 business rule은 고객의 요구가 변경될 때마다 바뀔 수 있습니다.
그렇기 때문에 필요에 따라 수정할 수 있게끔 special place(tier)에 배치해야 합니다.

non-business software도 business rule을 갖습니다.
예를 들어, 유저가 xyz를 할 때, application은 무엇인가를 인증해야 한다는 rule이 있다면 이것은 business rule으로 분류될 수 있습니다.

parsing / processing / data access 같은 Utility code는 business rule로 분류되지 않습니다.

2. What is Systam Architecture?

System Architecture는 시스템의 구조(structure), 행위(behavior), 뷰(views)를 정의하는 conceptual model입니다.

시스템의 목적을 달성하기 위해 시스템의 각 컴포넌트가 무엇이며
어떻게 상호작용하는지, 정보가 어떻게 교환되는지를 설명합니다.

System Architecture의 목적
Separation of Concern(관심사의 분리)입니다.

소프트웨어를 계층으로 나눔으로써 관심사를 분리합니다.
그리고 business rules을 위한 하나 이상의 계층과
인터페이스를 위한 또 다른 계층을 두고 있습니다.

Clean Architecture 뿐만 아니라 많은 System Architecture들은 다음 특징들을 갖는 시스템을 생성합니다.

  1. Independent of Frameworks
    System Architecture는 소프트웨어 라이브러리 존재 여부에 의존하지 않습니다. 이는 시스템을 프레임워크의 한정된 제약에 억지로 집어넣는 대신 도구로써 사용하는 것을 가능하게 합니다.
  2. Testable
    business rules는 UI, DataBase, Web Server, 기타 외부 요인없이 테스트가 가능합니다.
  3. Independent of UI
    시스템의 나머지 부분을 변경할 필요 없이 UI를 쉽게 변경할 수 있습니다.
  4. Independent of Database
    Oracle 또는 SQL Server를 MongoDB, BigTable, CouchDB 등으로 바꿀 수 있습니다. business rules는 DB에 얽매이지 않습니다.
  5. Independent of any external agency
    실제로 business rules은 외부 세계에 대해 아무것도 모릅니다.

이제 수많은 System Architecture들 중 Robert C. Martin이 공개한 Clean Architecture에 대해 설명하겠습니다.

3. what is Clean Architecture?

clean-architecture-ex-3.png

inner circle은 application의 domain layer를 뜻하며 이곳에 business rules가 존재합니다. 번역앱은 번역을 하고 온라인 쇼핑몰은 물건을 팝니다. 이러한 business rules은 매우 안정적인 성격을 띕니다. 왜냐하면 app이 하는 일의 본질을 자주 바꾸지는 않기 때문입니다.

outer circle 은 infrastructure입니다. UI, the database, web APIs, and frameworks 들이 이곳에 속합니다. domain layer에 존재하는 것보다는 바꿀 일이 많습니다. 예를 들어, 대출 계산 방법보다는 UI button을 바꿀 일이 많은 것 처럼요.

domain과 infrastructure 사이의 경계에서는 domain이 infrastructure에 대해 모르도록 설정합니다. UI 와 database는 business rules에 의존하지만 business rules는 UI, database에 무관하기 때문입니다.
UI가 web interface이던 mobile app이던 desktop app이던
data가 저장되는 곳이 SQL이던 NoSQL이던 Cloud이던 domain 관점에서는 중요하지 않습니다.

이런 Architecture는 infrastructure를 바꾸기 쉽게 합니다.
이러한 규칙을 Dependency Rule이라고 합니다.

The Dependency Rule
위 그림의 원들(Circles)은 소프트웨어의 각기 다른 영역을 나타내고 있습니다. 바깥쪽으로 향할수록 고수준의 소프트웨어 입니다. 바깥쪽의 원은 메커니즘(Mechanism)이고 안쪽의 원은 정책(Policy)입니다.

이 아키텍처를 작동하게 하는 중요한 규칙이 바로 Dependency Rule입니다.
이 규칙에 의해서 소스 코드는 안쪽을 향해서만 의존할 수 있습니다. 안쪽의 원은 바깥쪽의 원에 대해 전혀 알지 못합니다. 특히, 바깥쪽의 원에서 선언된 어떠한 "이름"도 안쪽 원에서 참조해서는 안됩니다. 여기서 말하는 "이름"은 function, class, variable 등 이름이 붙은 모든 software entity들을 말합니다.

위 그림을 재정의 해보겠습니다.
clean-architecture-ex-4.png

위 그림의 domain layer는 entities 와 use cases로 다시 나눌 수 있습니다. 그리고 adapter layer는 domain layer와 infrastructure layer 사이에 경계를 형성합니다.

clean_architecture.png

Entities
entity는 related business rules의 집합입니다. Application 기능에 중요한 역할을 합니다. OOP language에서 the rules for an entity는 class에서 method로 함께 그룹화됩니다. application이 없더라도 rule들은 여전히 존재합니다.

예를 들어, 대출에 10% 이자를 부과하는 것은 은행이 가진 규칙입니다.
이것을 컴퓨터로 처리하느냐 서면으로 처리하느냐의 차이만 있을 뿐입니다.
다음 그림은 entity class의 예제입니다.
clean-architecture-ex-5.png
entity는 다른 계층에 대해 아무 것도 모릅니다. 즉, 바깥 계층에서 선언된 class나 component를 사용하지 않습니다.

Use Cases
use case는 특정 Application의 business rules입니다. 어떻게 시스템을 자동화하는지 알려주며 Application의 동작을 결정합니다. 다음은 한 use case에 대한 business rules 예제입니다.

    Gather Info for New Loan

    Input:  Name, Address, Birthdate, etc.
    Output: Same info + credit score

    Rules:
      1. Validate name
      2. Validate address, etc.
      3. Get credit score
      4. If credit score < 500 activate Denial
      5. Else create Customer (entity) and activate Loan Estimation

use case는 entities에 의존하는 동시에 상호작용(interact)합니다. 그리고 이들 또한 더 바깥 계층에 대해 아무 것도 알지 못합니다.
위를 예로 들면, 대출이 web page에서 이뤄지든 iPhone app에서 이뤄지든 use case에서 상관할 바가 아니기 때문입니다. 또한, 대출과 관련된 data가 cloud에 저장되는지 SQLite에 저장되는지는 관심이 없습니다.

다만, 이 계층에서는 바깥 계층에서 사용할 수 있는 abstract classes를 가지거나 interfaces를 정의합니다.

Adapters
The adapters (interface adapters)는 the domain 과 the infrastructure 사이의 번역기입니다.
예를 들어, GUI로부터 input data를 받아 use cases와 entities에 편리한 form으로 repackage합니다.
그런 다음 use cases와 entities의 출력을 가져와 GUI에 표시하거나 데이터베이스에 저장하기에 편리한 형식으로 다시 패키징합니다.

infrastructure
이 계층은 모든 I/O component들(the UI, database, frameworks, devices, etc.)이 있는 곳입니다. 이 계층의 것들은 변화할 가능성이 매우 높기 때문에, 그것들은 가능한 한 더 안정적인 도메인 계층으로부터 멀리 유지됩니다. 분리되어 있기 때문에, 비교적 쉽게 변경하거나 하나의 구성요소를 다른 구성요소와 교환할 수 있습니다.