태그 보관물: design-patterns

design-patterns

.NET MVC 프로젝트 아키텍처 / 계층화 자동차를 필터링합니다.var cars

중규모 MVC 웹 응용 프로그램의 아키텍처를 계획 할 때 가능한 한 분리되고 테스트하기 쉬운 계층을 어떻게 구현합니까? (기본적으로 모범 사례를 따르십시오) 먼저 데이터 액세스로 코드를 사용한다고 가정 해 봅시다.

“비즈니스 로직”을 정의하는 것과 데이터 계층과 상호 작용하는 방법에 대해 고민합니다. 차량 판매 애플리케이션을 예로 들어, 비즈니스 로직은 주어진 차량에 대한 세금 대역 계산, 갤런 당 마일 통계 비교 등과 같은 작업을 수행하는 클래스입니까? 비즈니스 엔티티 (예 : Cars, Vans, Motorcycles)에 대해서는 DataContext클래스 와 함께 데이터 계층에 넣습니다 .

또한 비즈니스와 달리 응용 프로그램 논리를 구성하는 것은 무엇입니까? 세션 / 사용자 입력 유효성 검사와 같은 것을 추측하고 있습니까?

예를 들어, 자동차 컨트롤러는 유형 및 최고 mpg로 필터링 된 상위 10 대 자동차를 나열하는 동작 /보기 결과를 반환 할 수 있습니다. 그래서 ICarRepository컨트롤러에 ‘carRepo’를 주입 했다고 가정 하고 (저장소 패턴 / DI를 사용하여) 액션 메소드 매개 변수에서 자동차를 필터링합니다.var cars = carRepo.getCarsByType("hatchback");

따라서 저장소를 사용하여 컨트롤러에서 데이터 액세스 지식을 유지했습니다. 이제 도메인 모델을 사용하여 비즈니스 로직을 컨트롤러에서 유지합니다. var result = new MpgCalculator (cars); -DB에서 엔티티를로드 / 필터링하는 것보다 최상의 연료 효율을 계산하기 위해 추가 논리를 수행해야하기 때문에 계산기 클래스가 필요하다고 가정 해 봅시다. 이제 저장소를 사용하여 데이터 액세스 계층에서 검색하고 해당 데이터에서 비즈니스 관련 작업을 처리하고 수행하는 도메인 특정 개체를 렌더링하는 뷰에 대한 데이터 세트가 있습니다.

내가 실수를 저지르고 있습니까? 우리는 여전히 저장소 패턴을 사용해야합니까, 아니면 ORM과 테스트를 분리하기 위해 인터페이스에 대해 코딩 할 수 있습니까? 이 주제에서는 구체적인 데이터 액세스 클래스 dbcontext가 데이터 계층에 있으므로 인터페이스 정의가 도메인 / 비즈니스 계층으로 이동해야하는데 이는 데이터 액세스 기술이 변경 되어도 다른 계층에 영향을 미치지 않습니까?

지금까지 내가 연구 한 내용에서 내 구조는 다음과 같습니다.

MVC 인터넷 애플리케이션 -> 표준 인터넷 프로젝트-여기 모델은 ViewModels입니다

도메인 / 비즈니스 계층 -> 관련 뷰로 전달하기 전에 컨트롤러가 데이터 계층에서 도메인 엔티티를 처리하는 데 사용할 수있는 비즈니스 특정 클래스 / 모델

리포지토리 추상화가 필요합니까? -> 특히 ORM을 사용할 때 이것에 대해 많은 토론을 듣는다

데이터 계층 -> 엔티티 클래스 (Car, Van, Motorcycle), DbContext-콘크리트 데이터 액세스 기술 계층



답변

당신은 당신의 질문에 많은 움직이는 부분을 가지고 있으며, 많은 개념을 다루고 있지만, 중대형 MVC 응용 프로그램에 대해 생각하는 방법에 관한 기본 조언은 다음과 같습니다.

프리젠 테이션 <—> 비즈니스 로직 <—> 데이터 액세스

먼저, 앱을 “MVC 애플리케이션”으로 생각 하지 않는 것이 가장 좋습니다 . MVC 패턴을 프리젠 테이션 컴포넌트로 사용하는 애플리케이션입니다. 이런 식으로 생각하면 비즈니스 로직 문제와 프레젠테이션 문제 를 분리하는 데 도움이됩니다 . 아마도 소규모 응용 프로그램이 데이터베이스 액세스에 이르기까지 모든 것을 MVC 구조에 쌓아 두는 것이 좋지만 중대형 응용 프로그램에서는 신속하게 고정 할 수 없게 될 것입니다.

MVC (프레젠테이션)

