비즈니스 로직이 시야에 들어오지 않을 수 있습니까?


31

지난 3 년간 여러 웹 응용 프로그램 프로젝트를 위해 개인적으로나 직장에서 개발했으며 적어도 일부 비즈니스 논리가 응용 프로그램의 뷰 계층에서 끝나지 않는지 알아낼 수 없습니다 .

대부분의 경우, "사용자가 옵션 x를 선택했다면 응용 프로그램은 y에 대한 정보를 제공 할 수 있어야합니다. 그렇지 않은 경우 정보 z를 제공해야합니다"와 같은 문제가 발생합니다. 또는 AJAX 작업을 수행하여 모델에 일부 변경 사항을 적용해야하지만 사용자가 명시 적으로 요청할 때까지 커밋하지 마십시오. 이것들은 내가 직면 한 가장 간단한 문제 중 일부이며보기에서 복잡한 논리를 피할 수있는 방법을 알 수 없습니다.

MVC에 대해 읽은 대부분의 책은 일반적으로 서버에서 데이터를 업데이트하고 표시하는 CRUD 작업과 같은 아주 간단한 예를 보여 주지만 CRUD는 대부분의 응용 프로그램에서는 그렇지 않습니다.

비즈니스 로직이 전혀없는 견해를 가질 수 있습니까?


2
MVC 파생 MVP 및 MVVM ( en.wikipedia.org/wiki/Model_View_Presenteren.wikipedia.org/wiki/Model_View_ViewModel 참조 )을 살펴보면 원하는 것일 수 있습니다.
Doc Brown


2
뷰는 데이터와 로직의 외부에서 보이는 표현입니다. 비즈니스 논리를 제시하지 않을 수 없습니다. 또는 뷰에 코드가 없어야한다고 말하고 있습니까? 확실히 HTML 전용보기를 만들 수 있습니다.
BobDalgleish

템플릿 애니메이션을 볼 수 있습니다 . 이것은 아마도 뷰 레이어 에서 모든 로직을 제거하지는 않지만 약간 더 나은 분리로 이어질 것 같습니다.
paul

더 나은 질문은 뷰 데이터가 모델을 오염시키는 것이 더 나은지 또는 비즈니스 로직과 관련된 뷰 로직을 포함하는 것이 더 나은지 여부입니다. 이것이 실제 시나리오입니다. 귀하의 질문은 본질적으로 모델의 오염을 주장하여 뷰를 지원하도록 요구하는 것입니다.
Dunk

답변:


22

비즈니스 로직이 전혀없는 견해를 가질 수 있습니까?

나는 이것이 대답하기 어려운 결정적인 질문이라고 생각합니다. (생각하는 질문입니다!)

이론적으로, 우리가 비즈니스 로직으로 정의한 것에 따라 다릅니다. 실제로, 엄격한 분리는 훨씬 더 어려워지고 어쩌면 바람직하지 않을 수도 있습니다.

관심사 분리는 소프트웨어 구축에 대해 생각할 수있는 좋은 방법입니다. 코드를 배치 할 위치에 대한 아이디어를 제공하고 관리자에게 코드를 찾을 위치에 대한 좋은 아이디어를 제공합니다. 나는 인간이 우려를 분리하지 않고 작동하는 소프트웨어를 만드는 것은 기본적으로 불가능하다고 주장합니다. 우리는 이것이 필요합니다.

그러나 모든 것과 마찬가지로 절충점이 있습니다. 최상의 개념 위치는 다른 이유로 최상의 위치가 아닐 수 있습니다. 웹 서버에로드가 너무 많을 수 있으므로 웹 페이지에 자바 스크립트를 추가하여 서버에 닿기 전에 입력 오류를 쉽게 잡을 수 있습니다. 지금 당신은 당신의 견해에 약간의 비즈니스 논리가 있습니다.

뷰 자체는 비즈니스 로직 없이는 가치가 없습니다. 그리고 내재적으로나 명시 적으로 사용하고 표시하는 데 효과적이기 위해서는 비즈니스 프로세스에 대한 지식이 필요합니다. 우리는 그러한 지식의 양을 제한 할 수 있고, 지식의 일부를 제거 할 수 있지만, 실제적인 고려는 종종 우리가 우려의 분리를 '파괴'하도록 강요 할 것입니다.


2
The best conceptual location may not be the best location for other reasons브라보 !!
Magno C

8

