클린 아키텍처 .NET Core(1부: 소개)

작성자

카테고리:

,

원본링크 : Clean Architecture .NET Core (Part 1: Introduction)

클린 아키텍처란?

코드에 다음과 같은 문제가 있습니까?

  1. 자주 버그 생성
  2. 디버깅 및/또는 새 기능 추가는 고통스럽습니다.
  3. 데이터베이스/웹 서버 없이 테스트를 작성할 수 없습니다.
  4. 다른 개발자는 코드의 의도를 이해할 수 없습니다.
  5. 비즈니스 논리와 혼합된 프레젠테이션 논리 또는 데이터 액세스 논리와 혼합된 비즈니스 논리가 있습니다.

축하합니다! 당신은 버그가 많은 코드를 작성합니다! 잠깐만요.. 그래서 그것에 대한 해결책이 없나요? 음.. 모범 사례를 따르기만 하면 됩니다. SOLID 또는 다른 디자인 패턴 과 같습니다 . 그들은 모두 관심의 분리라는 동일한 목표를 가지고 있습니다. 그들은 모두 소프트웨어를 계층으로 나누어 이러한 분리 를 달성합니다. 각각에는 비즈니스 규칙에 대한 계층과 인터페이스에 대한 계층이 하나 이상 있습니다.

유지 관리하기 쉬운 대형 프로젝트를 구축하는 비결은 파일이나 클래스를 다른 구성 요소와 독립적으로 변경할 수 있는 구성 요소로 분리하는 것입니다. 몇 가지 이미지로 설명하겠습니다.

이미지 제공 : pusher.com

이미지 (a)에서 가위를 칼로 교체하려면 어떻게 해야 하나요? 바쁜 직업이라고 해도 과언이 아닙니다. 이미지 (b)에서 가위를 어떻게 교체합니까? 포스트잇 아래에서 가위의 실을 빼내고 칼에 묶인 새 실을 추가하기만 하면 됩니다. 훨씬 더 쉽습니다. Post -it 노트는 끈이 묶여 있지 않기 때문에 신경 쓰지 않습니다.

두 번째 이미지가 나타내는 아키텍처는 분명히 변경하기가 더 쉬웠습니다. 클린 아키텍처 이면의 핵심 규칙 은 정확히 이것 또는 더 기술적으로는 소스 코드 종속성 이 안쪽 만을 가리킬 수 있다고 명시하는 종속성 규칙 입니다. 그래서 이것은 무엇을 의미합니까? 구경하다.

이미지 제공 : fullstackmark.com

내부 원의 어떤 것도 외부 원의 어떤 것에 대해 전혀 알 수 없습니다. 특히 외부 원에서 선언된 이름은 내부 원의 코드에서 언급되어서는 안 됩니다. 여기에는 함수, 클래스가 포함됩니다. 변수 또는 기타 명명된 소프트웨어 엔터티. 요지는 아키텍처 모델의 각 “링”에 종속성이 캡슐화되어 있으며 이러한 종속성은 내부만 가리킬 수 있다는 것입니다.

엔터티: 전사적 비즈니스 규칙을 캡슐화합니다.

엔터티는 애플리케이션 기능에 중요한 관련 비즈니스 규칙 집합입니다. 개체 지향 프로그래밍 언어에서 엔터티에 대한 규칙은 클래스의 메서드로 함께 그룹화됩니다. 적용이 없더라도 이러한 규칙은 여전히 ​​존재합니다.

예를 들어 , 대출에 대해 10%의 이자를 부과하는 것은 은행이 가질 수 있는 규칙입니다. 이는 이자가 종이로 계산되든 컴퓨터를 사용하여 계산되든 마찬가지입니다. 엔티티는 다른 레이어에 대해 아무것도 모릅니다. 그들은 아무것도 의존하지 않습니다. 즉, 외부 계층에 있는 다른 클래스나 구성 요소의 이름을 사용하지 않습니다.

사용 사례 : 애플리케이션별 비즈니스 규칙을 포함합니다.

그들은 시스템을 자동화하는 방법을 알려줍니다. 이는 앱의 동작을 결정합니다. 이러한 사용 사례는 엔터티 간 데이터 흐름을 오케스트레이션하고 해당 엔터티가 전사적 비즈니스 규칙을 사용하여 사용 사례의 목표를 달성하도록 지시합니다. 다음은 샘플 사용 사례입니다.

신규 대출 정보 수집입력: 이름, 주소, 생년월일 등 
출력: 동일한 정보 + 신용 점수규칙:1.이름
확인 2.주소 등 확인 3.
신용 점수 받기
4.신용 점수 < 500인 경우 거부 활성화
5.그렇지 않으면 고객(엔티티) 생성 및 대출 견적 활성화

사용 사례는 엔터티와 상호 작용하고 엔터티에 의존하지만 레이어에 대해 더 이상 알지 못합니다. 웹페이지든 iPhone 앱이든 상관하지 않습니다 . 데이터가 클라우드 또는 로컬 SQLite 데이터베이스에 저장되어 있는지 상관하지 않습니다.

그러나 우리 는 응용 프로그램 작동에 대한 변경 사항이 사용 사례와 이 계층의 소프트웨어에 영향을 미칠 것으로 예상합니다. 사용 사례의 세부 사항이 변경되면 이 계층의 일부 코드가 확실히 영향을 받습니다.

