정렬 로직을 모델, 뷰 또는 컨트롤러에 배치해야합니까? [닫은]


157

테이블에서 최종 사용자에게 값을 표시하는 드롭 다운 목록이 있습니다. 이 값을 알파벳순으로 정렬하고 싶습니다.

적절한 MVC 설계에 따르면 정렬 논리를 모델, 뷰 또는 컨트롤러 중 어떤 레이어에 배치해야합니까?

편집 : LarsH의 질문에 "원하는 정렬 순서를 결정하는 코드 또는 정렬을 수행하는 코드를 의미합니까?"


6
의견의 의견 불일치를 해결하기 위해 "정렬 논리"라는 의미를 말하면 도움이 될 것입니다. 원하는 정렬 순서를 결정하는 코드를 의미합니까? 또는 정렬을 수행하는 코드?
LarsH

9
MVC 디자인은 특별하거나 마술적인 것이 아닙니다. 그것은 단지 시작일뿐입니다. 필요에 맞게 만들고 언제든지 리팩토링 할 수 있음을 기억하십시오. 다른 벤더가 컨트롤러에 들어가는 것을 재정의하거나 툴킷의 요구에 따라보기 때문에 계약을 찾기가 어렵다는 것을 알았습니다. 중요한 것은 뷰 / 컨트롤러에서 모델을 분리하는 것입니다. MVP 패턴에서 더 많은 마일리지를 얻을 수도 있습니다. 정확히이 영역에서 좀 더 구체적이라고 생각합니다.
Bill K

9
아마도 이것은 프로그래머에게 마이그레이션해야 할 것입니다.
Alfredo Osorio

57
확실히 컨트롤러에서. 그 또는 모델 중 하나입니다. 아니면보기.
mob

2
절대로 절대로, 절대로, 절대로, 절대로, 절대로, 절대로, 절대로, 절대로, 절대로, 절대로, 절대로, 절대로, 절대로, 절대로, 절대로, 절대로, 절대로, 절대로, 절대로
contactmatt

답변:


49

(참고 :이 인용문과 인용은 @dasblinkenlight의 답변 에서 가져온 것이지만, 우리는 그 해석에 동의하지 않습니다. 그의 게시물을 읽고 자신의 마음을 구성하십시오).

MVC 설명 에 따르면 ,

컨트롤러는 모델의보기 표시를 변경하기 위해 명령을 관련보기로 보낼 수 있습니다 (예 : 문서를 스크롤하여). 모델 상태를 업데이트하는 명령을 모델에 보낼 수 있습니다 (예 : 문서 편집).

정렬 논리 (예 : 정렬 비교기 / 정렬 알고리즘)는 비즈니스 규칙 및 상태 데이터를 포함하므로 모델에 속합니다. 모델 데이터가 정렬되는 방식을 변경하는 것은 "모델의 뷰 표시 표현 변경"범주에 속하기 때문에 컨트롤러는 model.changeSortedState () 메소드를 호출하여 "정렬 수행"을 담당합니다.


8
동일한 데이터를 두 개의 다른보기로 다르게 정렬하려면 어떻게해야합니까?
s4y

model.SortAscending () 및 model.SortDescending ()과 같은 방식으로 수행해야하며 Controller에 의해 호출됩니다.
Brij

1
@Brij 적절한 MVC에서 두 뷰가 동일한 모델을 공유 할 수 없습니까?
KOVIKO

@Sidnicious 다른 매개 변수를 취하는 하나의 정렬 방법을 사용하는 것이 좋습니다. 예를 들어 public void Sort(bool sortByDescending = false), false 인 경우 오름차순으로 정렬합니다. 또는 논리가 매우 다른 경우 두 가지 정렬 방법이 있습니다.
MattMcGowan 10

@Sidnicious에는 정렬 논리를 제외한 모든 것을 단일 세 번째 모델에 위임하는 두 가지 모델이 있습니다. docs.google.com/drawings/d/…
rightfold

62

정렬 순서는 누가 제어합니까?

간단한 MVC 다이어그램( Wikipedia에서 )

