비즈니스 로직을 모델에 넣는 이유는 무엇입니까? 여러 유형의 스토리지가있는 경우 어떻게됩니까?


70

나는 항상 비즈니스 로직이 컨트롤러에 있어야하고 컨트롤러가 '중간'부분이기 때문에 정적 상태를 유지하고 모델 / 뷰가 인터페이스를 통해 캡슐화되어야한다고 생각했습니다. 이렇게하면 다른 어떤 것도 영향을주지 않고 비즈니스 로직을 변경할 수 있고, 여러 모델 (각 데이터베이스 / 스토리지 유형마다 하나씩)과 수십 개의 뷰 (예 : 다른 플랫폼의 경우)를 프로그래밍 할 수 있습니다.

이제이 질문 에서 비즈니스 로직을 항상 모델에 넣어야하며 컨트롤러가 뷰와 깊이 연결되어 있다는 것을 읽었습니다 .

나에게는 이것이 의미가 없으며 다른 데이터베이스 / 스토리지 유형을 지원하는 수단을 원할 때마다 비즈니스 논리를 포함하여 전체 모델을 다시 작성해야 함을 의미합니다.

그리고 다른보기를 원한다면보기와 컨트롤러를 모두 다시 작성해야합니다.

누군가가 왜 그런지 설명하거나 어딘가에 잘못되었는지 설명해 줄 수 있습니까?

답변:


69

ElYusubov의 대답 은 대부분 그것을 이해하고, 도메인 로직은 모델로, 애플리케이션 로직은 컨트롤러로 들어가야합니다.

두 가지 설명 :

  • 여기에서 비즈니스 로직이라는 용어는 애매 모호하므로 쓸모가 없습니다. 비즈니스 로직은 비즈니스 사람들이 관심을 갖는 모든 로직에 대한 포괄적 인 용어로, 데이터베이스에 물건을 저장하는 방법이나 화면에 렌더링하는 방법과 같은 단순한 기술과 분리됩니다. 도메인 논리 ( "유효한 전자 메일 주소는 다음과 같습니다 ...")와 워크 플로 / 비즈니스 프로세스 ( "사용자가 등록 할 때 전자 메일 주소 요청")는 모두 비즈니스 논리로 간주되며 전자는 분명히 모델과 후자는 컨트롤러에 들어가는 애플리케이션 로직입니다.
  • MVC는 화면에 물건을 놓고 사용자가 상호 작용할 수 있도록하는 패턴으로, 저장 공간 을 전혀 지정하지 않습니다 . 대부분의 MVC 프레임 워크는 단순한 MVC를 넘어서서 데이터를 저장하는 데 도움이되는 풀 스택 프레임 워크이며, 저장해야하는 데이터는 일반적으로 모델에서 찾을 수 있으므로 이러한 프레임 워크는 모델을 저장하는 편리한 방법을 제공합니다. 데이터베이스의 데이터이지만 MVC와 관련이 없습니다. 이상적으로 모델은 지속성에 구애받지 않아야하며 다른 유형의 스토리지로 전환해도 모델 코드에 전혀 영향을 미치지 않아야합니다. 본격적인 아키텍처에는이를 처리하기위한 지속성 계층이 있습니다.

4
대부분의 MVC-frameworks 종류는 모델을 쉽게 저장하기 위해 모든 스토리지 / 데이터베이스를 모델에 혼합합니다 (종종 프레임 워크를 모델 클래스로 확장하여). 이것은 아마도 혼란의 근원 일 것입니다. 기술적으로 작성하는 모델 코드는 실제 모델 (도메인 레이어)이어야하지만 프레임 워크에서 제공하는 코드는 스토리지 (지속 레이어)를 처리해야합니다. 예를 들어, 프레임 워크가 모델의 일부로 저장소 패턴을 구현했기 때문에 User.find (...) (User가 모델 인 경우)와 같은 것이 작동합니다.
Waquo

3
View-Controller-Model-Storage는 일반적인 원칙입니다 (M, V 및 C의 관계는 삼각형으로 표시되어야 함). 프레임 워크가 스토리지를 "모델"로 혼합하면 다음과 같이 작동합니다. View-Controller- (모델은 프레임 워크에서 스토리지를 상속합니다).
Waquo

