"비즈니스 로직 레이어"는 MVC 애플리케이션에 적합합니까?


86

첫째, 누군가 속이는 소리를 지르기 전에 간단한 제목으로 요약하기가 어려웠습니다. 또 다른 제목은 "도메인 모델과 MVC 모델의 차이점은 무엇입니까?"일 수 있습니다. 또는 "모델이란?"

개념적으로 나는 모델이 뷰와 컨트롤러가 사용하는 데이터라는 것을 이해합니다. 그 외에도 모델을 구성하는 요소에 대해 많은 의견이 다른 것 같습니다. 도메인 모델, 앱 모델, 뷰 모델, 서비스 모델 등은 무엇입니까?

예를 들어, 최근에 리포지토리 패턴에 대해 물었던 질문에서 리포지토리가 모델의 일부라는 점을 들었습니다. 그러나 모델이 지속성 모델과 비즈니스 로직 레이어와 분리되어야한다는 다른 의견을 읽었습니다. 결국 Repository 패턴은 모델에서 구체적인 지속성 방법을 분리해야하지 않습니까? 다른 사람들은 도메인 모델과 MVC 모델간에 차이가 있다고 말합니다.

간단한 예를 들어 보겠습니다. MVC 기본 프로젝트에 포함 된 AccountController입니다. 포함 된 계정 코드가 디자인이 좋지 않고 SRP를 위반한다는 의견을 여러 번 읽었습니다. MVC 응용 프로그램에 대해 "적절한"멤버십 모델을 디자인한다면 어떻게 될까요?

모델에서 ASP.NET 서비스 (멤버십 공급자, 역할 공급자 등)를 어떻게 분리 하시겠습니까? 아니면 전혀할까요?

내가보기에 모델은 아마도 유효성 검사 논리를 사용하여 "순수"해야합니다.하지만 비즈니스 규칙과 분리되어야합니다 (유효성 검사 제외). 예를 들어 새 계정이 생성 될 때 누군가에게 이메일을 보내야한다는 비즈니스 규칙이 있다고 가정 해 보겠습니다. 그것은 내 관점에서 실제로 모델에 속하지 않습니다. 그래서 그것은 어디에 속합니까?

누구든지이 문제에 대해 밝힐 관심이 있습니까?


1
그래서 네 가지 질문을해야합니다.
John Farrell

3
키워드는 "거의"입니다. 기본 질문을 설명하는 데 사용되는 하위 질문과 함께 실제로 동일한 질문입니다.
Erik Funkenbusch 2010

3
모델-보기-컨트롤러. 저장소 / BL보기입니까? 아니요. 컨트롤러입니까? 아니오. 남은 것은 무엇입니까 :)? MSVC가 아니라 MVC이며 MRVC가 아니라 MBLVC입니다. 세 개의 레이어가 있습니다. 따라서 저장소는 모델의 일부이고 BL은 모델의 일부입니다. 추가로 분리 할 수 ​​있지만 모델 레이어 내부에서 수행됩니다.
LukLed 2010

3
@LukeLed, @bslm-그렇지 않습니다. MVC는 컨트롤러 또는 모델이 상호 작용하는 다른 레이어가있을 수 없다고 말하지 않습니다.
John Farrell

3
@LukLed-동의하지 않음-MVC는 단순히 표현 레이어 패턴입니다. BLL 및 DAL과 같은 다른 계층을 구성하는 방법에는 영향을 미치지 않습니다.
Cory House

답변:


69

내가 한 방식-그리고 그것이 옳고 그름을 말하는 것이 아닙니다. 내 뷰를 가지고 내 뷰에 적용되는 모델을 갖는 것입니다. 이 모델에는 데이터 주석 및 유효성 검사 규칙을 포함하여 내보기와 관련된 항목 만 있습니다. 컨트롤러에는 모델 구축을위한 로직 만 있습니다. 모든 비즈니스 로직을 수용하는 서비스 계층이 있습니다. 내 컨트롤러는 내 서비스 계층을 호출합니다. 그 너머는 내 저장소 레이어입니다.

내 도메인 개체는 별도로 보관됩니다 (실제로 자체 프로젝트에 있음). 고유 한 데이터 주석과 유효성 검사 규칙이 있습니다. 내 저장소는 데이터베이스에 저장하기 전에 내 도메인의 개체를 확인합니다. 내 도메인의 모든 객체는 유효성 검사가 내장 된 기본 클래스에서 상속되기 때문에 내 저장소는 일반적이며 모든 것을 유효성 검사합니다 (기본 클래스에서 상속해야 함).

두 세트의 모델을 갖는 것은 코드의 중복이라고 생각할 수 있으며 어느 정도는 그렇습니다. 그러나 도메인 개체가보기에 적합하지 않은 완벽하게 합리적인 경우가 있습니다.