1) 데이터 자체의 자연스러운 순서 :

순서는 모델의 일부이므로 거기로 가야합니다. "모든 데이터"의 원시 풀은 정렬 된 순서로 데이터를 리턴하며 정렬 순서를 선택할 인터페이스가 없습니다.

2) 사용자는 데이터를 보는 방법을 제어해야합니다.

뷰는 컨트롤러와 상호 작용하는 인터페이스 (예 : 오름차순 / 내림차순 화살표)를 제공하며 모델은 데이터에서 요청 된 정렬을 수행하기에 충분히 데이터를 이해합니다. 그러나 (1)과 달리 원시 데이터 풀을 정렬 할 필요는 없습니다.

두 경우 모두

뷰는 어떤 정렬 방향이 선택되었는지 표시하는 기능 외에 다른 정렬이 있음을 이해하지 못합니다. 거기에 논리를 넣지 마십시오.

작은 경고

정렬 기능 하나의 상황에서보기에서 순전히 진행될 있습니다 (내가 생각할 수는 있지만 더있을 수도 있습니다).

모든 데이터가 이미 뷰에 있고 정렬을 수행하기 위해 도메인 지식을 사용할 필요가없는 "멍청한"정렬입니다. 예를 들어 매우 간단한 문자열 또는 숫자 비교. 예를 들어, 결과가 여러 페이지로 나눠 질 수있는 웹 페이지의 검색 결과에서는 불가능합니다.


58
보기는 사용자를 볼 수 있습니다!?
Farzher

41
모델이 뷰를 업데이트합니다!?
deceze

13
"wikipedia article"은 "컴포넌트 상호 작용"섹션이 오른쪽에 표시된 다이어그램과 충돌합니다 (방금 게시 한 것). 둘째, 모델은 뷰를 "업데이트"하지 않습니다. 상태가 변경되면 뷰에 알립니다. 보기는 업데이트 방법을 결정합니다. 어. 주위에 떠 다니는 불분명 한 정보가 너무 많을 때 왜이 질문에 1000 개의 다른 답변이 있는지 궁금합니다.
KyleM

4
@cHao 물론입니다. 우리는 Wikipedia 그래프가 꽤 이상하다는 데 동의 할 수 있습니다. :)
사망

6
@StephenSarcsamKamenar 및 기타 모든 사람 : 아니요, 이미지는 완벽하게 이해됩니다. 코드 연결이 아니라 데이터 흐름을 보여줍니다 .
이즈 카타

18

MVC 설명 에 따르면 ,

컨트롤러는 모델의보기 표시를 변경하기 위해 명령을 관련보기로 보낼 수 있습니다 (예 : 문서를 스크롤하여). 모델 상태를 업데이트하는 명령을 모델에 보낼 수 있습니다 (예 : 문서 편집).

이에 따르면, 정렬 논리는 컨트롤러에 속합니다. 모델 데이터가 정렬되는 방식을 변경하는 것은 "모델의 뷰 표시 표현 변경"범주에 속하기 때문입니다.

편집 : 주석에서 언급 된 여러 오해를 명확히하기 위해 "정렬 논리"는 정렬을 수행하는 코드 가 아닙니다 . 정렬 을 정의 하는 코드입니다 . 정렬 논리는 개별 항목을 서로 비교하여 순서를 설정하거나 (예 :의 인스턴스를 통해 IComparator<T>) 외부 시스템에 의해 (예 :의 인스턴스를 통해) 주문에 사용되는 객체를 구성하는 논리를 포함 IOrderedQueryable<T>합니다. 이 로직은 애플리케이션의 "비즈니스"측면과 관련된 지식이 필요하기 때문에 컨트롤러에 속합니다. 정렬을 수행하는 것으로는 충분하지만 실제로 수행 하는 코드와는 별개입니다.그것. 정렬 된 코드는보기, 모델 또는 모델을 뒷받침하는 지속성 계층 (예 : SQL 데이터베이스)에있을 수 있습니다.