Interface Adapters : 유스 케이스와 엔터티에 가장 편리한 형식의 데이터를 변환합니다.

GUI의 MVC 아키텍처를 완전히 포함하는 것은 이 계층입니다. 발표자, 보기 및 컨트롤러가 모두 여기에 속합니다. 모델은 컨트롤러에서 전달되는 데이터 구조일 가능성이 높습니다.

이 원 안에 있는 코드는 데이터베이스에 대해 전혀 알지 못합니다. 데이터베이스가 SQL 데이터베이스인 경우 모든 SQL은 이 계층으로 제한되어야 합니다.

Frameworks and Drivers : 모든 I/O 구성 요소가 있는 곳.

이 레이어는 모든 세부 사항이 있는 곳입니다. 웹은 세부 사항입니다. 데이터베이스는 세부 사항입니다. 우리는 이러한 것들을 거의 해를 끼치지 않는 외부에 보관합니다. 가장 불안정한 계층입니다. 이 계층의 항목은 변경될 가능성이 높기 때문에 보다 안정적인 도메인 계층에서 가능한 한 멀리 유지됩니다. 그것들은 분리되어 있기 때문에 상대적으로 쉽게 변경하거나 한 구성 요소를 다른 구성 요소로 교체할 수 있습니다. (예: UI, 데이터베이스, 프레임워크, 장치)

교차 경계

위 다이어그램의 오른쪽 하단(아래에 설명됨)에는 원 경계를 교차하는 방법의 예가 있습니다.

다음 계층에서 사용 사례와 통신하는 컨트롤러 및 발표자를 보여줍니다. 제어 흐름에 유의하십시오. 컨트롤러에서 시작하여 사용 사례를 통해 이동한 다음 Presenter에서 실행됩니다. 이것을 어떻게 구현합니까? ” 종속성 역전 원칙 “.

종속성 역전 원칙(DIP)

SOLID의 D입니다. 즉, 덜 안정적인 클래스와 구성 요소는 더 안정적인 클래스와 구성 요소에 의존해야 하며 그 반대는 아닙니다. 안정적인 클래스가 불안정한 클래스에 의존하는 경우 불안정한 클래스가 변경될 때마다 안정적인 클래스에도 영향을 미칩니다. 따라서 종속성의 방향을 반대로 해야 합니다. 이것은 어떻게 이루어 집니까? 추상 클래스를 사용하거나 인터페이스 뒤에 안정적인 클래스를 숨김으로써.

따라서 안정적인 클래스 대신 다음과 같이 휘발성 클래스의 이름을 사용하십시오.

class StableClass {
    void myMethod(VolatileClass param) {
        param.doSomething();
    }
}

휘발성 클래스가 구현하는 인터페이스를 만들 수 있습니다.

class StableClass {
    interface StableClassInterface {
        void doSomething();
    }
    void myMethod(StableClassInterface param) {
        param.doSomething();
    }
}
    class VolatileClass implements StableClass.StableClassInterface {
        public void doSomething() {
          // Do something
        }
    }

예를 들어 사용 사례에서 발표자를 호출해야 한다고 가정합니다. 그러나 이 호출은 종속성 규칙 을 위반하므로 직접 호출해서는 안 됩니다. 외부 원의 이름은 내부 원에서 언급할 수 없습니다. 그래서 우리는 유스 케이스가 내부 원에서 인터페이스(여기서는 유스 케이스 출력 포트 로 표시됨 )를 호출하고 외부 원의 발표자가 이를 구현하도록 합니다.

경계를 넘는 데이터는 무엇입니까?

일반적으로 경계를 넘는 데이터는 단순한 데이터 구조입니다. 원하는 경우 기본 구조체 또는 간단한 데이터 전송 객체를 사용할 수 있습니다. 또는 데이터는 단순히 함수 호출의 인수일 수 있습니다. 또는 해시맵으로 압축하거나 개체로 구성할 수 있습니다. 중요한 것은 격리되고 단순한 데이터 구조가 경계를 넘어 전달된다는 것입니다.

  • 우리는 엔터티 또는 데이터베이스 행을 속이고 전달하고 싶지 않습니다.
  • 우리는 데이터 구조가 종속성 규칙을 위반하는 어떤 종류의 종속성도 가지기를 원하지 않습니다.

결론

The Clean Architecture의 본질은 다음과 같이 요약할 수 있습니다. 같은 시간에 같은 이유로 변경될 수 있는 클래스는 구성 요소로 함께 그룹화해야 합니다. 비즈니스 규칙 구성 요소는 더 안정적이며 UI, 데이터베이스, 웹, 프레임워크 및 기타 세부 사항을 처리하는 보다 변동성이 큰 인프라 구성 요소에 대해 전혀 알지 못합니다. 구성 요소 계층 간의 경계는 계층 간의 데이터를 변환하고 보다 안정적인 내부 구성 요소의 방향을 가리키는 종속성을 유지하는 인터페이스 어댑터를 사용하여 유지됩니다.

다음 위로..

다음 포스트에서는 .NET Core를 사용하여 The Clean Architecture를 구현하려고 합니다.