나는 보통 이렇게한다 : 사용자가 옵션 x를 선택하면보기 호출

controller->OptionXChanged()

그런 다음 컨트롤러가보기에서 y를 활성화하십시오.

view->SetEnableInfoY(True) // suppose False=SetDisable

보기는 아무것도 결정하지 않고 컨트롤러에 통지합니다.


+1. 영업 이익의 사소한 문제는 일반적으로 사소 응용 프로그램에서 다음과 같이 처리 할 것
dev_feed

이 논리를 컨트롤러에 두는 데는 두 가지 문제가 있습니다. 1) 단위 테스트가 복잡하고 동일한 데이터의 여러보기를 지원할 수 없습니다.
케빈 클라인

4

나는 당신이 묘사 한 예가 실제로 비즈니스 논리인지 의문을 제기합니다. 설명하는 예는 시스템에서 수행 할 수있는 조작입니다. 보기에서 비즈니스 로직을 수행하고있는 것처럼 보일 수있는 선택 사항을 사용자에게 제공하는 방법입니다.

"보기"의 ​​장점에서 시스템에 InfoY 또는 InfoZ 만 제공합니다. UI 구현이 오퍼레이터 선택에 따라 (즉, InfoY 또는 InfoZ 활성화) 일부 동적 업데이트를 수행한다고해서 기능적인 비즈니스 논리를 만들지는 않습니다. 실제로 뷰 구현 로직입니다. 운영자에게 전체 활성화 작업없이 InfoY 또는 InfoZ를 입력 할 수있는 옵션을 제공했을 수 있습니다. 그런 맥락에서 여전히 비즈니스 로직이라고 생각하십니까? 그렇지 않은 경우 정보 필드를 동적으로 활성화 / 비활성화하는 경우에도 동일하게 적용됩니다.

커밋 예제도 마찬가지입니다. 시스템이 올바르게 작동하기 위해 필요한 2 가지 작업입니다. 원하는 기능을 수행하기 위해 View에서 적절한 작업을 시작할 수 있어야합니다. 시스템 사용 방법을 아는 것이 비즈니스 로직이 유출되는 것을 의미합니까? 나는 누군가가 어떻게 말할 수 있는지 알 수 있지만 당신이 그렇게 믿는다면 실제로는 비즈니스 로직을 다른 것과 분리하는 것과 같은 것이 없다는 것입니다. 의미있는 것을 달성하기 위해 시스템이 수행하고있는 작업을 알아야합니다. 그렇지 않으면 상상할 수있는 모든 MVC 응용 프로그램에서 작동하는 단일 일반 뷰 및 컨트롤러를 만드는 것이 매우 쉬울 것입니다. 우리가 아는 것은 불가능합니다.

결론적으로, 비즈니스 로직에 대한 정의는 다른 정의와 동일하지 않다고 생각합니다.


1

나는 이런 식으로 일한다 (Struts2 + Hibernate) :

My Struts Actions는 웹 브라우저의 정보 표시 만 담당합니다. 생각하지 않습니다.

사용자-> 조치-> 서비스-> 저장소-> 데이터 액세스

또는:

보고 싶어요-> 보는 방법->해야 할 일-> 얻는 방법-> 어디로

따라서 첫 번째 레이어 (보기)에는 다음과 같은 것이 있습니다.

public String execute ()   {
    try {
        CourseService cs = new CourseService();
        Course course = cs.getCourse(idCourse);
    } catch (NotFoundException e) {
        setMessageText("Course not found.");
    } catch (Exception e) {

    }
    return "ok";
}

보시다시피, 나의 "보기"는 생각하지 않습니다. 특정 코스에 대한 서비스 (코스 관리)를 요청합니다. 이 서비스는 보고서, 뱀 등과 같은 많은 일을 더 많이 할 수 있습니다. 결과는 항상 목록 또는 특정 개체 (예 : 예)입니다. 서비스는 실제 머신이며 규칙을 적용하고 리포지토리에 액세스하여 데이터를 관리합니다.

따라서 서비스, 리포지토리 및 DAOS를 다른 라이브러리에 배치하면 텍스트 기반 프로그램이나 아무것도 변경하지 않은 Window 기반 데스크톱 시스템에서도 사용할 수 있습니다.