12
-1이 인용문에서 어떻게 이것을 관리 했습니까? 컨트롤러가 모델에서 정보를 검색해야한다고 어딘가에 있습니까? 컨트롤러는 상태를 변경하는 명령을 보냅니다. 정보 추출 또는 조작에 대해서는 언급 된 바가 없습니다.
tereško

3
@ tereško 컨트롤러가 모델에서 정보를 검색해야한다는 내 대답에서 어떻게 결론을 내렸습니까? "정렬 논리"는 C # 용어로 순서를 설정하는 데 필요한 논리 만 구현한다는 의미입니다 IComparer<T>. 모델에서 데이터 검색을 포함하여 정렬의 나머지 "보일러 판 역학"은보기에 달려 있습니다.
dasblinkenlight

3
".. 정렬 논리가 컨트롤러에 속합니다." " 이것은 무엇을 의미합니까?
tereško

3
"컨트롤러는 뷰의 프리젠 테이션을 변경하기 위해 관련 뷰로 명령을 보낼 수 있습니다"는 컨트롤러의 명령에 대한 응답으로 뷰가 정렬하는 것처럼 들립니다.
사무엘 에드윈 워드

1
@KyleM 그러나 뷰가 항상 정렬 논리를 포함하기에 충분한 지식을 가지고있는 것은 아닙니다. 예를 들어, 열거 형 중 하나에 해당하는 숫자 코드가있는 필드를 고려하십시오 {Unknown, Pass, Fail}. 또한 Unknown사용자가 선택한 오름차순 또는 내림차순에 관계없이 항상 마지막으로 정렬해야 한다고 가정 하십시오. 이 논리를 뷰에 배치하면 code필드 내부의 데이터 비즈니스 특성에 대해 너무 많은 정보를 볼 수 있습니다 . 보기는이를 알 수 없습니다. 사용자가 "정렬"제스처를 수행한다는 것만 알고 있으면됩니다 (예 : 헤더 클릭). 나머지는 컨트롤러에 달려 있습니다.
dasblinkenlight

10

위의 어느 것도 아닙니다. 정렬은 비즈니스 로직이며 비즈니스 로직은이 세 가지 중 하나에 속하지 않습니다. 응용 프로그램의 모든 코드가 모델, 뷰 또는 컨트롤러가되는 것은 아닙니다.

MVC 앱에서 일반적으로하는 일은 모든 비즈니스 로직을 수행하는 서비스 계층이 있다는 것입니다. 서비스 계층의 메소드에는 매개 변수가 이름이 지정된 깨끗하고 간단한 API가 있어야합니다. 그런 다음 컨트롤러에서 해당 메소드를 호출하여 모델의 데이터를 조작 할 수 있습니다.

그런 의미에서 정렬은 "컨트롤러에서"이지만 정렬을 수행하는 코드 자체는 컨트롤러에서 구현되어서는 안되며 여기서 만 호출해야합니다.


5
최근에 일부 사람들은 "서비스 계층"(비즈니스 로직)을 모델의 일부로 간주한다고 들었습니다.
Marvo

@Marvo 특정 논리 조각이 데이터 유형과 밀접하게 연결되어 하나의 클래스로 함께 캡슐화하는 것이 합리적 인 경우가 있다고 생각합니다. (예 : 시간 및 날짜 기능). 그러나 일반적으로 모델 객체가 데이터를 보유하고 있지만 아무것도하지 않을 때 가장 잘 작동합니다.
nont

그렇다면 MVC 패턴에서 비즈니스 로직은 어디에 존재합니까?
Marvo

2
애플리케이션이 MVC 패턴을 사용한다고해서 애플리케이션의 모든 코드가 모델, 뷰 또는 컨트롤러가되는 것은 아닙니다. 말 그대로 디자인 패턴을 취하고 있습니다. 예를 들어, 응용 프로그램에 일종의 구성 파일이있을 수 있습니다. 이 구성 파일은 사용자 데이터를 모델링하거나 뷰를 표시하거나 모델을 통해 뷰로의 데이터 흐름을 제어하지 않습니다. 구성 파일은 자체 종류의 것입니다.
nont

