ViewModel을 Model과 정확히 동일하게 추가하는 것이 좋습니다


16

내 솔루션에 다음 레이어가 있습니다.

  1. App.Domain
  2. App.Service
  3. App.Core (이 App.DataLayer라고도 함)
  4. App.Web

소프트웨어 디자인 패턴은 제 질문이 아닙니다. Domain

public class Foo {
    public int Id {get;set;}
    public int Name {get;set;}
    public int Value {get;set;}
}

뷰 (예 : 홈페이지) 에서이 모델을 사용 Id, Name & Value하고 싶고을 사용하고 싶습니다 . 따라서 ViewModel을 만들려면 다음을 추가하십시오.

public class FooViewModel {
    public int Id {get;set;}
    public int Name {get;set;}
    public int Value {get;set;}
}

좋은 생각입니까? 또는 Foo대신에 FooViewModel?


나는 이것을 이해하지 못한다. Model보통에 전달 되지 View않습니까? 의 필드를 정확히 다시 작성해야하는 이유 ModelView무엇입니까? 우려의 분리가 목표 MVC라면, 어떤 상황에서와 같은 일을 Model하고 View싶습니까? 만약 ViewModel, 둘 다 왜 안 모두 구성 / 확장하여 ModelView?
null

@svidgen의 답변에 대한 내 의견을 읽으십시오
Mehdi Dehghani

관련 문제가 있습니다-모델 (및 데이터베이스)의 유효성 검사 (필수 속성)에 특정 값을 입력해야하지만 상태에서는 볼 필요가 없습니다-따라서 일부 필드를 복사해야합니다. 모델은 모델을 직접 참조하는 것이 아니라 뷰 모델에 있습니다. 그러나 성찰 해보면 이것은 아마도 훌륭하고 실제로 다른 목적을 위해 있기 때문에 DRY를 위반하지 않습니다 (어쨌든 그렇게 나쁘지는 않습니다).
niico

답변:


20

이것은 처음에는 DRY 규칙을 위반하는 것처럼 보일 수 있지만, "유사하고 동일한 코드"가 다른 작업을 수행하거나 독립적으로 변경할 수있는 경우 반드시 "반복적"인 것은 아니라고 주장합니다. 그리고 뷰 모델의 경우, 코드는 "클라이언트"가 보는 것을 정의합니다. 반드시 비즈니스가 말하는 엔티티와 오퍼레이션은 아닙니다. 따라서 종종 "우연히 동일한"모델을 클라이언트 나 인터페이스에 공개합니다. 비즈니스 규칙 및 용어 또는 최종 사용자 용어를 서로 독립적으로 변경할 수 있습니다.

질문을 다시하겠습니다. 도메인이 변경되면 "버전 1"클라이언트가 이전 인터페이스를 계속 사용할 수 있습니까? "핵심 비즈니스 규칙"의 일부가 아닌 인터페이스에서 용어 또는 오퍼레이션을 공개 하시겠습니까? 그 반대?

이러한 종류의 질문을 염두에두고, 뷰의 "기능"이 기본 도메인 모델을 엄격하게 공개하는 것이라면 그렇습니다. 이것은 DRY 규칙을 위반하는 것처럼 보입니다.