이 서비스는해야 할 일을 알고 있지만 보여줄 방법을 모릅니다. 보기는 표시하는 방법을 알고 있지만 수행 할 작업을 모릅니다. 서비스 / 리포지토리와 동일 : 서비스가 데이터를 보내고 요청하지만 데이터의 위치와 수행 방법을 모릅니다. 리포지토리는 서비스와 함께 작업 할 수 있도록 원시 데이터를 buisines 객체로 "구성"합니다.

그러나 리포지토리는 데이터베이스에 대해 아무것도 모릅니다. 데이터베이스 종류 (MySQL, PostgreSQL 등)는 DAO와 관련이 있습니다.

데이터베이스를 변경하려는 경우 DAO를 변경할 수 있으며 상위 계층에 영향을 미치지 않아야합니다. 데이터 관리를 업데이트하려는 경우 리포지토리를 변경할 수 있지만 DAO 및 상위 계층에는 영향을 미치지 않아야합니다. 논리를 변경하려는 경우 서비스를 변경할 수 있지만 위와 아래의 계층을 망칠 수는 없습니다.

또한 기술 (웹, 데스크탑, 텍스트)을 포함하여 모든 것을 볼 수 있지만 아래의 내용과 접촉해서는 안됩니다.

비즈니스 로직은 서비스입니다. 그러나 이것과 상호 작용하는 방법은 보는 것입니다. 지금 표시 할 단추는 무엇입니까? 사용자가이 링크를 볼 수 있습니까? 시스템이 콘솔 기반 프로그램이라고 생각하십시오. 잘못된 사용자 #> myprogram -CourseService -option=getCourse -idCourse=234가 키를 눌러이 명령을 작성 하도록 선택 하거나 중지 해야하는지 거부해야 합니까?

웹 기반 시스템에서 말하기 (Struts + JavaEE) 별도의 GUI 컨트롤러 패키지가 있습니다. 작업보기에서 로그 된 사용자에게 클래스를 제공하고 클래스는 버튼 (또는 원하는 인터페이스 요소)을 제공합니다.

                <div id="userDetailSubBox">
                    <c:forEach var="actionButton" items="${actionButtons}" varStatus="id">
                        ${actionButton.buttonCode}
                    </c:forEach>
                </div>

private List<ActionButton> actionButtons;

이를 서비스에서 멀리 보관하십시오. VIEW 항목입니다. Struts Actions에 유지하십시오. 인터페이스 상호 작용은 실제 비즈니스 코드와 완전히 분리되어야하므로 시스템을 이식하면 더 이상 필요하지 않은 것을 쉽게자를 수 있습니다.


1

대부분의 경우 "사용자가 옵션 x를 선택한 경우 응용 프로그램은 y에 대한 정보를 제공 할 수 있어야합니다. 그렇지 않은 경우 정보 z를 제공해야합니다."

그것은 뷰가 아니라 모델의 논리입니다. UI를 지원하기 위해 특별히 만들어진 "뷰 모델"일 수 있지만 여전히 모델 논리입니다. 제어 순서는 다음과 같습니다.

  • 컨트롤러는 뷰 이벤트를위한 핸들러를 연결합니다
  • 뷰는 모델 이벤트에 대한 핸들러를 첨부합니다.
  • 사용자는 옵션 X를 선택합니다.
  • 보기에서 "옵션 X 선택"이벤트가 발생합니다.
  • 컨트롤러가 이벤트를 수신하고 model.selectOptionX ()를 호출합니다.
  • 모델이 "모델 상태 변경됨"이벤트를 발생시킵니다.
  • 보기는 모델 변경 이벤트를 수신하고 새 상태와 일치하도록보기를 업데이트합니다. inputY.enable(model.yAllowed()); inputZ.enable(model.zAllowed());

UI View Controller Model |.checkbox X checked.> | | | | | .. X selected ...>| | | | |-----> set X ------->| | | | | | |< .............state changed ............| | | | | | |-------------- Get state --------------->| | | | | | |<----------- new state ------------------| | <-- UI updates ------| 이것이 전형적인 MVC 패턴입니다. UI와 별도로 모델 로직을 완전히 테스트 할 수 있습니다. 컨트롤러와보기는 매우 얇고 테스트하기 쉽습니다.

=== 덩크에 대한 응답으로 ===