앱에서 ASP.NET MVC 구성 요소는 표시 목적 (모델), 사용자 인터페이스 표시 (보기) 및 라우팅, 인증, 권한 부여, 요청 유효성 검사, 응답 처리 및 통신 문제와 같은 통신 문제를 위해 비즈니스 데이터 변환을 처리해야합니다. (컨트롤러)와 같습니다. 다른 작업을 수행하는 코드가 있으면 MVC 구성 요소에 속하지 않습니다 .

리포지토리 / ORM (데이터 액세스)

또한 앱에서 데이터 액세스 계층은 영구 데이터를 검색하고 저장하는 데 관심이 있어야합니다. 일반적으로 이는 관계형 데이터베이스의 형태이지만 데이터를 유지할 수있는 다른 많은 방법이 있습니다. 영구 데이터를 읽거나 저장하지 않는 코드가있는 경우 해당 코드는 데이터 영역에 속하지 않습니다 . 나는 이전에 SO 에 대한 ORM / 리포지토리 토론에 대한 생각을 공유 했지만, 요약하자면, ORM이 여러 가지 이유로 리포지토리와 동일한 것으로 간주하지 않습니다.

비즈니스 로직

이제 프리젠 테이션 레이어 (MVC)와 데이터 레이어 (리포지토리 또는 ORM)가 있습니다. 그 밖의 모든 것은 비즈니스 로직 레이어 (BLL)입니다. 검색 할 데이터를 결정하거나 복잡한 계산을 수행하거나 비즈니스 결정을 내리는 모든 코드가 여기에 있어야합니다. 나는 일반적으로 비즈니스 로직을 ‘서비스’형식으로 조직하는데, 프리젠 테이션 레이어는 요청 된 작업을 수행 할 수 있습니다. 내 모든 도메인 모델이 여기에 있습니다.

당신의 접근

이것은 당신의 접근 방식이 나를 위해 약간 분해되는 곳입니다. MVC 컨트롤러 를 저장소에서 데이터를 가져올 장소로 설명 하고 MPGCalculator를 호출하여 일부 작업 등을 수행하십시오. 컨트롤러 가이 작업을 수행하지는 않지만 대신이 모든 것을 서비스에 위임합니다. BLL에서.

즉, 저장소에 MPGCalculator를 컨트롤러에 주입하지 않으므로 컨트롤러에 너무 많은 책임이 부여됩니다 ( 위에서 언급 한 모든 컨트롤러 항목을 이미 처리하고 있습니다 ). 대신 BLL에 서비스를 제공하여 그 모든 것을 처리하고 결과를 컨트롤러로 다시 전달합니다. 그런 다음 컨트롤러는 결과를 올바른 모델로 변환하고 올바른 뷰로 전달할 수 있습니다. 컨트롤러에는 비즈니스 로직이 없으며 컨트롤러에 주입 된 것은 적절한 BLL 서비스뿐입니다.

이 방법을 사용하면 비즈니스 로직 (예 : 차량 세트, MPG 계산 및 최악으로 정렬 )이 프리젠 테이션 및 지속성 문제와 무관합니다. 일반적으로 데이터 지속성 전략이나 프레젠테이션 전략을 모르거나 신경 쓰지 않는 라이브러리에 있습니다.


답변

모든 것이 구조에 맞는 것처럼 보입니다. 확실하지 않은 유일한 것은 MVC의 모델이 “ViewModels”이고 컨트롤러가 도메인 계층과 통신한다고 언급 한 것입니다. 기본 패턴이 컨트롤러를 사용하여 도메인 계층에 액세스 한 다음 “ViewModels”를 여러 도메인 엔터티의 더 많은 뷰별 정보 컴파일로 사용하는 것이 특정 뷰에 적합하다면 이것이 의미가 있다고 생각합니다. 그것이 당신이하고있는 일이라면 괜찮을 것입니다.

MVC 응용 프로그램에 도메인 계층을 완전히 추상화해야한다고 생각하는 학교가 있습니다. 개인적으로 엔터프라이즈 응용 프로그램에서 그렇게하면 심각한 정신적 고통이 발생합니다.

테스트 가능성과 유연성을 향상시키기 위해 리포지토리 패턴을 사용하여 데이터 계층에 대한 액세스를 관리하는 것이 좋습니다. 가장 급격한 변화를 일으키는 두 가지 요소는 UI와 데이터베이스입니다. 데이터베이스에서 직접 가져 오는 일부 정보가 데이터베이스 호출이 아닌 서비스 호출에서 검색되도록 변경되거나 일부 정보가 다른 .edmx가 필요한 다른 데이터베이스로 이동 된 경우를 상상해보십시오. 파일. 저장소 패턴은이를 지원하기위한 추상화를 제공합니다.


답변