또한 일부 언어에서는 멤버 속성과 리플렉션을 사용하여 모델 변경을 통해보다 자연스럽게 변경되는 뷰를 표시 할 수 있습니다. (또는 다른 영리함을 통한 반복 횟수 가 줄어든다 . 그러나 "영리함"은 종종 반복을 정당화하지 못한다.


이전 답변에 대한 의견으로 말했듯이 좋은 언급 된 메모 (투표에 동의)는 범용, 이미징에 대해 이야기하고 있으며 며칠 후 새로운 필드 / 속성을 추가하기로 결정 Foo했으므로 FooViewModel로 사용 하면 클라이언트도 새로운 속성을 얻게되므로이 새로운 보안 필드가 보안 필드 (허가에 대한 참 / 거짓 일 수 있음) 인 경우 어떻게해야합니까?
Mehdi Dehghani

@mehdi 당신은 당신이 추가하려는 필드와 왜 그것이 필드에 속하거나 속하지 않는지에 대해 더 구체적이어야합니다. 또는 일반적으로 우려되는 부분이 있습니다.
svidgen

@mehdi는 최종 사용자가 보안 값을 변경하는 것에 대해 걱정하는 경우 도메인은 사용자가 저장 권한이없는 것을 저장하도록 허용해서는 안됩니다.
svidgen

왜 ViewModel을 사용합니까? 아시다시피, 그중 하나는 보안을위한 것입니다. 예를 들어에서 User edit form, 우리는 IsAdmin이 필드를 안전하게 유지하기 위해 클라이언트 에게 필드를 전달할 필요가 없습니다 . 그래서 이것이 제가 걱정하는 것입니다. 내 하찮은 영어 실력에 죄송하다는 말씀을 드리고 싶습니다.
Mehdi Dehghani

1
다시 말하면, 원래 질문은 완전한 질문이라고 생각합니다. 여기 주석에서 파악하려는 질문은 또 다른 전체 질문입니다. 그리고 의견은 양질의 답변을 얻는 좋은 방법이 아닙니다.
svidgen

2

Foo 인스턴스라는 하나의 속성 만 포함하는 뷰 모델이 있습니다. 이렇게하면 정의에 따라 DRY를 위반하지 않고 Foo가 변경되면 뷰 모델이 자동으로 변경 사항을보고 뷰 모델과 모델의 직접적인 관계가 없어지게됩니다.

내일 뷰에 Foo뿐만 아니라 다른 것을 표시 해야하는 경우 새 속성을 추가하면 뷰 모델의 의도가 여전히 명확하고 Foo와 다른 것이 포함되어 있습니다. Foo의 속성과 관련이없는 다른 속성의 혼합.

뷰 모델을 FooViewModel로 생각하지는 않지만 뷰를 표시 해야하는 관점에서 생각합니다. Foo가 하나만 표시되면 뷰 모델에 Foo라는 하나의 속성이 포함됩니다.

내가 분명히 설명했는지 확실하지 않습니다. 그렇지 않은 경우 알려 주시면 깨어있을 때 다시 말씀 드리고 다시 말씀 드리겠습니다!


-2

FooViewModel이런 식으로 사용 하면 DRY 교장을 위반한다고 말할 수 있습니다. 변경해야 Foo할 경우에도 변경해야 FooViewModel합니다. 나는 당신이 단순히 Foo당신의 관점을위한 모델로 사용하는 것이 더 나을 것이라고 생각합니다 . Foo의 항목과 다른 항목을 표시 해야하는 경우 뷰 모델을 고려하십시오. 예를 들어, 일부 정보를 렌더링하는 데 필요하다고 Foo도에서를 Bar.


에 다른 필드 / 속성을 추가하기로 결정했다면 ViewModel로도 Foo사용했기 때문에이 Foo새로운 필드를 뷰에 전달해야하기 때문에 이것이 실제로는 좋지 않다고 생각합니다. ?
Mehdi Dehghani

뷰가 모델에 의해 노출 된 데이터의 하위 집합 만 사용하는 데 아무런 문제가 없습니다. 더 큰 파울은 Foo과 사이의 결합이라고 생각합니다 FooViewModel. 일반적으로 단일 논리 변경을 위해 여러 파일을 수정하지 않는 것이 좋습니다.
zero_dev

추가 된 필드가 true/false권한 값 또는 이와 같은 보안 필드 인 경우 어떻게해야합니까?
Mehdi Dehghani

View 자체에 이러한 필드를 공개 할 필요는 없지만 악의적 인 사용자가 그러한 변경 사항을 게시하려는 경우를 대비하여 나머지 코드로 인해 사용자가 보안 수준을 변경할 수 없도록해야합니다.
Graham

대량 할당 공격에 개방적인 것처럼 들린다
James
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.