모델의 구성 파일 부분을 쉽게 고려할 수 있습니다. 모델은 데이터베이스 일 필요는 없습니다. 나는 당신이 옳고 그름을 말하는 것이 아닙니다. 나는 최근에 (내가 똑같은 견해를 가졌기 때문에) 주제를 조금 구글에 올려 놓고 다른 사람들이 말하는 것을 보라고 제안했다.
Marvo

8

분명히 컨트롤러가 아님 : 메시지를보고 모델로 보내지 만 가능한 한 적은 작업을 수행해야합니다. 사용자가 정렬을 변경할 수있는 경우 해당 요청은 모델 또는 이에 대한보기를 알려 컨트롤러에 의해 처리됩니다.

순수한 View 일 경우 View 일 수 있습니다. 응용 프로그램이 정렬없이 잘 작동하면 정렬은 표현의 일부일 뿐이며보기로 이동해야합니다.

순서가 도메인의 고유 부분 인 경우 모델로 이동해야합니다.


"비교 자 또는 정렬 설명자 제공"이 "작업 수행"으로 간주됩니까? 정렬 논리는 비교기 또는 정렬 설명자에 캡슐화되므로 정렬 방법 또는 모델의 백엔드에서 "정렬 작업"을 수행하더라도 마찬가지입니다.
dasblinkenlight

제공한다는 의미에 따라 다릅니다 : 전달해도됩니다. 그러나 비교기는 컨트롤러가 아닌 모델 또는 뷰의 일부 여야합니다.
Jens Schauder

6
  • 뷰는 프리젠 테이션 로직을 포함해야하는 MVC의 일부입니다.
  • 모델 계층은 비즈니스 로직이 포함 된 곳입니다.
  • 컨트롤러는 사용자 입력에 따라 두 상태 만 변경합니다.

선택은 도메인 비즈니스 로직 또는 프리젠 테이션 로직의 일부라고 생각합니까?

적절한 MVC Model2 또는 클래식 MVC 패턴을 구현하는 경우 모델 계층에서 제공 한 데이터의 순서는 모델 계층에 대한 뷰 요청에 의해 트리거되어야한다고 말합니다. 보기는 주문 된 데이터를 요청하고 모델 계층에서 제공합니다.

그러나 표준 MVC와 약간 다른 MVC 패턴의 ASP.NET MVC 해석을 사용하고 있기 때문에 ViewModel 인스턴스는 모델 계층에서 순서 정보를 요청해야합니다 (어떤 이유로 ASP.NET 프레임 워크는 템플릿을 호출해야한다고 생각합니다) "조회수"와 "조회수"는 "조회수"라고해야합니다.


12
당신은 "정렬 논리"가 의미하는 바에 대한 자신의 가정 을 적용하여 여러 답변을 하향 조정했습니다 . 정렬 논리에는 검색이 포함되지 않으며 결코 포함되지 않습니다.
dasblinkenlight

1
@dasblinkenlight, yes, 컨트롤러가 정렬을 수행해야 함을 암시했기 때문에 여러 주제를 다운 투표했습니다. 어느 것이 잘못 되었습니까? 그리고 .. 사람들 .. 당신이 동의하지 않기 때문에 내 의견을 표시 중지하십시오.
tereško

분명히하기 위해 : 귀하의 답변이 정확하지 않기 때문에 답장하지 않았으며, 어떤 식 으로든 모욕적이라고 생각하지 않기 때문에 귀하의 의견을 결코 표시하지 않았습니다. 솔직히, 나는 당신의 대답이 어떻게 많은 다운 보트를 얻었는지 모르겠습니다.
dasblinkenlight

@dasblinkenlight naah .. 나는이 주제에서 사라진 내 의견에 대해 격노했다.
tereško

5

나는 보통 다른 답변에 따라 패턴과 일치하도록 컨트롤러에서 수행합니다. 추론에 대해서는 아래를 참조하십시오.

나는 이것을 숙고하고 답변과 관련 자료를 읽고 실용적으로 말하면 예를 들어 귀하의 응용 프로그램에 달려 있다고 말할 것입니다.

