"비즈니스 로직 계층"이 MVC 애플리케이션에 적합한 위치는 어디입니까?
첫째, 누군가 속이는 소리를 지르기 전에 간단한 제목으로 요약하기가 어려웠습니다. 또 다른 제목은 "도메인 모델과 MVC 모델의 차이점은 무엇입니까?"일 수 있습니다. 또는 "모델이란?"
개념적으로는 모델이 뷰와 컨트롤러에서 사용하는 데이터라는 것을 이해합니다. 그 외에도 모델을 구성하는 요소에 대한 다양한 의견이있는 것 같습니다. 도메인 모델, 앱 모델, 뷰 모델, 서비스 모델 등은 무엇입니까?
예를 들어, 리포지토리 패턴에 대해 묻는 최근 질문에서 리포지토리가 모델의 일부라는 점을 공백으로 들었습니다. 그러나 모델이 지속성 모델과 비즈니스 로직 레이어와 분리되어야한다는 다른 의견을 읽었습니다. 결국 Repository 패턴은 모델에서 구체적인 지속성 방법을 분리해야하지 않습니까? 다른 사람들은 도메인 모델과 MVC 모델 사이에 차이가 있다고 말합니다.
간단한 예를 들어 보겠습니다. MVC 기본 프로젝트에 포함 된 AccountController입니다. 포함 된 계정 코드가 디자인이 좋지 않고 SRP를 위반한다는 의견을 여러 번 읽었습니다. MVC 응용 프로그램에 대해 "적절한"멤버십 모델을 디자인한다면 어떻게 될까요?
모델에서 ASP.NET 서비스 (멤버쉽 공급자, 역할 공급자 등)를 어떻게 분리 하시겠습니까? 아니면 전혀할까요?
내가보기에 모델은 아마도 유효성 검사 논리를 사용하여 "순수"해야합니다.하지만 비즈니스 규칙과 분리되어야합니다 (유효성 검사 제외). 예를 들어 새 계정이 생성 될 때 누군가에게 이메일을 보내야한다는 비즈니스 규칙이 있다고 가정 해 보겠습니다. 그것은 제 생각에 모델에 속하지 않습니다. 그래서 그것은 어디에 속합니까?
누구든지이 문제에 대해 밝힐 관심이 있습니까?
내가 한 방식-그리고 그것이 옳고 그름을 말하는 것이 아닙니다. 내 뷰를 가지고 내 뷰에 적용되는 모델을 갖는 것입니다. 이 모델에는 데이터 주석 및 유효성 검사 규칙을 포함하여 내보기와 관련된 항목 만 있습니다. 컨트롤러에는 모델 구축을위한 로직 만 있습니다. 모든 비즈니스 로직을 수용하는 서비스 계층이 있습니다. 내 컨트롤러는 내 서비스 계층을 호출합니다. 그 너머는 내 저장소 레이어입니다.
내 도메인 개체는 개별적으로 보관됩니다 (실제로 자체 프로젝트에 있음). 고유 한 데이터 주석과 유효성 검사 규칙이 있습니다. 내 저장소는 데이터베이스에 저장하기 전에 내 도메인의 개체를 확인합니다. 내 도메인의 모든 객체는 유효성 검사가 내장 된 기본 클래스에서 상속되기 때문에 내 저장소는 일반적이며 모든 것을 유효성 검사합니다 (기본 클래스에서 상속해야 함).
두 세트의 모델을 갖는 것이 코드의 중복이라고 생각할 수 있으며 어느 정도는 그렇습니다. 그러나 도메인 객체가 뷰에 적합하지 않은 완벽하게 합리적인 경우가 있습니다.
적절한 사례는 신용 카드로 작업 할 때입니다. 결제를 처리 할 때 cvv가 필요하지만 cvv를 저장할 수 없습니다 ($ 50,000의 벌금). 하지만 주소, 이름, 만료일 변경 등 신용 카드를 수정할 수 있기를 바랍니다. 그러나 당신은 그것을 편집 할 때 나에게 번호 나 cvv를주지 않을 것이고, 나는 확실히 당신의 신용 카드 번호를 페이지에 평문으로 넣지 않을 것입니다. 내 도메인에는 새 신용 카드를 제공하는 데 필요한 이러한 값이 있지만 내 편집 모델에는 카드 번호 나 cvv도 포함되어 있지 않습니다.
너무 많은 레이어의 또 다른 이점은 올바르게 설계되면 구조 맵 또는 다른 IoC 컨테이너를 사용하고 애플리케이션에 해로운 영향을주지 않고 조각을 교체 할 수 있다는 것입니다.
제 생각에는 컨트롤러 코드는 뷰를 대상으로하는 코드 여야합니다. 이를 표시하고 숨기는 등의 작업을 수행합니다. 서비스 계층에는 앱의 비즈니스 논리가 포함되어야합니다. 비즈니스 규칙을 쉽게 변경하거나 수정할 수 있도록 모든 것을 한 곳에 모아 두는 것이 좋습니다. 리포지토리 레이어는 비즈니스 로직이없고 데이터를 쿼리하고 도메인 개체 만 반환하는 비교적 멍청해야합니다. 도메인 모델에서 뷰 모델을 분리하면 사용자 지정 유효성 검사 규칙과 관련하여 훨씬 더 많은 유연성을 갖게됩니다. 또한 숨겨진 필드의 뷰에 모든 데이터를 덤프하고 클라이언트와 서버 사이에서 앞뒤로 푸시 (또는 백엔드에서 다시 빌드) 할 필요가 없음을 의미합니다.
<% if (!String.IsNullOrEmpty(Model.SomeObject.SomeProperty) &&
Model.SomeObject.SomeInt == 3 && ...) { %>
모든 것이 흩어져 있고 겹겹이 쌓여있는 것처럼 보이지만, 이런 방식으로 설계되는 목적이 있습니다. 완벽합니까? 별로. 그러나 나는 컨트롤러에서 리포지토리를 호출하고 컨트롤러, 리포지토리 및 모델에서 비즈니스 로직을 혼합하는 과거 디자인보다 선호합니다.
저는 MVC 요소가 뷰 (페이지), 컨트롤러, 서비스 및 데이터 개체 (모델)가있는 전통적인 웹 애플리케이션 구조에 얼마나 정확히 맞는지 궁금해했습니다. 당신이 말했듯이, 그것의 많은 버전이 있습니다.
나는 "빈혈 도메인 모델"(대표 된)-안티 패턴을 사용하는 위에서 언급하고 널리 받아 들여지는 아키텍처 때문에 혼란이 존재한다고 생각합니다. 빈약 한 데이터 모델의 "반 패턴 성"에 대해서는 자세히 설명하지 않겠습니다 ( 여기 에서 설명하기 위해 제 노력을 살펴볼 수 있습니다 (자바 기반이지만 모든 언어와 관련이 있음)). 그러나 간단히 말해 우리 모델은 데이터 만 보유하고 비즈니스 로직은 서비스 / 관리자에 배치됩니다.
그러나 도메인 중심 아키텍처 가 있고 도메인 개체가 상태 및 비즈니스 논리를 모두 갖는 것으로 예상되는 방식 이라고 가정 해 보겠습니다 . 그리고이 도메인 중심의 관점에서 다음과 같은 일이 발생합니다.
- 보기는 UI입니다.
- 컨트롤러는 UI의 입력을 수집하고, 모델에서 메서드를 호출하고, UI에 응답을 보냅니다.
- 모델은 데이터를 보유하면서도 비즈니스 로직도 포함하는 비즈니스 구성 요소입니다.
그것은 당신의 주요 질문에 대한 답이라고 생각합니다. 저장소 레이어와 같은 레이어를 더 추가하면 상황이 복잡해집니다. 모델에 배치 된 비즈니스 로직에 의해 호출되어야하는 경우가 종종 있습니다 (따라서 각 도메인 객체에는 저장소에 대한 참조가 있음). 제가 링크 한 제 기사에서 저는 이것이 최선의 방법이 아니라고 주장합니다. 사실 서비스 계층을 갖는 것은 나쁘지 않습니다. 그건 그렇고, 도메인 중심 설계는 서비스 계층을 배제하지 않고 '얇고'도메인 개체를 조정해야합니다 (비즈니스 로직이 없음).
For the anemic data model paradigm, which is widely adopted (for good or for bad), the model would be both the service layer and your data objects.
In my opinion,
Model -
Should not contain business logic, it should be pluggable(WCF like scenario). It is used to bind to view so, it should have properties.
Business Logic -
It should be placed at "Domain Services Layer", it is separate layer altogether. Also, will add one more layer here "Application Services".
App Services talks to Domain Services layer to apply business logic and then lastly return the Model.
So, Controller will ask Application Service for Model and the flow will go like,
Controller->Application Services(using domain services)->Model
The MVC pattern and the Asp.net framework makes no distinction on what the Model should be.
MS's own examples include persistence classes in the model. Your question about membership being in the model. This depends. Are classes in your model owned by something? Is there a link between who logs in and what data is displayed? Is there filtering of data part of a permissions system that is editable? Is who last updated or edited an object part of your domain as in somebody else needs to see it or something for backend support?
The email example is also it depends. Are you familiar with domain eventing or eventing in particular? Do you have a separate service to send emails? Is the act of sending an email part of your domain or is it a application level concern outside of the scope of your system? Does the UI need to know if an email was sent successfully or not? Do emails that fail to send need retries? Does the content of the email sent need to be stored for support or customer service requirements?
These types of questions are overly broad and subjective but I'm answering so you and everybody who voted you up can understand this.
Your requirements/timelines/resources all bleed into your system's architecture. Even the revenue model can have an effect. You also have to consider the pattern you are shooting for. DDD is much different than persistence-as-model applications and all the slop in between are also valid for certain apps. Are you shooting for testing the app? All of this has an effect.
'developer tip' 카테고리의 다른 글
| 가장 효율적인 스레드 안전 C ++ 로거는 무엇입니까? (0) | 2020.09.17 |
|---|---|
| .js 파일에 상대적인 각도 지시문 templateUrl (0) | 2020.09.17 |
| Keras의 다 대일 및 다 대다 LSTM 예제 (0) | 2020.09.17 |
| Cabal과 Stack의 차이점은 무엇입니까? (0) | 2020.09.17 |
| Visual Studio 2015에서 누락 된 리팩터링 메뉴 (0) | 2020.09.17 |