MVC가 OOP가 아닙니까?


61

OOP의 기본 아이디어는 단일 개체 (객체)에서 데이터와 동작을 통합하는 것입니다. 절차 적 프로그래밍에는 데이터를 수정하는 별도의 알고리즘과 데이터가 있습니다.

Model-View-Controller 패턴에서 데이터와 로직 / 알고리즘은 각각 별개의 엔터티, 모델 및 컨트롤러에 배치됩니다. 동등한 OOP 방식에서 모델과 컨트롤러를 동일한 논리 엔티티에 배치해서는 안됩니까?


11
왜 동일한 논리 엔티티에 있어야합니까? 왜 이것이 유리한지 또는 OOP가 왜이 배열을 지시 할 것인지에 대해서는 언급하지 않았습니다.
Robert Harvey

26
비즈니스 로직은 컨트롤러가 아닌 모델에 적용됩니다. 컨트롤러는 실제로 뷰와 모델을 연결하는 중간 단계입니다. 따라서 모델에서는 동일한 위치에 데이터와 동작이 있습니다.
Robert Harvey

2
뭐? 데이터와 행동을 통합하는 것은 OOP의 핵심입니다.
Andy

3
OOP는 인터페이스와 구현을 분리하는 것입니다. 인터페이스는 동작과 더 관련이 있으며 구현은 데이터와 더 관련이 있습니다 (데이터가 숨겨진 경향이있는 이유). 따라서 OOP는 데이터와 동작을 통합하는 것이 아니라 분리하는 것입니다.
Kaz

5
어쨌든 모든 데이터와 행동을 하나의 클래스에 채우고 싶지는 않습니다. OOP 프로그램은 하나 이상의 클래스를 사용하여 객체의 프레임 워크를 만듭니다. 그리고 어쨌든 무언가가 "anti-OOP"라면, 그것은 좋은 일이 될 수 있습니다. OOP는 전부가 아닙니다. OOP 완전히 짜증 난다. 이제 OOP를 극복해야합니다.
Kaz

답변:


44

MVC는 UI 아키텍처 인 Separation of Concerns 의 실습입니다 . 프리젠 테이션이 컨텐츠와 분리되지 않아서 사용자 인터페이스에서 발생할 수있는 복잡성을 상관시키는 방법 입니다.

이론적으로 모든 객체에는 포함 된 데이터에서 작동하는 동작이있을 수 있으며 해당 데이터와 동작은 캡슐화 된 상태로 유지 됩니다. 실제로, 주어진 OOP 객체는 그 데이터에 대응하는 로직을 갖거나 갖지 않을 수 있거나, 또는 전혀 로직을 갖지 않을 수있다 ( 예를 들어, 데이터 전송 객체 ).

MVC에서 비즈니스 로직은 컨트롤러가 아닌 모델에 적용됩니다. 컨트롤러는 실제로 뷰와 모델을 연결하는 중간 단계입니다. 따라서 모델에서 동일한 위치에 데이터와 동작을 가질 수 있습니다.

그러나 이러한 배치조차도 엄격한 데이터 / 동작 융합을 보장하지는 않습니다. 데이터 만 포함 된 개체는 논리 만 포함 된 다른 클래스에서 조작 할 수 있으며 OOP를 완벽하게 사용할 수 있습니다.


구체적인 예를 드리겠습니다. 이것은 약간 고안된 것이지만, 당신이 Currency물건 을 가지고 있다고 가정 해 봅시다 . 그리고 그 물건은 달러에 고정 된 사용 가능한 통화로 자신을 표현할 수 있습니다. 따라서 다음과 같은 방법이 있습니다.

