OOP의 기본 아이디어는 단일 개체 (객체)에서 데이터와 동작을 통합하는 것입니다. 절차 적 프로그래밍에는 데이터를 수정하는 별도의 알고리즘과 데이터가 있습니다.
Model-View-Controller 패턴에서 데이터와 로직 / 알고리즘은 각각 별개의 엔터티, 모델 및 컨트롤러에 배치됩니다. 동등한 OOP 방식에서 모델과 컨트롤러를 동일한 논리 엔티티에 배치해서는 안됩니까?
OOP의 기본 아이디어는 단일 개체 (객체)에서 데이터와 동작을 통합하는 것입니다. 절차 적 프로그래밍에는 데이터를 수정하는 별도의 알고리즘과 데이터가 있습니다.
Model-View-Controller 패턴에서 데이터와 로직 / 알고리즘은 각각 별개의 엔터티, 모델 및 컨트롤러에 배치됩니다. 동등한 OOP 방식에서 모델과 컨트롤러를 동일한 논리 엔티티에 배치해서는 안됩니까?
답변:
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
객체, 그리고 그것을 받아 들일 Currency
및 Account
입력 등의 개체 만이 로컬 상태 (또는 어쩌면 어쩌면 조금 제외하고, 데이터 자체를 포함하지 않을 Transaction
입력 개체를 처리하기 위해 개체).
Teller
배치 해야 합니까? 에서 Controller
어디에서 Teller's
메소드 호출 또는에서 Model
비즈니스 로직이 때문에 일부?
Teller
간다 Model
가 컨트롤러에서 호출 할 수 있지만,. 비즈니스 도메인의 일부입니다.
MVC는 단일 객체보다 훨씬 높은 추상화 수준 에서 작동하며 실제로 세 가지 (모델, 뷰 및 컨트롤러) 각각은 일반적으로 각각 데이터와 동작이 모두있는 많은 객체로 구성됩니다.
데이터와 행동을 캡슐화하는 객체가 일반적으로 프로그램의 기본 토대가된다고해서 모든 수준의 추상화와 모든 목적에서 최상의 패턴이되는 것은 아닙니다.
OOP는 각각 자체 데이터와 자체 동작이있는 개체 간의 상호 작용을 제한하지 않습니다.
개미와 개미 식민지의 비유를 생각해보십시오. 개미 개미의 행동 (하루 종일 실행, 음식 가져 오기)은 전체 식민지의 행동과 다릅니다 (가장 바람직한 장소를 찾고 개미를 더 많이 만드십시오). MVC 패턴은 개미 식민지의 원하는 사회적 구조를 설명하는 반면, OOP는 개별 개미의 디자인을 안내합니다.
OOP는 또한 관심의 분리 , 즉 다른 대상에서 다른 역할 / 책임을 분리하는 것입니다.
MVC는 다음과 같은 구성 요소로 구분됩니다.
따라서 이러한 책임은 명확하게 구분되며 실제로 여러 엔터티로 분리되어야합니다.
Model-View-Controller 패턴에서 데이터와 로직 / 알고리즘은 각각 별개의 엔터티, 모델 및 컨트롤러에 배치됩니다.
모델과 컨트롤러는 별개의 역할입니다. 모델에는 상태와 논리가 있고 컨트롤러에는 상태와 논리가 있습니다. 그들이 통신한다는 사실은 캡슐화를 깨뜨리지 않습니다. 컨트롤러는 모델이 데이터를 저장 하는 방법 또는 컨트롤러가 데이터의 일부를 검색하거나 업데이트 할 때 데이터에 수행 하는 작업을 알거나 신경 쓰지 않습니다 . 모델은 모델이 제공하는 데이터로 컨트롤러가 무엇을하는지 알거나 신경 쓰지 않습니다.
캡슐화를 중단하지 않고 객체가 데이터를 앞뒤로 전달할 수없는 경우 실제로는 하나의 객체 만 가질 수 있습니다!
동등한 OOP 방식에서 모델과 컨트롤러를 동일한 논리 엔티티에 배치해서는 안됩니까?
MVC 는 OOP 접근 방식입니다. 특히 객체를 사용하여 프로그램을 효과적으로 구성하는 방법을 결정하는 방법입니다. 그리고 아니요 , 모델과 컨트롤러는 같은 엔티티가 아니어야합니다. 컨트롤러는 모델과 뷰를 분리 할 수 있습니다. 모델과 뷰를 서로 독립적으로 유지하면 더 테스트 가능하고 재사용 할 수 있습니다.
모델 계층은 단순한 컨트롤러 계층 이상의 데이터가 아닙니다.
컨트롤러 계층에는 용도에 맞는 완전한 개체 모음이 있습니다. 뷰에서 입력을 받고 해당 입력을 모델이 처리 할 수있는 양식으로 변환하기위한 오브젝트가 있습니다. Struts Java 프레임 워크는 Action / Form 모델에 좋은 예가 있습니다. 양식은 사용자의 입력으로 채워진 다음 동작으로 전달됩니다. Action은 해당 데이터를 가져 와서 모델을 조작하는 데 사용합니다.
같은 방식으로 모델 계층은 전적으로 데이터로 구성되지 않습니다. 예를 들어, 사용자 객체를 가져 오십시오-데이터베이스에서 사용자를 가져 오는 코드 또는 사용자를 주문과 연관 시키거나 사용자의 주소가 회사 서비스 영역 내에 있는지 확인하는 코드가 필요할 수 있습니다. 그림. 이것은 컨트롤러 로직이 아닙니다. 비즈니스 논리이며 많은 사람들이 모델 계층을 비즈니스 논리를위한 서비스 또는 관리자 계층, 데이터베이스 액세스를위한 DAO (데이터베이스 액세스 개체) 계층 등과 같은 여러 계층으로 나누었습니다.
MVC는 개별 모델 작업을 구성하는 방법이 아닙니다. 그것은 그것보다 높은 수준에서 작동합니다-그것은 응용 프로그램에 액세스하는 방법을 구성하는 방법입니다. 보기는 데이터를 조작하기위한 데이터 및 휴먼 조치를 표시하기위한 것이며, 제어기는 사용자 조치와 다양한보기 간의 변환을위한 것이며 모델은 비즈니스 데이터 및 비즈니스 이유가 존재하는 위치입니다.
OOP의 핵심은 함께 속하는 데이터와 기능 을 그룹화하는 것 입니다. 일부 데이터를 기반으로 한 계산이 항상 해당 데이터에 속하지 는 않습니다 .
MVC에서 데이터 (보기)를 표시하는 기능은 데이터 (모델)와 별도로 유지됩니다. 왜 그런 겁니까? 특히 기본 데이터를 변경하지 않고도 디스플레이 로직을 변경할 수 있습니다. 동일한 데이터를 다르게 표시해야 할 때마다 또는 디스플레이 하드웨어의 특성이 변경 될 때 또는 Windows에서 Linux로 전환 할 때보기를 쉽게 변경할 수 있습니다. 또는 두 사람이 동일한 데이터를 보는 서로 다른 두 가지 방법을 원할 때.
MVC는 OOP와 충돌하지 않으며 실제로 객체 지향 원칙의 올바른 응용 프로그램에서 파생됩니다.
모델 객체에 바인딩 된 영구 데이터와 모델이 상호 작용하는 데이터베이스의 응용 프로그램 데이터를 혼동하고 있다고 생각합니다. 모델에는 데이터베이스 작업 및 트랜잭션 수행을위한 비즈니스 논리 및 규칙이 포함됩니다. 현재 판매 여부, 사용자가 VIP 상태 자격이 있는지 여부 및 데이터 액세스, 설정 또는 조작 또는 구매 수행 시점에 따라 분기 논리와 같은 내부 상태 플래그를 설정하고 확인할 수 있습니다. 그것은 일련의 메소드와 지속적인 값 또는 데이터의 캡슐화 측면에서 객체를 논의 할 때 우리가 이야기하는 플래그입니다.
모델 개체가 비즈니스 규칙을 설정하는 데 필요한 데이터를 유지 관리하는 것처럼 컨트롤러는 IMO가 사용자의 로그인 여부 또는 신용 상태와 같은 앱의 동작 방식과 관련된보다 일반적인 응용 프로그램 상태 데이터를 유지해야합니다. 카드 데이터가 제자리에 있습니다. 모델 메소드는 처음에 이러한 상태를 판별하지만, 비즈니스가 실행되거나 데이터 트랜잭션이 수행되는 방식에 적용되지 않는 경우 컨트롤러가 일반 앱 흐름과 관련된 플래그를 유지하는 것이 좋습니다. 로그인하지 않은 것으로 확인되면 다른 로그인 시도가 명확해질 때까지 사용자 상태 확인으로 모델을 귀찮게하지 마십시오.
마찬가지로 적절한 뷰 객체와 대부분의 서버 측 웹 프레임 워크에서 볼 수있는보다 일반적인 HTML 템플릿이 있습니다. 사용자의 색상 기본 설정이로드되면 해당 데이터를 유지하고 실행하는보기 여야합니다. 설정로드, 확인 및 변경은 모두 모델 문제이지만 변경이 발생할 때까지 한 번만 모델 문제 여야합니다.
IMO는 컨트롤러가 뷰와 모델을 내부 집계 개체로 사용하는 복합 개체가 될 수 없다고 말합니다. 컨트롤러는 뷰와 모델이 상호 작용하는 방식에 대한 데이터와 논리 세부 정보를 묻고 높은 수준의 앱 개체에 인터페이스를 노출하기에 이상적인 장소이므로 UI 위젯 팩토리와 같이 소규모로 MVC를 적용하는 경우 실제로 의미가 있습니다. 컨트롤러가 실제로 가장 높은 수준의 개체 인 독점 앱 개체에는 실제로 의미가 없습니다.
내가 이해 한대로; 인수는 컴포넌트 기반 아키텍처 대 OOP입니다. 그리고 종교 전쟁에 들어 가지 않고, 나는 그들이 같은 것을 묘사하고 있다고 생각합니다. 다른 각도에서 보면
예를 들어, OOP / OOD의 핵심은 코드를 더 모듈화하고 재사용 할 수있게하는 것입니다. 예?
정확히 컴포넌트 기반 아키텍처의 목표입니다. 그래서 그들은 다른 것보다 더 비슷합니다.
MVC는 OOP의 자연스런 진화라고 생각합니다. 객체를 정리하고 우려를 분리하고 코드를 재사용하는 더 좋은 방법.
MVC에는 안티뿐만 아니라 OOP도 필요하지 않습니다.
일반적으로 클래스로 표시되는 컨트롤러는 데이터를 보유하지 않기 때문입니다. 순수한 기능으로는 충분합니다.
예를 들어, 데이터를 동작과 분리하고 분리하는 경우 모델이 데이터베이스 데이터에 대해서만 작동한다고 가정 해 봅시다.이 데이터는 인스턴스에 어떤 종류의 데이터를 저장하는 대신 함수 (데이터 조작을 담당하는)가 호출 될 때마다 가져옵니다. 필드)-그런 다음 모델에 대해 동일하게 말할 수 있습니다.
더 나아가 응용 프로그램의 뷰 레이어를 비슷한 방식으로 나누면 실제로 MVC는 OOP와 아무런 관련이 없다는 결론으로 끝날 것이며 절차 적 접근 방식 만 사용하면 아무런 어려움없이 MVC 구현을 작성할 수 있습니다. .
내 의견에서 OOP는 (데이터와 행동)이 하나의 엔티티 (클래스)로 성형되기 때문에 응집력보다 결합 효과가 더 크다는 단점이 있습니다. 반면 MVC에는 Models ... (Beans, DAO, Other Logic 클래스), 컨트롤이 이동하는 방법을 지정하는 Controller 및 데이터 표시 방법을 결정하는 뷰가 분리 된 방식으로 제공됩니다. 이를 바탕으로 프로젝트가 너무 큰 경우에도 OOP와 달리 혼합되지 않고 별도의 엔티티로 쉽게 만들 수 있습니다. 문제는 분할 n 정복 전략과 같은 논리적 패턴으로 해결되며 MVC가이를 따릅니다.