2
View-Controller-Model-Storage는 평평하지 않아야하기 때문에 다소 조잡합니다. 예를 들어 컨트롤러가 모델을 얻기 위해 User.find (...)와 같은 작업을 수행하면 도메인 계층을 거치지 않고 스토리지 계층에 직접 요청합니다.
Waquo

2
보다 신중한 레이어링이있는 아키텍처에서는 UserRepository.find ()와 유사합니다. "모델"이란 당신이 상속 한 프레임 워크가 제공하는 "모델"클래스를 의미했습니다. User.find ()에 의해 리턴 된 User-object는 누군가가 사용자가 무엇인지, 사용자가 어떻게 행동 하는지를 모델링한다는 의미에서 사용자의 모델입니다.
Waquo

1
@flipdoubt 비즈니스 로직은 mwp에서 uwp 앱이라고 포팅하는 경우 동일하게 유지해야하는 로직입니다.
Andy

23

프로그래밍 세계의 많은 부분과 MVC 부분의 역할이 무엇인지 오해하는 것 같습니다. 요컨대, 그들은 :

모델 = 도메인 로직

보기 = 출력 로직

컨트롤러 = 입력 로직

이는 모델이 화면에 위젯 그리기, 프린터 구동, 데이터를 HTML로 출력, HTTP 요청 파싱 등의 모든 비즈니스 로직을 담당한다는 것을 의미합니다.

그러나 많은 현대 소위 "MVC"프레임 워크는 실제로 MVC를 전혀 수행하지 않거나 부분의 레이블을 잘못 지정합니다. 종종 "모델"이라고하는 것은 모델의 지속성 계층이며, 비즈니스 로직은 "컨트롤러"라고 부르는 것에 있습니다. 실제 컨트롤러는 일반적으로 라우팅 테이블과 개별 "컨트롤러"에 약간의 코드가 포함 된 중앙 엔트리 포인트로, 수신 한 입력을 올바른 비즈니스 프로세스로 디스패치합니다. 이러한 프레임 워크가 "view"라고 부르는 것은 실제로는 프레젠테이션 로직 (View), 입력 처리 및 유효성 검사 (Controller) 및 비즈니스 로직 (Model)과 같은 모든 것입니다. 실제 관점에서 사자가 차지하는 비율은 보통 "템플릿"이라고합니다.

Multi-Tier Architecture에 대해서도 읽어보십시오. MVC는 일방 통행이며 (흐름은 컨트롤러-> 모델->보기), 다중 계층은 양방향입니다 (프레젠테이션-> 논리-> 데이터-> 논리-> 프리젠 테이션). MVC를 가장하는 프레임 워크는 실제로 3 계층을 수행하여 프레젠테이션을 뷰로 레이블을 지정하고 로직을 컨트롤러로, 데이터를 모델로 레이블을 지정합니다.


2
나는 당신이 Model ( "Model = domain logic")을 잘못 표현한다고 생각한다. 내 생각에 그것은 데이터를 가진 집단을위한 그릇이며, MVC 패턴의 가장 순수한 형태로 View를 사용하여 렌더링된다. 실제로 간단한 사용 사례에서는이를 "도메인 논리"로 취급 할 수 있지만 기존의 가치가있는 대부분의 시스템은 매우 빠르게 성장할 것이라고 보증합니다. "도메인 로직"을 별도의 계층 / 클래스 (예 : 서비스 계층)로 분리하는 것이 좋습니다.
A. Murray

@ A.Murray : 물론 모델은 하나의 모 놀리 식 코드 덩어리 일 필요는 없으며 지속성, 데이터 구조 및 도메인 논리로 분리하는 것이 일반적으로 의미가 있습니다. 여전히 MVC는이 세 가지 관심사를 모델에서 함께 그룹화합니다. 어쨌든 컨트롤러와 뷰에 도메인 논리가 포함되어 있으면 더 이상 실제 MVC가 아닙니다.
tdammers