public decimal Yen { get { return // dollars to yen; } }
public decimal Sterling { get { return // dollars to sterling; } }
public decimal Euro { get { return // dollars to euro; } }

그 행동은 Currency 객체로 캡슐화됩니다.

하지만 한 계좌에서 다른 계좌로 통화를 이체하거나 일부 통화를 입금하려면 어떻게해야합니까? 해당 동작이 Currency 개체에도 캡슐화됩니까? 아뇨. 지갑의 돈은 지갑에서 은행 계좌로 이체 할 수 없습니다. 계좌에 돈을 입수하는 데 도움이되는 하나 이상의 에이전트 (텔러 또는 ATM)가 필요합니다.

그래서 동작은로 캡슐화 될 Teller객체, 그리고 그것을 받아 들일 CurrencyAccount입력 등의 개체 만이 로컬 상태 (또는 어쩌면 어쩌면 조금 제외하고, 데이터 자체를 포함하지 않을 Transaction입력 개체를 처리하기 위해 개체).


그리고 어떤 엔티티 / 패키지에 Teller배치 해야 합니까? 에서 Controller어디에서 Teller's메소드 호출 또는에서 Model비즈니스 로직이 때문에 일부?
m3th0dman

Teller간다 Model가 컨트롤러에서 호출 할 수 있지만,. 비즈니스 도메인의 일부입니다.
Robert Harvey

비즈니스 규칙에 모델을 사용하면 MVC가 반 효과적인 패턴이된다고 항상 생각했습니다. 실제 애플리케이션에 대한 어댑터 모델을 사용하고 컨트롤러가 어댑터와보기 사이에서 중개되도록하는 것이 SoC를 달성하는 데 항상 훨씬 더 효과적입니다.
얌 마르코비치

@YamMarcovic : 무슨 말인지 잘 모르겠습니다. 모델은 일종의 포괄입니다. 실제로 비즈니스 규칙은 일반적으로 자체 서비스 계층에 배치되지만 여전히 모델의 일부로 간주됩니다 (예를 들어 개별 컨트롤러 방법 내에서 특정 비즈니스 규칙을 인코딩하지는 않음). 컨트롤러는 중간에 있습니다.
Robert Harvey

4
대부분의 사람들이 MVC에 대해 잘못 이해하고 있다고 생각하는 것 중 하나는 "비즈니스 로직"의 의미에 대한 광범위한 가정입니다. 완전히 다른 애플리케이션 로직을 가진 컨트롤러를 통해 동일한 비즈니스 목표를 가지지 만 매우 다른 아키텍처를 가진 완전히 새로운 앱에서 모델을 튀어 나와 거의 수정하지 않고 사용하면 모델이 잘못되었습니다. IMO. 물론 다른 모든 것을 혼합하여 뷰를 분리하는 데는 여전히 가치가 있지만 가벼운 구조이므로 C는 분리의 핵심 포인트를 놓친 것으로 생각됩니다.
Erik Reppen

73

MVC는 단일 객체보다 훨씬 높은 추상화 수준 에서 작동하며 실제로 세 가지 (모델, 뷰 및 컨트롤러) 각각은 일반적으로 각각 데이터와 동작이 모두있는 많은 객체로 구성됩니다.

데이터와 행동을 캡슐화하는 객체가 일반적으로 프로그램의 기본 토대가된다고해서 모든 수준의 추상화와 모든 목적에서 최상의 패턴이되는 것은 아닙니다.


객체 지향 접근 방식은 추상화 수준으로 확장 할 수 있습니다. 예를 들어 고전적인 계층 구조가 OOPish가 아니라 절차 적이기 때문에 나타나는 Domain Driven Design의 이유를 참조하십시오. 이것은 MVC보다 더 높은 추상화 수준에서 발생합니다.
m3th0dman

6
@ m3th0dman : 광범위하고 포괄적 인 일반 표현을하고 있습니다. MVC가 Winforms 또는 Webforms 인 스파게티 코드 악몽을 제거하는 방법과 같은 세부 사항을 논의하는 것은 어떻습니까?
Robert Harvey

3
@ m3th0dman : 그것은 DDD의 매우 단순한 특성입니다.
Michael Borgwardt

1
@RobertHarvey MVC가 스파게티를 없애 버리는 이유는 실제로 여기에 있지 않기 때문에 MVC가 좋은 이유에 대한 반론입니다. 동의하지만 MVC는 절차 적 패턴으로 구현되는 경향이 있습니다. 그래서 나는 이것이 질문을하는 것이 적절한 질문이라고 생각하거나 오히려 사람들이 "MVC를 절차 적으로 얼마나 자주 구현 하는가?"라고 묻습니다.
Jimmy Hoffa

1
@Robert Harvey이 질문의 목적은 MVC의 우수성에 대한 것이 아닙니다. OO 원칙을 기반으로하거나 그렇지 않은 사실에 관한 것입니다.
m3th0dman

71

OOP는 각각 자체 데이터와 자체 동작이있는 개체 간의 상호 작용을 제한하지 않습니다.

개미와 개미 식민지의 비유를 생각해보십시오. 개미 개미의 행동 (하루 종일 실행, 음식 가져 오기)은 전체 식민지의 행동과 다릅니다 (가장 바람직한 장소를 찾고 개미를 더 많이 만드십시오). MVC 패턴은 개미 식민지의 원하는 사회적 구조를 설명하는 반면, OOP는 개별 개미의 디자인을 안내합니다.


5
+1 : 나는 보통 유추를 통한 설명을 싫어하지만, 이것은 훌륭합니다.
Michael Borgwardt

@ Caleb 이것은 훌륭한 포인트입니다. 대단히 감사합니다!
dasblinkenlight

19

OOP는 또한 관심의 분리 , 즉 다른 대상에서 다른 역할 / 책임을 분리하는 것입니다.

MVC는 다음과 같은 구성 요소로 구분됩니다.

  • 모델 : 데이터 및 비즈니스 로직
  • 보기 : 데이터 표현
  • 컨트롤러 : 모델과 뷰 사이의 조정.

따라서 이러한 책임은 명확하게 구분되며 실제로 여러 엔터티로 분리되어야합니다.


단일 책임 원칙이 OOP를 효과적으로 사용하는 데 도움이된다는 것은 사실이지만, "OOP는 단일 책임 원칙에 관한 것"이라고 말하는 것은 신축 적이라고 생각합니다. 거꾸로 보인다.
Caleb

@ Caleb 그래, 무슨 말인지 이해합니다. 어쩌면 그것은 rephrased 수 있지만 당신은 요점을 얻을.
marco-fiset

18

Model-View-Controller 패턴에서 데이터와 로직 / 알고리즘은 각각 별개의 엔터티, 모델 및 컨트롤러에 배치됩니다.

모델과 컨트롤러는 별개의 역할입니다. 모델에는 상태와 논리가 있고 컨트롤러에는 상태와 논리가 있습니다. 그들이 통신한다는 사실은 캡슐화를 깨뜨리지 않습니다. 컨트롤러는 모델이 데이터를 저장 하는 방법 또는 컨트롤러가 데이터의 일부를 검색하거나 업데이트 할 때 데이터에 수행 하는 작업을 알거나 신경 쓰지 않습니다 . 모델은 모델이 제공하는 데이터로 컨트롤러가 무엇을하는지 알거나 신경 쓰지 않습니다.

캡슐화를 중단하지 않고 객체가 데이터를 앞뒤로 전달할 수없는 경우 실제로는 하나의 객체 만 가질 수 있습니다!

동등한 OOP 방식에서 모델과 컨트롤러를 동일한 논리 엔티티에 배치해서는 안됩니까?

MVC OOP 접근 방식입니다. 특히 객체를 사용하여 프로그램을 효과적으로 구성하는 방법을 결정하는 방법입니다. 그리고 아니요 , 모델과 컨트롤러는 같은 엔티티가 아니어야합니다. 컨트롤러는 모델과 뷰를 분리 할 수 ​​있습니다. 모델과 뷰를 서로 독립적으로 유지하면 더 테스트 가능하고 재사용 할 수 있습니다.


컨트롤러에는 논리가 있지만 상태가 거의 없거나 거의 없기를 바랍니다. 컨트롤러가 어떤 상태에 있다고 생각하십니까?
Matthew Flynn

1
@MatthewFlynn 우선 컨트롤러는 뷰와 모델에 대해 알아야합니다. 그 외에도, 우리가 이야기하는 MVC의 특정 풍미에 따라 달라질 수 있지만 일반적으로 컨트롤러는 정보가 표시 되는 방법 (예 : 현재 선택) 과 관련된 상태를 유지할 수 있지만 모델 은 표시 되는 정보를 처리합니다.
Caleb

1
@MattFenwick 이것이 바로 '맛'에 대한 의미입니다 ... 정확히 컨트롤러에 저장하는 것과 모델에있는 것은 맛과 컨벤션의 문제입니다. Cocoa / Cocoa Touch에서는 컨트롤러에서 현재 선택 및 사용자 기본 설정과 같은 항목을 유지하는 것이 일반적입니다. 일부 웹 프레임 워크에서 사용되는 MVC는 거의 모든 것을 모델에, 컨트롤러에는 거의 넣지 않을 수 있습니다. YMMV.
Caleb

4
@MatthewFlynn 대부분은 귀하의 의견에 동의하지만 IMO는 사람들이 비즈니스 로직을 예상보다 넓은 범주로 생각합니다. 컨트롤러는 사람들이 종종 비즈니스 로직과 혼동되는 애플리케이션 로직을 처리합니다. 이상적인 분리 문제에서 비즈니스 객체를 수정하지 않고 동일한 비즈니스 목표를 제공하는 완전히 다른 앱 아키텍처에서 모델 객체를 재사용 할 수 있어야합니다. 새로운 응용 프로그램은 인터페이스를 사용하고 반환 및 처리 된 데이터 및 트랜잭션으로 자체 작업을 수행하기 만하면됩니다.
Erik Reppen

1
@MattFenwick : 다중 사용자 응용 프로그램을 고려하십시오. 모델과 컨트롤러 사이의 선을 그리는 분명한 점은 모델이 공유 상태를 처리하고 컨트롤러가 로컬 상태를 처리한다는 것입니다. 현재 선택은 로컬이므로 컨트롤러로 이동합니다.
Jan Hudec

4

MVC는 객체가 상호 작용할 수있는 합리적인 방법을 설명하는 패턴입니다. 자체는 메타 클래스가 아닙니다. OO는 엔터티의 동작 및 데이터와 해당 엔터티의 상호 작용을 설명합니다. 전체 시스템을 하나의 거대한 객체로 통합하는 것이 아닙니다.


2

컨트롤러는 모델의 동작을 나타내지 않습니다. 컨트롤러는 전체 응용 프로그램의 동작 _ 사용자가 할 수있는 것과 사용자가 볼 수있는 것을 모두 나타냅니다.

컨트롤러와 모델을 하나로 보는 것은 잘못입니다. 그것들은 다른 목적, 다른 의미를 가지고 있으므로 하나의 목적으로 통합되어서는 안됩니다.


2

모델 계층은 단순한 컨트롤러 계층 이상의 데이터가 아닙니다.

컨트롤러 계층에는 용도에 맞는 완전한 개체 모음이 있습니다. 뷰에서 입력을 받고 해당 입력을 모델이 처리 할 수있는 양식으로 변환하기위한 오브젝트가 있습니다. Struts Java 프레임 워크는 Action / Form 모델에 좋은 예가 있습니다. 양식은 사용자의 입력으로 채워진 다음 동작으로 전달됩니다. Action은 해당 데이터를 가져 와서 모델을 조작하는 데 사용합니다.

같은 방식으로 모델 계층은 전적으로 데이터로 구성되지 않습니다. 예를 들어, 사용자 객체를 가져 오십시오-데이터베이스에서 사용자를 가져 오는 코드 또는 사용자를 주문과 연관 시키거나 사용자의 주소가 회사 서비스 영역 내에 있는지 확인하는 코드가 필요할 수 있습니다. 그림. 이것은 컨트롤러 로직이 아닙니다. 비즈니스 논리이며 많은 사람들이 모델 계층을 비즈니스 논리를위한 서비스 또는 관리자 계층, 데이터베이스 액세스를위한 DAO (데이터베이스 액세스 개체) 계층 등과 같은 여러 계층으로 나누었습니다.

MVC는 개별 모델 작업을 구성하는 방법이 아닙니다. 그것은 그것보다 높은 수준에서 작동합니다-그것은 응용 프로그램에 액세스하는 방법을 구성하는 방법입니다. 보기는 데이터를 조작하기위한 데이터 및 휴먼 조치를 표시하기위한 것이며, 제어기는 사용자 조치와 다양한보기 간의 변환을위한 것이며 모델은 비즈니스 데이터 및 비즈니스 이유가 존재하는 위치입니다.


2

OOP의 핵심은 함께 속하는 데이터와 기능 을 그룹화하는 것 입니다. 일부 데이터를 기반으로 한 계산이 항상 해당 데이터에 속하지 는 않습니다 .

MVC에서 데이터 (보기)를 표시하는 기능은 데이터 (모델)와 별도로 유지됩니다. 왜 그런 겁니까? 특히 기본 데이터를 변경하지 않고도 디스플레이 로직을 변경할 수 있습니다. 동일한 데이터를 다르게 표시해야 할 때마다 또는 디스플레이 하드웨어의 특성이 변경 될 때 또는 Windows에서 Linux로 전환 할 때보기를 쉽게 변경할 수 있습니다. 또는 두 사람이 동일한 데이터를 보는 서로 다른 두 가지 방법을 원할 때.

MVC는 OOP와 충돌하지 않으며 실제로 객체 지향 원칙의 올바른 응용 프로그램에서 파생됩니다.


0

모델 객체에 바인딩 된 영구 데이터와 모델이 상호 작용하는 데이터베이스의 응용 프로그램 데이터를 혼동하고 있다고 생각합니다. 모델에는 데이터베이스 작업 및 트랜잭션 수행을위한 비즈니스 논리 및 규칙이 포함됩니다. 현재 판매 여부, 사용자가 VIP 상태 자격이 있는지 여부 및 데이터 액세스, 설정 또는 조작 또는 구매 수행 시점에 따라 분기 논리와 같은 내부 상태 플래그를 설정하고 확인할 수 있습니다. 그것은 일련의 메소드와 지속적인 값 또는 데이터의 캡슐화 측면에서 객체를 논의 할 때 우리가 이야기하는 플래그입니다.

모델 개체가 비즈니스 규칙을 설정하는 데 필요한 데이터를 유지 관리하는 것처럼 컨트롤러는 IMO가 사용자의 로그인 여부 또는 신용 상태와 같은 앱의 동작 방식과 관련된보다 일반적인 응용 프로그램 상태 데이터를 유지해야합니다. 카드 데이터가 제자리에 있습니다. 모델 메소드는 처음에 이러한 상태를 판별하지만, 비즈니스가 실행되거나 데이터 트랜잭션이 수행되는 방식에 적용되지 않는 경우 컨트롤러가 일반 앱 흐름과 관련된 플래그를 유지하는 것이 좋습니다. 로그인하지 않은 것으로 확인되면 다른 로그인 시도가 명확해질 때까지 사용자 상태 확인으로 모델을 귀찮게하지 마십시오.

마찬가지로 적절한 뷰 객체와 대부분의 서버 측 웹 프레임 워크에서 볼 수있는보다 일반적인 HTML 템플릿이 있습니다. 사용자의 색상 기본 설정이로드되면 해당 데이터를 유지하고 실행하는보기 여야합니다. 설정로드, 확인 및 변경은 모두 모델 문제이지만 변경이 발생할 때까지 한 번만 모델 문제 여야합니다.

IMO는 컨트롤러가 뷰와 모델을 내부 집계 개체로 사용하는 복합 개체가 될 수 없다고 말합니다. 컨트롤러는 뷰와 모델이 상호 작용하는 방식에 대한 데이터와 논리 세부 정보를 묻고 높은 수준의 앱 개체에 인터페이스를 노출하기에 이상적인 장소이므로 UI ​​위젯 팩토리와 같이 소규모로 MVC를 적용하는 경우 실제로 의미가 있습니다. 컨트롤러가 실제로 가장 높은 수준의 개체 인 독점 앱 개체에는 실제로 의미가 없습니다.


0

내가 이해 한대로; 인수는 컴포넌트 기반 아키텍처 대 OOP입니다. 그리고 종교 전쟁에 들어 가지 않고, 나는 그들이 같은 것을 묘사하고 있다고 생각합니다. 다른 각도에서 보면

예를 들어, OOP / OOD의 핵심은 코드를 더 모듈화하고 재사용 할 수있게하는 것입니다. 예?

정확히 컴포넌트 기반 아키텍처의 목표입니다. 그래서 그들은 다른 것보다 더 비슷합니다.

MVC는 OOP의 자연스런 진화라고 생각합니다. 객체를 정리하고 우려를 분리하고 코드를 재사용하는 더 좋은 방법.


MVC와 Component-Based Architecture는 OOP 접근법의 영역을 벗어나지 않는 디자인 패턴이지만 OOD / OOP는 단순히 경계에 유비쿼터스 프로그래밍을 사용하는 방법에 대한 생각과 학계 학파의 혼란과 충돌입니다. 제대로 구성하십시오. 두 가지 범주를 비교하는 것은 사각형과 사각형을 그리는 데 사용한 펜을 비교하는 것과 같습니다.
Erik Reppen

-1

나는이 파티에 늦었고 내 앞에있는 모든 답을 고려할 때, 새로운 제안이 많지 않다는 것을 인정한다. 그러나 질문은 패턴 자체가 아니라 구현에 관한 것 같습니다. MVC 자체는 특정 방법론에 적합하지 않습니다. 실제로, 절차 지향 코드를 MVC 패턴으로 쉽게 구상 할 수 있습니다 (이것이 제가 암시 한 것처럼 느꼈습니다).

실제 질문은 다음과 같습니다. MVC 패턴을 사용할 때 절차 적 코드에 더 취약합니다.

(아마도 그냥 투표를받을 수 있습니까?)


-1

MVC에는 안티뿐만 아니라 OOP도 필요하지 않습니다.

일반적으로 클래스로 표시되는 컨트롤러는 데이터를 보유하지 않기 때문입니다. 순수한 기능으로는 충분합니다.

예를 들어, 데이터를 동작과 분리하고 분리하는 경우 모델이 데이터베이스 데이터에 대해서만 작동한다고 가정 해 봅시다.이 데이터는 인스턴스에 어떤 종류의 데이터를 저장하는 대신 함수 (데이터 조작을 담당하는)가 호출 될 때마다 가져옵니다. 필드)-그런 다음 모델에 대해 동일하게 말할 수 있습니다.

더 나아가 응용 프로그램의 뷰 레이어를 비슷한 방식으로 나누면 실제로 MVC는 OOP와 아무런 관련이 없다는 결론으로 ​​끝날 것이며 절차 적 접근 방식 만 사용하면 아무런 어려움없이 MVC 구현을 작성할 수 있습니다. .


하하, 나는 사실에 직면했을 때 어떤 사람들이 고통을 겪는 것을 본다. OOP로 자체 프레임 워크를 수행하는 데 너무 많은 노력이 필요하십니까? 잃어버린 시간을 견딜 수 없습니까? 가장 간단한 답변이 가장 좋습니다.
luke1985

왜이 답변에 다운 보트가 있는지 확실하지 않습니다. 그는 그들이 "안티"가 아니라 관련이 없다고 말합니다. 꽤 정확한 것 같습니다.
mwilcox

-3

내 의견에서 OOP는 (데이터와 행동)이 하나의 엔티티 (클래스)로 성형되기 때문에 응집력보다 결합 효과가 더 크다는 단점이 있습니다. 반면 MVC에는 Models ... (Beans, DAO, Other Logic 클래스), 컨트롤이 이동하는 방법을 지정하는 Controller 및 데이터 표시 방법을 결정하는 뷰가 분리 된 방식으로 제공됩니다. 이를 바탕으로 프로젝트가 너무 큰 경우에도 OOP와 달리 혼합되지 않고 별도의 엔티티로 쉽게 만들 수 있습니다. 문제는 분할 n 정복 전략과 같은 논리적 패턴으로 해결되며 MVC가이를 따릅니다.


이것이 당신의 의견일까요, 아니면 어떻게 든 백업 할 수 있습니까?
gnat
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.