적절한 사례는 신용 카드로 작업 할 때입니다. 결제를 처리 할 때 cvv가 필요하지만 cvv를 저장할 수 없습니다 ($ 50,000 벌금). 하지만 주소, 이름, 만료일 변경 등 신용 카드를 수정할 수 있기를 바랍니다. 그러나 당신은 그것을 편집 할 때 나에게 번호 나 cvv를주지 않을 것이고, 나는 확실히 당신의 신용 카드 번호를 페이지에 평문으로 넣지 않을 것입니다. 내 도메인에는 새 신용 카드를 제공하는 데 필요한 이러한 값이 있지만 내 편집 모델에는 카드 번호 나 cvv도 포함되어 있지 않습니다.

너무 많은 레이어의 또 다른 이점은 올바르게 설계되면 구조 맵 또는 다른 IoC 컨테이너를 사용하고 애플리케이션에 해로운 영향을주지 않고 조각을 교체 할 수 있다는 것입니다.

제 생각에는 컨트롤러 코드는 뷰를 대상으로하는 코드 여야합니다. 이를 표시하고 숨기는 등의 작업을 수행합니다. 서비스 계층에는 앱의 비즈니스 논리가 포함되어야합니다. 비즈니스 규칙을 변경하거나 조정하기 쉽도록 모든 것을 한곳에 모아 두는 것이 좋습니다. 리포지토리 레이어는 비즈니스 로직이없고 데이터를 쿼리하고 도메인 개체 만 반환하는 비교적 멍청해야합니다. 도메인 모델에서 뷰 모델을 분리하면 사용자 지정 유효성 검사 규칙과 관련하여 훨씬 더 많은 유연성을 갖게됩니다. 또한 숨겨진 필드의 뷰에 모든 데이터를 덤프하고 클라이언트와 서버 사이에서 앞뒤로 밀어 넣거나 (또는 ​​백엔드에서 다시 빌드 할 필요가 없음) 의미합니다.