@ tdammers, 나는 당신의 대답의 깔끔함과 논리에 중점을 둡니다. 귀하의 관점에서 지속성 및 트랜잭션 처리와 같은 응용 프로그램 문제는 어디에 속합니까? MVC와 같이 S는 서비스를 제공하는 MVCS와 같은 네 글자 약어 여야합니다.
flipdoubt

15

비즈니스 로직을 분리하여 프리젠 테이션 계층 인프라와 분리하려면 애플리케이션 서비스로 캡슐화해야합니다. MVC 아키텍처는 프레젠테이션 계층을 구현하는 방법이며 모든 비즈니스 로직을 이러한 응용 프로그램 서비스에 위임하여 해당 범위를 유지해야합니다. 뷰 모델을 뷰와 표시하거나 읽어야하는 데이터 간의 어댑터로 생각하십시오. 컨트롤러는 비즈니스 로직을 호스팅하는 뷰 모델, 뷰 및 애플리케이션 서비스 간의 상호 작용을 중재합니다.

응용 프로그램 서비스는 비즈니스 사용 사례를 구현하며 MVC이든 다른 방식이든 프레젠테이션 계층과 분리되어 있습니다. 차례로, 응용 프로그램 서비스를 호스팅 할 수있는 트랜잭션 스크립트 또는 도메인 중심의 디자인 .

스토리지의 경우 애플리케이션 서비스는 저장소 또는 지속성 메커니즘의 추상화를 참조 할 수 있습니다 . 데이터 액세스를 인터페이스로 추상화하여 다른 구현을 지원할 수 있습니다. 일반적으로 이러한 추상화는 유출 되어 구현 전반에 걸쳐 부분적으로 만 이식 가능하며 완전한 이식성을 얻기위한 무의미한 시도입니다.

최신 정보

내 제안은 육각형 아키텍처를 기반으로합니다 . 육각형 아키텍처에서는 도메인 모델 (비즈니스 로직)이 핵심입니다. 이 코어는 파사드 역할을하는 애플리케이션 서비스에 의해 캡슐화됩니다 . 응용 프로그램 서비스는 도메인의 사용 사례에 해당하는 메서드가있는 간단한 클래스입니다. 응용 프로그램 서비스에 대한 자세한 내용 은 도메인 기반 디자인 서비스를 참조하십시오 . 코드 샘플에는 PurchaseOrderService구매 도메인에 대한 애플리케이션 서비스 인가 포함되어 있습니다. 응용 프로그램 서비스가 도메인 기반 디자인을 사용한다는 것을 의미하지는 않습니다.

육각형 아키텍처에서 MVC 프리젠 테이션 계층은 도메인 모델 (비즈니스 로직)과 GUI 사이의 어댑터입니다. 도메인 모델은 프리젠 테이션 레이어를 인식하지 못하지만 프리젠 테이션 레이어는 도메인 모델을 인식합니다.

이 솔루션은 확실히 컨트롤러에 비즈니스 로직을 배치하는 솔루션보다 움직이는 부품이 있으므로 단점과 이점을 평가해야합니다. 내가 제안하는 이유는 복잡성을 방지하기 위해 비즈니스 논리를 프레젠테이션 계층에서 분리하는 것을 선호하기 때문입니다. 응용 프로그램이 커질수록 더 중요해집니다.


컨트롤러와 뷰 모델이 모두있는 MVC 및 MVVM의 나쁜 놈을 설명하는 것 같습니다. 또한 설명하는 아키텍처가 OP의 요구에 따라 약간 무거울 수 있다고 생각합니다.
Waquo

솔직히 말하면, 나는 Waquo의 답변을 더 좋아합니다. 주로 '응용 프로그램 서비스'의 의미를 전혀 알지 못하기 때문입니다. 그 용어를 설명해 주시겠습니까? 내 GoogleFU가 여기에서 작동하지 않습니다.
Steffen Winkler

1
@Waquo 제안 된 아키텍처가 과도 할 수 있지만 동의해야합니다. 프레젠테이션 레이어를 구현하는 또 다른 방법 인 MVVM에 대해서는 언급하지 않았습니다. 응용 프로그램 서비스는 MVC를 사용하든 MVVM을 사용하든 관계없이 적용되며 제안한 것은이 둘의 조합을 나타냅니다.
eulerfx 2013