UI MVC 패턴의 모델은 일반적으로 비즈니스 오브젝트 모델이 아닙니다 . UI 상태의 모델 일뿐입니다. 데스크톱 응용 프로그램에서는 여러 비즈니스 모델에 대한 참조를 보유 할 수 있습니다. Web 2.0 애플리케이션에서 UI 상태를 유지하고 AJAX를 통해 서버와 통신하는 Javascript 클래스입니다. 대부분의 UI 버그가있는 곳에서 UI 상태 모델의 핸즈 오프 단위 테스트를 작성할 수있는 것이 매우 중요합니다. 뷰와 컨트롤러는 매우 얇은 커넥터 여야합니다.


1
MVC의 정의가 무엇이라고 생각하는지에 달려 있습니다. 이 버전은 MVC에 대한 매우 엄격한 해석을 확실히 준수합니다. 문제는이 엄격한 해석이 실생활에서 유용하거나 유지 관리 가능한 시스템을 제공하는 경우는 거의 없다는 것입니다. 새로운 UI 요소 / 무언가를 수행하는 방법이 생길 때마다 모델을 변경해야하기 때문입니다. 그런 다음 UI에만 관련된 쓸모없는 속성으로 인해 모델이 복잡해집니다. 이들은 빌드하려는 응용 프로그램과 관련이 없지만 운영자에게 데이터를 제공하려는 방법에만 관련이 있습니다. 나쁜!
Dunk

kevin 댓글 상자에 답장을 보내 주시면 답장을 쉽게 보내실 수 있습니다. 동의합니다. 어떤 종류의 구조도없이 인터페이스 (UI) 정보를 유지할 수는 없지만 "MODEL"명명법은 혼동 될 수 있습니다. @Dunk가 말하는 것을 쉽게 수행 할 수 있도록 다른 교환 가능한 패키지로 UI 항목을 관리하는 것을 선호합니다. 내 대답을 참조하십시오.
Magno C

@MagnoC : 추가 된 텍스트가 답을 향상 시킨다고 생각했기 때문에 Dunk에 대한 응답으로 편집했습니다. 그것이 바로 사이트의 주제입니다 : 질문과 답변. 모델은 일반적인 용어이며 MVC 패턴에서 "UI 상태 모델"을 의미합니다.
케빈 클라인

0

비즈니스 로직은보다 비슷 If X then return InfoType.Y하며 UI는 도메인이 반환 한 결과에 따라 필드를 표시합니다.

// Controller method pseudocode
option changed routine

    get selected option

    get required info type from domain routine based on selected option

    display fields based on required info type

UI에 비즈니스 로직이 필요한 경우 선택 항목을 도메인에 위임하십시오. UI는 단순히 결정에 따라 행동합니다.


0

사용자가 옵션 x를 선택한 경우, 응용 프로그램은 y에 대한 정보를 제공 할 수 있어야하고, 그렇지 않은 경우에는 정보 z를 제공해야합니다. "

조건에 따라 필요한 값을 가진 입력이 있습니다. 대부분의 GUI 환경에서, 특히 타이밍을 처리하는 방법에 대한 많은 선택이 있습니다. 선택한 옵션 (이 경우 x)을 처리해야하므로 컨트롤러로 보내십시오. 사용자가 입력 필드를 떠날 때 보냅니다. 다른 객체를 클릭하거나 저장을 누를 때까지 기다리십시오. 비즈니스 로직에는 중요하지 않습니다. 어떤 식 으로든 컨트롤러는 결정을 내릴 것이며 "y is required"라는 견해를 알려야합니다.

뷰가 이것을 해석하거나 구현하는 방법은 실제로 비즈니스 로직 관점에서 중요하지 않습니다. 필수 입력란을 작성하십시오. 팝업을하거나 대포를 쏘고 사용자에게 y를 입력하거나 완고하게 지시하고 가난한 사용자가 이것을 알아낼 때까지 아무것도하지 못하게하십시오.

컨트롤러가 저장을 시도하고 데이터베이스의 필수 필드에 값을 입력하지 않았으며 순수하게 데이터베이스 오류에 응답했기 때문에이 모든 것이 발생했을 수 있습니다. 견해에 관한 한 중요하지 않습니다.

입력에 필요한 값이나 제한된 값과 같은 것을 여러 곳에서 처리 할 수 ​​있습니다. 보기에서 "만"해결하면 여러 사용자 인터페이스가있을 때 많은 개발자가이를 문제로 간주합니다. 그렇기 때문에 많은 사용자 인터페이스 나 데이터베이스 없이도 비즈니스 로직을 작성하고 테스트 할 수 있습니다. 웹 사이트가 없어도됩니다.

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