중형 / 대형 응용 프로그램이거나 여러 UI가 연결되어 있습니까 (예 : Windows 앱, 웹 인터페이스 및 전화 인터페이스).

  • 이 경우 서비스 계층을 구성하여 비즈니스 오브젝트에 넣은 다음 컨트롤러에서 적절한 메소드를 호출합니다.

잘 정의 된 단일 UI 웹 사이트이고 EF Code First와 같은 것을 사용하고 있고 서비스 계층을 만들려는 의도가 없거나없는 경우 간단한 확장 방법을 사용하여이를 달성 할 계획입니다.

  • 이 경우 아마도 컨트롤러를 시간 / 예산과 관련하여 실용적으로 가장 적합하게 넣었을 것입니다.

위의 BUT와 동일한 경우 즉시 사용 가능한 확장 방법으로 구현할 수 없습니다.

  • 컨트롤러보다 여기에 더 적합하기 때문에 Model 클래스에 실제로 표시하도록 선택할 수 있습니다 (단일 유형에 맞는 경우). 정렬을 둘 이상의 클래스에 적용 할 수 있다면 확장 메서드에서 구현 한 다음 컨트롤러에서 호출합니다.

요약하면 :

교의 답변 : 서비스 계층

실용 답변 : 일반적으로 컨트롤러


"보기 위해 데이터 준비"를 담당하는 정의 컨트롤러는 무엇입니까?
tereško

1
@ tereško : 변형 섹션의 msdn.microsoft.com/en-us/library/ff649643.aspx 에 설명 된대로 모델이 "수동적"인 경우 "HTTP는 이에 대한 예"를 참조하십시오. 순수 주의자가 이의를 제기 할 수는 있지만 MVC에서 시작하는 초보자는 컨트롤러에서 직접 EF 또는 다른 모델을 사용하고 BAL을 통하지 않고이 방식으로 생각하여 패턴을 더 이해하는 데 대한 장벽을 낮추는 MVC에서 시작하는 것이 더 쉬울 수 있습니다.
Luke Baughan

1
당신이 말하는 것은 "무기 모델"입니다.
tereško

지적한대로 문제의 설명을 제거했습니다. 입력을 응원합니다!
Luke Baughan

3

드롭 다운 목록에 유용 할 정도로 작은 테이블 데이터에서 데이터를 정렬하는 것이 좋습니다. 이미 쿼리를 통해 정렬 된 DB에서 가져와야합니다. 나에게 그것은 정렬이 적용되는 장소를 모델로 만든다.

손으로 정렬하기로 결정했다면 모델이나 컨트롤러를 선호하는 로직으로 사용하는 것에 대한 좋은 주장이 있다고 생각합니다. 제한은 특정 프레임 워크입니다. 모델에서만 데이터를 관리하는 것을 선호합니다. 컨트롤러를 사용하여 (자기) 가르쳐 왔던 것처럼 데이터 (모델) 및 프레젠테이션 (보기)을 결혼시킵니다.


2

정렬이 Business Logic이라는 아이디어에 원칙적으로 동의하지만, 정렬 방식을 원점으로 분류하면 "고객이 제품 페이지에 날짜별로 정렬 된 이미지가 표시되도록 할 것"과 같은 결과를 얻게됩니다. 데이터에 대한 정렬 순서는 일반적으로 임의적이지 않습니다. 정렬이없는 경우에도 누락에 의한 비즈니스 결정이므로 비어있는 목록은 여전히 ​​목록입니다.

그러나 ...이 답변은 ORM 기술의 진보를 고려하지 않는 것 같습니다 .Entity Framework와 관련하여 만 이야기 할 수 있습니다 (이것이 참 ORM인지 여부에 대한 논쟁은 피하십시오). 그것이 제가 사용하는 것이지만 다른 ORM도 비슷한 기능을 제공합니다.