1

비즈니스 로직의 의미에 따라 다릅니다. 모델의 내용을 의미하는 "논리"는 모델에 있어야합니다. 관련 질문에서 가장 높은 투표 응답은 "비즈니스 로직"을 데이터와 관련된 것으로 정의하는 것 같습니다. 이것은 비즈니스 데이터가 비즈니스라는 관점에서 의미가 있습니다!

한때 레일즈 (Rails) (제 생각에) 제작자에 의해 예를 보았습니다. 그의 예는 앱 등록 및 로그인을위한 컨트롤러 클래스 및 메소드입니다. 일반 텍스트로 제공된 비밀번호는 모델 (데이터베이스)에 삽입하거나 쿼리하기 전에 암호화되었습니다.

컨트롤러 논리가 아니며 모델에 직접 속한 무언가에 대한 더 좋은 예를 생각할 수 없습니다.

이 모델은 수많은 데이터 저장소에 대한 인터페이스가되어 이식성 문제를 완화 할 수 있습니다. 여기 모델 인터페이스가 실제로 "컨트롤러"인지 아닌지 혼동 될 수 있습니다.

일반적으로 컨트롤러는 모델과 뷰 (앱의 고기와 감자)를 연결합니다. Cocoa 개발에서는 컨트롤러가 XCode GUI (컨트롤러 객체 및 바인딩)를 통해 컨트롤러를 처리하는 지점까지 간단 할 수 있습니다.

MVC에 대한 GoF의 "디자인 패턴"섹션은 다음과 같이 인용했습니다.

MVC 클래스 클래스는 Smalltalk-80에서 사용자 인터페이스를 구축하는 데 사용됩니다. 모델은 응용 프로그램 객체이고,보기는 화면 표현이며 컨트롤러는 UI가 사용자 입력에 반응하는 방식을 정의합니다. MVC는 뷰와 모델간에 구독 / 알림 프로토콜을 설정하여 뷰와 모델을 분리합니다. 다음 다이어그램은 모델과 세 가지보기를 보여줍니다. 단순성을 위해 컨트롤러를 생략했습니다.

MVC는 UI에 관한 것입니다. 모델과 뷰에 중점을두고 데이터를 정의하고 표시합니다. "구독 / 알림 프로토콜"에 주목하십시오. 이것은 컨트롤러가 들어오는 곳입니다. 원하는 모든 뷰를 만들 수 있습니다. 프로토콜을 준수하는 한 모델이나 컨트롤러를 만질 필요가 없습니다.

웹 개발에 대해 구체적으로 이야기하고 있다면 IMHO 많은 인기있는 웹 프레임 워크는 MVC와 그 구성 요소 정의라는 용어로 빠르거나 느슨합니다.


저는 C # / Java (몇몇 프로젝트 만 있음) 개발자입니다. 모델이하는 일을 오해 한 것 같습니다. '비즈니스 로직'을 컨트롤러에 넣는 것은 실제로 후유증에 불과했습니다 (제 생각의 기차는 '좋아요. 데이터에 대한 모델을 읽었습니다 (데이터베이스 연결 / 스토리지). 내 비즈니스 로직은 컨트롤러에 있어야합니다. 데이터를 데이터베이스에 저장하기 전에 적용해야합니다. '컨트롤러에서 모든 수준을 한 단계 아래로 이동하면됩니다. 실제로 현재의 문제 (한 프로그램에서 MySQL 및 MSSQL 지원)를 해결합니다
Steffen Winkler

0

왜 서비스 계층을 도입하지 않습니까?

그러면 컨트롤러가 간결하고 읽기 쉬워지며 모든 컨트롤러 기능이 순수한 동작이됩니다.

서비스 계층 내에서 필요한만큼 비즈니스 로직을 분해 할 수 있습니다. 코드 재사용 성이 우수하고 모델 및 리포지토리에 영향을 미치지 않습니다.

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