<% if (!String.IsNullOrEmpty(Model.SomeObject.SomeProperty) && 
    Model.SomeObject.SomeInt == 3 && ...) { %>

모든 것이 흩어져 있고 겹겹이 쌓여있는 것처럼 보이지만, 이러한 방식으로 설계되는 목적이 있습니다. 완벽합니까? 별로. 그러나 나는 컨트롤러에서 리포지토리를 호출하고 컨트롤러, 리포지토리 및 모델에서 비즈니스 로직을 혼합하는 과거 디자인보다 선호합니다.


엔터프라이즈 MVC 응용 프로그램에서 내가 가진 것과 거의 비슷합니다. N-Tier 아키텍처. MVC 앱은 N 계층 영역의 비즈니스 개체 및 서비스와 만 상호 작용합니다.
Ed DeGagne 2013-10-11

여기서 거의 동일합니다. 정의, 모델, 뷰 모델, DAL 등을위한 별도의 프로젝트. 유일한 차이점은 내 DAL에 보고서 또는 사용자 정의 고객 뷰에 대한 복잡한 데이터 배포를 최적화하기 위해 웹용 데이터를 평면화하는 논리가 포함되어 있다는 것입니다. 이제 웹 팜과 Azure 클라우드를 사용하여 조회 테이블 등을 위해 애플리케이션 캐시에 항목을 보관하지 않습니다.
Robert

1
@Josh, 샘플 프로젝트의 스크린 샷을 보여줄 수 있다면 도움이 될까요?
Shaiju T

@Josh 프로젝트에 데이터베이스가 없다면 어떨까요? 서비스 참조와 상호 작용합니다. 모든 도메인 클래스와 메서드는 이러한 참조에서 가져옵니다. 이 시나리오가 계층 구조에 적합합니까?
user6395764

17

저는 MVC 요소가 뷰 (페이지), 컨트롤러, 서비스 및 데이터 개체 (모델)가있는 전통적인 웹 애플리케이션 구조에 얼마나 정확히 맞는지 궁금해했습니다. 당신이 말했듯이, 그것의 많은 버전이 있습니다.

나는 "빈혈 도메인 모델"(대표 된)-안티 패턴을 사용하는 위에서 언급 한 널리 수용된 아키텍처 때문에 혼란이 존재한다고 생각합니다. 빈약 한 데이터 모델의 "반 패턴 성"에 대해서는 자세히 설명하지 않겠습니다 ( 여기 에서 설명하기 위해 제 노력을 살펴볼 수 있습니다 (Java 기반이지만 모든 언어와 관련이 있음)). 그러나 간단히 말해 우리 모델은 데이터 만 보유하고 비즈니스 로직은 서비스 / 관리자에 배치됩니다.

그러나 도메인 중심 아키텍처 가 있고 도메인 개체가 상태 및 비즈니스 논리를 모두 갖는 것으로 예상되는 방식 이라고 가정 해 보겠습니다 . 그리고이 도메인 중심의 관점에서 다음과 같은 일이 발생합니다.

  • 보기는 UI입니다.
  • 컨트롤러는 UI의 입력을 수집하고, 모델에서 메서드를 호출하고, UI에 응답을 보냅니다.
  • 모델은 데이터를 보유하면서도 비즈니스 로직도 포함하는 비즈니스 구성 요소입니다.

나는 그것이 당신의 주요 질문에 대답한다고 생각합니다. 저장소 레이어와 같은 레이어를 더 추가하면 상황이 복잡해집니다. 모델에 배치 된 비즈니스 로직에 의해 호출되어야하는 경우가 종종 있습니다 (따라서 각 도메인 객체에는 저장소에 대한 참조가 있음). 내가 연결 한 기사에서 나는 이것이 최선의 방법이 아니라고 주장한다. 사실 서비스 계층을 갖는 것은 나쁘지 않습니다. 그건 그렇고, 도메인 중심 디자인은 서비스 계층을 배제하지 않지만 '얇고'도메인 개체를 조정하는 것으로 간주됩니다 (따라서 비즈니스 논리가 없음).

널리 채택 된 빈약 한 데이터 모델 패러다임의 경우 (좋든 나쁘 든) 모델은 서비스 계층과 데이터 개체가 될 것입니다.


훌륭한 포인트! 한 가지 말 : 서비스에도 똑같은 혼란이 있습니다. 최소한 서비스는 애플리케이션 서비스 및 도메인 서비스 일 수 있습니다. 애플리케이션 서비스는 저장소 등에서 정보를 수집하는 얇은 래퍼 일뿐입니다. 도메인 서비스는 도메인 모델의 조합 또는 도메인 모델에 항상 맞지 않는 항목 만 사용하는 비즈니스 로직을 제공합니다.
Artru

프로젝트에 데이터베이스가 없으면 어떻게 될까요? 서비스 참조와 상호 작용합니다. 모든 도메인 클래스와 메서드는 이러한 참조에서 가져옵니다. 이 시나리오가 계층 구조에 적합합니까?
user6395764

3

제 생각에는

모델-

비즈니스 로직을 포함하지 않아야하며 플러그 가능해야합니다 (시나리오와 같은 WCF). 보기에 바인딩하는 데 사용되므로 속성이 있어야합니다.

비즈니스 로직-

"도메인 서비스 계층"에 배치되어야하며, 모두 별도의 계층입니다. 또한 여기에 "응용 프로그램 서비스"계층을 하나 더 추가합니다.

App Services는 도메인 서비스 계층과 통신하여 비즈니스 논리를 적용한 다음 마지막으로 모델을 반환합니다.

따라서 Controller는 Application Service에 Model을 요청하고 흐름은 다음과 같이 진행됩니다.

    Controller->Application Services(using domain services)->Model

2

MVC 패턴과 Asp.net 프레임 워크는 모델이 무엇이어야 하는지를 구분하지 않습니다.

MS의 자체 예제에는 모델의 지속성 클래스가 포함됩니다. 회원 자격에 대한 질문입니다. 이것은 상황에 따라 다릅니다. 모델의 클래스가 소유하고 있습니까? 로그인하는 사람과 표시되는 데이터 사이에 링크가 있습니까? 편집 가능한 권한 시스템의 데이터 부분 필터링이 있습니까? 다른 사람이 볼 필요가 있거나 백엔드 지원을 위해 무언가를 볼 필요가있는 것처럼 누가 마지막으로 개체를 업데이트하거나 편집 했습니까?

이메일 예도 다릅니다. 특히 도메인 이벤트 또는 이벤트에 대해 잘 알고 있습니까? 이메일을 보낼 수있는 별도의 서비스가 있습니까? 이메일을 보내는 행위가 도메인의 일부입니까, 아니면 시스템 범위를 벗어난 애플리케이션 수준 문제입니까? UI는 이메일이 성공적으로 전송되었는지 여부를 알아야합니까? 전송에 실패한 이메일은 재 시도가 필요합니까? 지원 또는 고객 서비스 요구 사항을 위해 전송 된 이메일의 내용을 저장해야합니까?

이러한 유형의 질문은 지나치게 광범위하고 주관적이지만 귀하와 귀하를 투표 한 모든 사람이 이것을 이해할 수 있도록 대답하고 있습니다.

요구 사항 / 타임 라인 / 리소스는 모두 시스템 아키텍처로 흘러 들어갑니다. 수익 모델 조차도 영향을 미칠 수 있습니다. 촬영하려는 패턴도 고려해야합니다. DDD는 모델로서의 지속성 애플리케이션과는 많이 다르며 그 사이의 모든 슬롭도 특정 앱에 대해 유효합니다. 앱 테스트를 위해 촬영하고 있습니까? 이 모든 것이 효과가 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.