MS MVC와 Entity Framework를 사용하여 Product 클래스에 대해 Strongly Typed 뷰를 만들고 Product와 Image 테이블 (예 : FK_Product_Image_ProductId)간에 외래 키 관계가 있으면 즉시 정렬 할 수 있습니다. 뷰에서 다음과 같은 것을 사용하여 디스플레이하는 동안 이미지 :

@foreach(Image i in Model.Image.OrderBy(e => e.DisplayOrder)){ //etc etc... }

비즈니스 로직의 80 %를 수행하는 데 사용하는 특정 Business Logic 계층에 대한 언급이 있었지만 기본 제공되는 것을 모방하는 정렬 기능을 Business Logic 계층에 쓰지 않습니다. Entity Framework에서.

나는이 질문에 대한 정답이 아니라고 생각합니다. 복잡한 비즈니스 로직을 가능한 한 추상화해야하지만 휠을 재발 명하는 비용은 발생하지 않아야합니다.


나는 똑같은 생각을하고 있었고 여기에 대한 답변은 ORM 및 확장 방법을 고려하지 않는 것 같습니다. 대부분의 경우 정렬 로직은 다음과 같이 간단합니다. myList.OrderBy(x => x.CreationDate)실제로이를 수행하기 위해 불필요한 추가 레이어를 도입 할 필요가 없습니다. 이 외에도 페이지 및 정렬 된 데이터가 필요한 경우 어떻게해야합니까? 전체 테이블을 쿼리하고 정렬 한 다음 필요한 것을 유지합니까? 하나만 호출 myList.OrderBy(x => x.Date).Skip((page-1)*pageSize).Take(pageSize)하면 불필요한 데이터가 검색되지 않습니다.
Balázs

1

MVC 웹 사이트, WebForms 웹 사이트 및 모바일 애플리케이션이 있다고 가정하십시오.

이러한 프리젠 테이션 레이어간에 정렬을 일관되게하려면 프리젠 테이션 레이어 외부에서 정렬이라고합니다. 서비스는 좋은 후보가 될 것입니다.

그렇지 않으면 해당 논리를 뷰 모델에 저장합니다. 왜? 재사용이 가능하고 쉽게 테스트 할 수 있기 때문입니다.


0

나열된 세 가지 중에서 컨트롤러에 속한다고 말할 수 있습니다. 그래도 컨트롤러에 이런 종류의 논리를 배치하는 것을 좋아하지 않습니다. 나는 보통 컨트롤러가 통신하는 서비스 계층을 만들어 데이터 저장소와 통신하고 정렬 논리를 처리합니다. 작은 응용 프로그램의 경우 컨트롤러에 앉아 있으면 좋습니다.


2
그것은 논리를 모델 측에 더 많이 넣을 것입니다. 맞습니까?
Ryan Kohn

예, "서비스 계층"에 대한 이해는 모델의 일부라는 것입니다.
Marvo

0

이것은 asp.net을 염두에두고 묻는 질문이지만 누군가 Rails를 언급했기 때문에 그 맥락에서 문제를 고려하는 것이 흥미로울 것이라고 생각했습니다. Rails에서는 프레임 워크와 ActiveRecord / ActiveQuery API가이를 제공하기 때문에 컨트롤러 작업으로서 검색과 함께 정렬을 수행하는 것이 자연스럽고 일반적입니다. 반면에 정적 항목에 대한 일종의 사용자 지정 정렬 순서를 정의하고 컨트롤러에서 사용할 모델에 넣을 수 있으므로 모델이 수행하지 않아도 정렬 논리의 일부를 재생할 수 있습니다 직접 작업. 그것이 무엇이든간에, 정렬 논리를보기에 넣는 것은 일반적으로 싫은 것이라고 말할 수 있습니다.

나는 약간의 대답이 컨트롤러 또는 모델에 정렬하는 것에 절대적으로 반대하고 내 취향에 너무 관대하다고 생각하지만 사용 된 프레임 워크의 특성과 관련된 일반적인 규칙에 달려 있다고 가정합니다. 그것. 나는 또한 분리를하는 것이 더 중요하다는 Bill K의 의견에 동의합니다.

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