자바 스크립트 모듈성, 서버 기반 MVC 및 비즈니스 현실


32

나는 이것이 매우 광범위한 질문 이라는 것을 이해 하지만이 문제의 다양한 측면을 개별적으로 다루었 고 모든 개념과 기술을 하나로 모으는 데 어려움을 겪고 있습니다.

답변에 다음 기술이 포함되도록 지정하고 싶습니다.

  • 기음#
  • 면도기 포함 MVC 3
  • 자바 스크립트 w / jQuery

Backbone.js , Entity Framework 등과 같은 것을 넘어 서면 다음과 같은 질문에 대한 답변을 얻을 수 있습니다.

위에 나열된 기술을 사용하여 확장 성과 유지 관리 기능이 풍부하고 빠르고 깨끗한 UI를 만드는 기능을 유지하면서 코드와 논리를 구성하기위한 최적의 전략 은 무엇 입니까?

비즈니스 / 기업 환경에 배포되는 솔루션에 초점을 두는 것이 이상적입니다. 참고로, 위의 기술 목록 은 변경 되지 않으므로 " 현재 사용중인 yyy 대신 xxx 를 사용해야합니다"솔루션을 제공하지 마십시오 .

배경

나는 매일 jQuery와 함께 일하고 ASP.NET의 MVC를 채택했으며 오랫동안 C #과 함께 일해 왔습니다. 따라서 해당 기술에 대한 중급에서 고급 지식을 전제로 솔루션을 제시 할 수 있습니다.

질문을 더 작은 부분 으로 구성하여보다 쉽게 ​​응답 할 수 있도록하겠습니다.

1. 프로젝트 구조

ASP.NET MVC ( Visual Studio 2010 )로 작업하고 있다고 가정하면 이 유형의 응용 프로그램의 기본 레이아웃을 수용 할 수있는 디렉토리 구조 솔루션을 원합니다. Brunch 와 같은 것이 있지만 각 폴더에 포함 된 내용과 앱의 다른 영역과 어떻게 작동하는지 조금 더 자세히 설명합니다.

2. 데이터 액세스

API 유형 구조로 가능한 한 많이 데이터 액세스를 모듈화하고 싶습니다. 당신은 POCO 개체 (많은 가정 할 수있다 User, UserGroup, Customer, OrderHeader, OrderDetails, 등)뿐만 아니라, 데이터 집약적 인 SQL 및주의 UI 렌더링을 필요로하는 일부 복잡한 보고서가있을 것입니다. EF + LINQ 는 전자에게는 환상적이지만 후자는별로 훌륭하지 않습니다. 지나치게 복잡하거나 지나치게 단순하지 않으면 두 시나리오에 모두 맞는 것으로 보이지 않습니다.

3. 클라이언트 측 코드 구성 및 UI 렌더링

대부분의 개발자가 처음 jQuery를 집어 들었 듯이, 코드는 어디로 가야하는지에 관계없이 코드를 모으는 함정에 빠졌습니다. 그 이후로 도약하고 한계가 있지만 코드를 반복하지 않고 코드를 모듈화하고 UI의 다양한 부분을 다루는 데 어려움을 겪고 있습니다.

예를 들어, 내가 작성할 수있는 전형적인 코드는 다음과 같습니다. 저는 귀찮게하는 것들에 대해 언급했습니다 ( 이후 지연된 AJAX 호출을 사용하도록 변경하고 실제 데이터 요청을 DOM 조작과 분리했습니다 ).

$('#doSomethingDangerous').click(function () {
    // maybe confirm something first
    if (confirm('Are you sure you want to do this?')) {   

        // show a spinner?  something global would be preferred so I don't have to repeat this on every page 
        $('#loading').show();  

        // maybe the page should notify the user of what's going on in addition to the dialog?
        $('#results').show().html('<h2>Please wait, this may take a while...</h2>');  

        $.ajax({
            url: 'blah/DoDangerousThing',
            success: function (data) {                     
                // The results will be loaded to the DOM obviously, is there a better way to pull this type of specific code out of the data access calls?
                $('#results').empty();
                $('#results').append('<b>' + data.length + '</b> users were affected by this dangerous activity');
                $('#results').append('<ul>');

                // I've recently started to use jQuery templates for this sort of logic, is that the way to go?
                $(data).each(function (i, user) {
                    $('#results').append('<li>' + user.Username + '</li>');
                });                    
                $('#results').append('</ul>');

                // Need to hide the spinner, again would prefer to have this done elsewhere
                $('#loading').hide();
            }
        });
    }
});

일반적인 질문들

  • 클라이언트 MVC 대 서버 MVC? 내 프로젝트는 이미 서버 측 MVC 구조이므로 Backbone.js가 제공하는 것과 같은 클라이언트 MVC가 여전히 필요합니까?
  • Javascript 파일을 각 객체 (예 OrderHeader.js:) 에 대해 생성 한 다음 빌드 중에 축소 / 병합해야합니까? 아니면 등에 Order.js대한 논리 가있는 것이 있어야 OrderHeader, OrderDetails, Reports합니까?
  • 복잡한 쿼리는 어떻게 처리해야합니까? 현재 내 주요 이론은 /Reports/Orders-By-Date/그 라인을 따라 있거나 무언가이며 ViewModelRazor View에 사용자 정의 데이터 세트 (또는 )를 렌더링하는 사용자 정의 SQL 쿼리를 사용합니다 . 그러나 페이징, 정렬 등은 어떻습니까? 클라이언트 또는 서버 측에서 수행하는 것이 더 낫습니까? (더 큰 데이터 세트-2 ~ 3 초 SQL 쿼리를 가정)
  • Microsoft의 Project Silk를 읽었습니다 . 이것이 좋은 방법입니까? Backbone.js 또는 다른 것과 어떻게 비교됩니까?
  • 나는 N- 계층 구조에 매우 익숙합니다. 이러한 개념이 다소 창 밖으로 던져 지는가? MVC는 과거에 프론트 엔드 또는 최상위 계층에 있었던 미니 N 계층 섹션과 같습니다.

다시 한 번 더 구체적으로 대답하면 더 좋습니다. 높은 수준의 문서와 예제를 많이 읽었으며 실제 예제로 번역 하는 것을 더 잘 이해 하려고 노력하고 있습니다 .


2
이 질문에 많은 노력을 기울 였지만 그것은 Stackoverflow 질문처럼 보이지 않습니다. 아마도 프로그래머 stackexchange가 더 적합 할 것입니다.
Pointy

3
나는 그것이 흥미로운 주제라는 것에 동의하지 않지만 Stackoverflow는 객관적인 질문 에 관한 입니다. 이 질문과 같은 것은 기본적으로 "의견, 토론, 논쟁, 여론 조사 또는 확장 된 토론을 요구할 것"인 질문에 대한 포스터 아동입니다.
Pointy

8
결코 큰 일을 계획하지 않는 사람들의 캠프가 있습니다. 나는 결코 일어나지 않은 일을 너무 오래 계획했기 때문에 사업을 조용히 빼앗 았습니다.
Jason Sebring

1
나는 이것이 프로그래머 스택에 속한다는 @Pointy에 동의합니다. 귀하의 질문은 매우 흥미 롭습니다. 저는 항상 조언을 찾고 있기 때문에 그것을 쫓아 낼 것입니다. 그러나 이것은 객관적인 질문이 아니며 우선적 인 토론으로 끝나고 있습니다. 항상 그렇듯이, 귀하의 상황에 가장 적합한 것을 수행하십시오 ... 우리 중 누구도 귀하의 네트워크 구조, 클라이언트 또는 트래픽 통계 또는 빌드 프로세스에 대해 아무것도 모릅니다. 그래서 질문은 너무 모호합니다. 실크를 피하십시오. ;)
one.beat.consumer

1
이 질문은 "과도하게 광범위하다"라는 정의에 부합하므로 "실제 질문은 아니다". 어떤 것이 든 , 개별 질문 은 약간의 배경을 가진 개별 질문으로 제기되어야합니다 (너무 많은 사람들은 "실제 질문이 아님") 그러나 귀하가 요청하는 많은 개별 질문이 자체적으로 "건설적이지 않은"것으로 표시 될 수 있으므로주의를 기울이는 방법에주의를 기울여야합니다.
casperOne

답변:


10

TerryR 내 친구, 너와 나는 술을 마셔야한다. 비슷한 문제가 있습니다.

1. 프로젝트 구조 : MVC 앱의 폴더 구조가 원하는 것으로 남겨둔다는 Eduardo의 의견에 동의합니다. 표준 컨트롤러, 모델 및보기 폴더가 있습니다. 그러나 Views 폴더는 각 컨트롤러마다 다른 폴더와 공유 폴더로 나뉩니다. 그리고 각 Views / ControllerName 또는 Views / Shared는 EditorTemplates와 DisplayTemplates로 나눌 수 있습니다. 그러나 모델 폴더를 구성하는 방법을 결정할 수 있습니다 (하위 폴더와 추가 네임 스페이스 선언을 사용하거나 사용하지 않고 수행 할 수 있음).

각 영역에 대한 컨트롤러, 모델 및보기 폴더 구조를 복제하는 영역을 사용하지 마십시오.

/Areas
    /Area1Name
        /Controllers
            FirstController.cs
            SecondController.cs
            ThirdController.cs
        /Models
            (can organize all in here or in separate folders / namespaces)
        /Views
            /First
                /DisplayTemplates
                    WidgetAbc.cshtml <-- to be used by views in Views/First
                /EditorTemplates
                    WidgetAbc.cshtml <-- to be used by views in Views/First
                PartialViewAbc.cshtml <-- to be used by FirstController
            /Second
                PartialViewDef.cshtml <-- to be used by SecondController
            /Third
                PartialViewMno.cshtml <-- to be used by ThirdController
            /Shared
                /DisplayTemplates
                    WidgetXyz.cshtml <-- to be used by any view in Area1
                /EditorTemplates
                    WidgetXyz.cshtml <-- to be used by any view in Area1
                PartialViewXyz.cshtml <-- to be used anywhere in Area1
            _ViewStart.cshtml <-- area needs its own _ViewStart.cshtml
            Web.config <-- put custom HTML Helper namespaces in here
        Area1NameRegistration.cs <-- define routes for area1 here
    /Area2Name
        /Controllers
        /Models
        /Views
        Area2NameRegistration.cs <-- define routes for area2 here

/Controllers
    AccountController.cs
    HomeController.cs
/Models
/Views
    /Account
        /DisplayTemplates
            WidgetGhi.cshtml <-- to be used views in Views/Account
        /EditorTemplates
            WidgetGhi.cshtml <-- to be used views in Views/Account
        PartialViewGhi.cshtml <-- to be used by AccountController
    /Home
        (same pattern as Account, views & templates are controller-specific)
    /Shared
        /DisplayTemplates 
            EmailAddress.cshtml <-- to be used by any view in any area
            Time.cshtml <-- to be used by any view in any area
            Url.cshtml <-- to be used by any view in any area
        /EditorTemplates
            EmailAddress.cshtml <-- to be used by any view in any area
            Time.cshtml <-- to be used by any view in any area
            Url.cshtml <-- to be used by any view in any area
        _Layout.cshtml <-- master layout page with sections
        Error.cshtml <-- custom page to show if unhandled exception occurs
    _ViewStart.cshtml <-- won't be used automatically in an area
    Web.config <-- put custom HTML Helper namespaces in here

즉, WidgetController와 같은 작업을 수행하는 경우 관련 WidgetViewModels, WidgetViews, WidgetEditorTemplates, WidgetDisplayTemplates 등을 찾으려면 다른 폴더를 살펴 봐야합니다. 이러한 MVC 규칙. 모델, 컨트롤러 및 뷰를 동일한 폴더에 다른 네임 스페이스가있는 한 ReSharper를 사용하므로 이것을 피하십시오. 클래스가있는 폴더와 일치하지 않는 네임 스페이스에 빠르게 밑줄을 긋습니다. 이 R # 기능을 해제 할 수 있지만 프로젝트의 다른 부분에 도움이됩니다.

비 클래스 파일의 경우 MVC는 즉시 컨텐츠 및 스크립트를 제공합니다. 우리는 모든 정적 / 컴파일되지 않은 파일을 이러한 장소에 다시 유지하여 규칙을 따릅니다. 테마 (이미지 및 CSS)를 사용하는 js 라이브러리를 통합 할 때마다 테마 파일은 모두 / content 아래에 있습니다. 스크립트의 경우 모든 스크립트를 / scripts에 직접 넣습니다. 원래 이것은 VS에서 JS intellisense를 가져 오는 것이었지만 이제는 / scripts의 배치에 관계없이 R #에서 JS intellisense를 얻었으므로 그로부터 벗어날 수 있고 스크립트를 폴더별로 나누어 더 잘 정리 할 수 ​​있다고 가정합니다. ReSharper를 사용하고 있습니까? 순금 IMO입니다.

리팩토링에 많은 도움이되는 또 다른 작은 금 조각은 T4MVC입니다. 이를 사용하여 영역 이름, 컨트롤러 이름, 작업 이름, 심지어 콘텐츠 및 스크립트의 파일에 대한 문자열 경로를 입력 할 필요가 없습니다. T4MVC는 모든 매직 스트링을 강력하게 입력합니다. 다음은 T4MVC를 사용하는 경우 프로젝트 구조가 중요하지 않은 방법에 대한 작은 샘플입니다.

// no more magic strings in route definitions
context.MapRoutes(null,
    new[] { string.Empty, "features", "features/{version}" },
    new
    {
        area = MVC.PreviewArea.Name,
        controller = MVC.PreviewArea.Features.Name,
        action = MVC.PreviewArea.Features.ActionNames.ForPreview,
        version = "december-2011-preview-1",
    },
    new { httpMethod = new HttpMethodConstraint("GET") }
);

@* T4MVC renders .min.js script versions when project is targeted for release *@
<link href="@Url.Content(Links.content.Site_css)?r=201112B" rel="stylesheet" />
<script src="@Url.Content(Links.scripts.jquery_1_7_1_js)" type="text/javascript">
</script>

@* render a route URL as if you were calling an action method directly *@
<a href="@Url.Action(MVC.MyAreaName.MyControllerName.MyActionName
    (Model.SomeId))">@Html.DisplayFor(m => m.SomeText)</a>

// call action redirects as if you were executing an action method
return RedirectToAction(MVC.Area.MyController.DoSomething(obj1.Prop, null));

2. 데이터 액세스 : PetaPoco에 대한 경험이 없지만 체크 아웃 할 가치가 있다고 확신합니다. 복잡한 보고서의 경우 SQL Server Reporting Services를 고려 했습니까? 아니면 다른 DB에서 실행 중입니까? 정확히 당신이 요구하는 것이 확실하지 않습니다. EF + LINQ를 사용하지만 도메인 클래스에서 보고서를 생성하는 방법에 대한 특정 지식도 제공합니다. 따라서 컨트롤러 호출 저장소를 직접 사용하는 대신 컨트롤러 호출 도메인 서비스 호출 저장소가 있습니다. 임시 보고서의 경우 SQL Reporting Services를 사용하지만 완벽하지는 않지만 사용자는 데이터를 Excel로 쉽게 가져올 수 있기를 원하며 SSRS를 통해 쉽게 사용할 수 있습니다.

3. 클라이언트 측 코드 구성 및 UI 렌더링 : 여기에 도움이 될 수 있습니다. MVC 눈에 띄지 않는 유효성 검사 및 눈에 잘 띄지 않는 AJAX 책에서 페이지를 가져옵니다. 이걸 고려하세요:

<img id="loading_spinner" src="/path/to/img" style="display:none;" />
<h2 id="loading_results" style="display:none;">
    Please wait, this may take a while...
</h2>
<div id="results">
</div>
<input id="doSomethingDangerous" class="u-std-ajax" 
    type="button" value="I'm feeling lucky" 
    data-myapp-confirm="Are you sure you want to do this?"
    data-myapp-show="loading_spinner,loading_results" 
    data-myapp-href="blah/DoDangerousThing" />

지금은 아약스 성공 함수를 무시하십시오 (나중에 자세히 설명). 일부 작업에 대해 단일 스크립트를 사용하여 벗어날 수 있습니다.

$('.u-std-ajax').click(function () {
    // maybe confirm something first
    var clicked = this;
    var confirmMessage = $(clicked).data('myapp-confirm');
    if (confirmMessage && !confirm(confirmMessage )) { return; } 

    // show a spinner?  something global would be preferred so 
    // I dont have to repeat this on every page 
    // maybe the page should notify the user of what's going on 
    // in addition to the dialog?
    var show = $(clicked).data('myapp-show');
    if (show) {
        var i, showIds = show.split(',');
        for (i = 0; i < showIds.length; i++) {
            $('#' + showIds[i]).show();
        }
    }

    var url = $(clicked).data('myapp-href');
    if (url) {
        $.ajax({
            url: url,
            complete: function () {                     
                // Need to hide the spinner, again would prefer to 
                // have this done elsewhere
                if (show) {
                    for (i = 0; i < showIds.length; i++) {
                        $('#' + showIds[i]).hide();
                    }
                }
            }
        });
    }
});

위의 코드는 확인을 처리하고 스피너를 표시하고 대기 메시지를 표시하며 아약스 호출이 완료된 후 스피너 / 대기 메시지를 숨 깁니다. 눈에 거슬리지 않는 라이브러리와 같은 data- * 속성을 사용하여 동작을 구성합니다.

일반적인 질문들

-클라이언트 MVC 대 서버 MVC? 컨트롤러가 JSON을 반환하는 것처럼 보이기 때문에 성공 함수에서 수행 한 작업을 유지하려고하지 않았습니다. 컨트롤러가 JSON을 반환하는 경우 KnockoutJS를 살펴볼 수 있습니다. 녹아웃 JS 버전 2.0이 오늘 출시되었습니다 . JSON에 바로 연결할 수 있으므로 관찰 가능한 클릭이 자동으로 데이터를 자바 스크립트 템플릿에 바인딩 할 수 있습니다. 반면에 아약스 액션 메서드가 JSON 대신 HTML을 반환하도록 신경 쓰지 않는다면 이미 구성된 UL을 LI 자식과 함께 반환 할 수 있으며 data-myapp-response =를 사용하여 요소에 추가 할 수 있습니다 "결과". 성공 함수는 다음과 같습니다.

success: function(html) {
    var responseId = $(clicked).data('myapp-response');
    if (responseId) {
        $('#' + responseId).empty().html(html);
    }
}

이에 대한 최선의 대답을 요약하면 액션 메서드에서 JSON을 반환 해야하는 경우 서버 측보기를 건너 뛰므로 실제로 서버 MVC가 아니며 MC 일뿐입니다. html과 함께 PartialViewResult를 아약스 호출에 반환하면 이것이 서버 MVC입니다. 따라서 앱이 ajax 호출에 JSON 데이터를 반환해야하는 경우 KnockoutJS와 같은 클라이언트 MVVM을 사용하십시오.

어느 쪽이든, 레이아웃 (html 태그)과 동작 (비동기 데이터로드)을 혼합하기 때문에 게시 한 JS가 마음에 들지 않습니다. 부분 html 뷰가있는 서버 MVC 또는 순수한 JSON 뷰 모델 데이터가있는 클라이언트 MVVM을 선택하면이 문제가 해결되지만 Javascript에서 DOM / HTML을 수동으로 구성하면 문제가 분리됩니다.

-Javascript 파일 작성 분명히 축소 기능이 .NET 4.5에 제공 될 것입니다 . 눈에 거슬리지 않는 경로로 가면 모든 JS를 1 스크립트 파일로로드하지 못하게하는 것이 없어야합니다. 각 엔티티 유형마다 다른 JS 파일을 작성하는 데주의를 기울이면 JS 파일 폭발이 발생합니다. 스크립트 파일이로드되면 브라우저는 향후 요청을 위해이를 캐시해야합니다.

-복잡한 쿼리 페이지 매김, 정렬 등과 ​​같은 기능을 복잡한 것으로 생각하지 않습니다. DB 쿼리를 필요에 따라 제한적으로 만들기 위해 URL 및 서버 측 논리로 처리하는 것이 좋습니다. 그러나 Azure에 배포되었으므로 쿼리 최적화가 중요합니다. 예를 들면 다음과 같습니다 /widgets/show-{pageSize}-per-page/page-{pageNumber}/sort-by-{sortColumn}-{sortDirection}/{keyword}.. EF 및 LINQ to Entities는 .Take (), .Skip (), .OrderBy () 및 .OrderByDescending ()과 같은 메소드를 사용하여 페이지 매김 및 정렬을 처리 할 수 ​​있으므로 db 트립 중에 필요한 것을 얻을 수 있습니다. 아직 clientlib의 필요성을 찾지 못했기 때문에 솔직히 그들에 대해 많이 알지 못합니다. 그것에 대한 더 많은 조언을 얻으려면 다른 답변을 찾으십시오.

-프로젝트 비단 이것에 대해 들어 본 적이 없는지 확인해야합니다. 나는 Steve Sanderson, 그의 서적, BeginCollectionItem HtmlHelper 및 그의 블로그를 좋아합니다. 즉, 프로덕션에서 KnockoutJS 대한 경험이 없습니다 . 튜토리얼을 확인했지만 버전 2.0 이상이 될 때까지 무언가를 저 지르려고하지 않습니다. 앞서 언급했듯이 KnockoutJS 2.0이 출시되었습니다.

-N-tier 만약 당신이 다른 물리적 기계를 의미한다면, 아니, 나는 창문 밖으로 나가는 것이 없다고 생각합니다. 일반적으로 3 계층은 3 대의 컴퓨터가 있음을 의미합니다. 따라서 사용자의 컴퓨터에서 실행되는 프레젠테이션 계층으로 팻 클라이언트가있을 수 있습니다. 팻 클라이언트는 응용 프로그램 서버에서 실행되고 XML 또는 팻 클라이언트에 무엇이든 반환하는 서비스 계층에 액세스 할 수 있습니다. 그리고 서비스 계층은 세 번째 시스템의 SQL Server에서 데이터를 가져올 수 있습니다.

MVC는 1 계층의 한 계층입니다. 컨트롤러, 모델 및보기는 모두 프리젠 테이션 레이어의 일부이며 물리적 아키텍처에서 1 계층입니다. MVC는 Model-View-Controller 패턴을 구현하여 추가 레이어를 볼 수 있습니다. 그러나이 세 가지 측면을 계층 또는 계층으로 생각하지 마십시오. 이 3 가지를 모두 프레젠테이션 레이어 문제로 생각하십시오.

사전 / 버스 / 데이터 주석 후 업데이트

좋아, 그래서 당신은 계층과 계층을 상호 교환하여 사용하고 있습니다. 나는 보통 논리적 / 프로젝트 / 조립 부문에 "계층"이라는 용어를 사용하고 물리적 네트워크 분리에 계층을 사용합니다. 혼란을 드려 죄송합니다.

MVC 캠프에서 엔터티 데이터 모델에 MVC의 "모델"을 사용하지 말고 비즈니스 로직에 컨트롤러를 사용해서는 안된다고 말하는 사람들이 꽤 있습니다. 이상적으로 모델은 뷰 특정 ViewModel이어야합니다. Automapper와 같은 것을 사용하면 도메인 모델에서 엔티티를 DTO로 가져와 뷰에서 사용하도록 특별히 조각 된 ViewModels로 DTO합니다.

모든 비즈니스 규칙은 도메인의 일부 여야하며 도메인 서비스 / 팩토리 패턴 / MVC 프레젠테이션 계층이 아닌 도메인 계층에 적합한 모든 것을 사용하여 규칙을 구현할 수 있습니다. 컨트롤러는 모델만큼 멍청하지는 않지만 멍청해야하며 비즈니스 지식이 필요한 모든 것에 대해서는 도메인에 책임을 져야합니다. 컨트롤러는 HTTP 요청 및 응답의 흐름을 관리하지만 실제 비즈니스 가치가있는 것은 컨트롤러의 급여 등급보다 높아야합니다.

따라서 프리젠 테이션 레이어로 MVC를 사용하여 레이어 아키텍처를 계속 사용할 수 있습니다. 설계 방식에 따라 응용 프로그램 계층, 서비스 계층 또는 도메인 계층의 클라이언트입니다. 그러나 궁극적으로 엔티티 모델은 MVC의 모델이 아닌 도메인의 일부 여야합니다.


이 답변에 전적으로 동의합니다! 특히 : • Resharper는 MVC의 천재입니다. 오류 확인에서 IDE 탐색에 이르기까지 그 유용성으로 인해 많은 도움이되었습니다! • 서버 측 MVC 는 거의 항상 최선의 방법입니다. • MVC는 3 개의 개별 계층이 아니며 단일 프레젠테이션 계층입니다. 실제로 이런 식으로 생각한 적이 없지만 절대적으로 정확합니다.
Scott Rippey

아주 좋은 대답, 분명히 내가 300 명을 대가로 찾던 것. 토론토 지역에 있다면 음료가 제공됩니다. :)

btw 나는 항상 N 계층이 물리적 위치에 관계없이 Pres / Bus / Data로 간주했습니다. 그렇기 때문에 MVC는 기본적으로 3을 결합하기 때문에 아키텍처를 거의 제거한다고 말했습니다.

ViewModel, per-view, 접근법에 대해 경고합니다. 나는 최근에 DTO에서 ViewModel에 대한 추상화가 없기를 바라는 상황에 부딪쳤다. 참조 : stackoverflow.com/q/7181980/109456

일반적으로 jQuery를보고 싶지 않고 대신 서버 측 개발자가 JQ 또는 DOM API를 사용하여 비즈니스를 수행하는 인터페이스를 사용하여 객체를 작성하는 것을 좋아하지 않습니다. 또한 Django의 URLConfig 개념을 정말 좋아하며 페이지에서 구현할 객체를 설정하는 데 도움이된다는 것을 알았습니다. 나는 MV가 무엇인지 모른다? 도서관은 나를 위해해야합니다. 그들은 문제에 완벽하게 맞지 않으며 IMO와 DOM + 이벤트 위임은 특정 구조에 지나치게 묶이지 않고 페이지를 처리하는 데 필요한 모든 모델입니다.
Erik Reppen 2016 년

6

나는 완전한 답변을 쓰지 않겠지 만 몇 가지 팁을 공유하고 싶습니다.

내 팁 :

1. 프로젝트 구조
기본 MVC 구조가 나에게 좋지 않다는 것을 알았습니다. 나는 일반적으로 같은 엔티티 (생각, 제품, 주문, 고객)의 컨트롤러, 뷰 및 모델에서 동시에 작업합니다. 따라서 파일은 동일한 폴더에 있지만 네임 스페이스가 다릅니다.

2. 데이터
Linq-to-SQL 또는 EF를 사용하는 경우 나중에 후회하게됩니다.
PetaPoco를 사용하여 매핑 고통없이 레코드를 검색하고 업데이트 할 수 있지만 성능 악몽없이 작업을 수행하는 새로운 방법을 배우지 않고도 SQL을 실행할 수 있습니다.

PetaPoco 속성으로 초기 POCO 클래스를 생성하는 코드 생성기가 있고 일부 필드가 추가되거나 제거 될 때 클래스를 변경합니다.

PetaPoco 는 동적 및 표준 클래스와 함께 작동하므로 타협하지 않습니다 (Massive는 모두 동적이며 Dapper는 모든 표준 클래스입니다)

또한 내장 SqlBuilder를 사용하여 엔터티에 대한 모든 표준 조인을 포함 하는 마스터 SQL을 생성 하지만 WHERE는 없으므로 하나의 엔터티 또는 목록을 검색하기 위해 동일한 SQL을 재사용합니다.

3. Jquery 일반적인 jQuery 호출 (HTML 요소 내부에 일부 데이터 채우기)을 사용하여 UI의 일부를 표준화 할 수 있습니다.

예를 들어, 삭제를 위해 이것을 가지고 있습니다.

var deleteLinkObj;
// delete Link
$('.jbtn-borrar').click(function () {
    deleteLinkObj = $(this);  //for future use
    $('#delete-dialog').dialog('open');
    return false; // prevents the default behaviour
});
$('#delete-dialog').dialog({
    autoOpen: false, width: 400, resizable: false, modal: true, //Dialog options
    buttons: {
        "Borrar": function () {
            $.post(deleteLinkObj[0].href, function (data) {  //Post to action
                if (data == 'OK') {
                    deleteLinkObj.closest("tr").hide('fast'); //Hide Row
                }
                else {
                    alert(data);
                }
            });
            $(this).dialog("close");
        },
        "Cancelar": function () {
            $(this).dialog("close");
        }
    }
});

클래스 jbtn-borrar를 하이퍼 링크 에 추가하면 대화 상자가 표시되고 레코드를 삭제하고tr

그러나 너무 생각하지 마십시오. 모든보기에서 작은 터치로 앱이 빛을 발합니다.

클라이언트 MVC 대 서버 MVC
서버 MVC. 초기 렌더링에 사용할 수있는 부분 뷰를 활용하고 동일한 뷰를 사용하여 Ajax로 일부 부품을 새로 고칩니다. 이 훌륭한 기사를보십시오

복잡한 쿼리를 처리하는 방법 (보고서라고 함)
Report 매개 변수를 속성으로 사용하는 클래스 (MVC 자동 매핑을 사용하기에 적합 함)와 Generate쿼리를 실행하고 사용자 지정 클래스 목록을 채우는 메서드를 사용합니다 ( ViewModel에 맞는 클래스가 없음)
이 클래스를 뷰의 모델로 사용하고 생성 된 목록으로 테이블을 채울 수 있습니다.

Microsoft의 Project Silk
Overarchitected. 반대 방향으로 최대한 빨리 달리십시오.


웃긴, Project Silk를 읽을 때이 잔소리가 계속 들리고 나는 그것을 배치 할 수 없었습니다.

3

1. 프로젝트 구조

내 솔루션에 2 개의 프로젝트 파일이 있습니다

1) 서비스 / 비즈니스 계층 모든 비즈니스 로직과 DB 액세스 코드 및 POCO를이 별도의 프로젝트에 배치합니다. ORM이 이미 DB 계층을 추상화 할 때 ORM을 사용하는 경우 데이터 액세스 계층이 필요하지 않습니다.

2) UI 레이어에는 모든 뷰, 컨트롤러, 모델, 스크립트, CSS가 포함됩니다.

컨트롤러, 뷰, 스크립트 및 CSS가 모두 유사한 폴더 구조를 사용하도록하려고합니다. 또한 가능한 한 URL 경로와 일치하도록 파일을 구성하십시오. 사용자 지정 라우팅을 작성하지 않아도됩니다.

DisplayTemplates, EditorTemplates, Partial views 및 Shared 폴더를 가능한 많이 사용하십시오.

그런 다음 모든 스크립트를 동일한 영역, c # 파일의 컨트롤러와 일치하도록 구성합니다. 그래서 루트에 common.js 파일을 페이지 당 js 파일과 각 영역에 대한 common.js 파일을 갖습니다.

내가 일반적으로 2 + n을 가진 CSS 파일 (여기서 n은 영역 수) 첫 번째 CSS 파일은 빠른 페이지 로딩 시간 (비즈니스 / 기업 환경에는 그렇게 중요하지 않음)을 돕기 위해 방문 페이지 전용 CSS입니다. 다른 모든 페이지에 대한 모든 스타일을 가진 common.css입니다. 그런 다음 각 영역에 대한 또 다른 common.css 파일 (예 : 모든 관리 페이지에 대해 CSS가있는 AdminArea.css 파일)

2. 데이터 액세스

Entity Framework를 사용하는 경우 POCOS와 잘 작동하고 유지 관리 할 모델이 없으므로 CodeFirst를 사용합니다. nHibernate는 훨씬 강력하지만 스텝 러 학습 곡선이 있습니다. DB 결과 페이징의 경우 재사용 가능한 util c # 클래스와 patial view가 있으며 모든 뷰에 사용합니다.

복잡한 쿼리 및 보고서 생성을 위해 저장 프로 시저를 사용합니다. LINQ의 작성 및 유지 관리가 훨씬 쉬우 며 더 많은 기능을 제공합니다. SSRS와 같은 다른 서비스에서도 재사용 할 수 있습니다. automapper를 사용하여 반환 된 데이터 세트를 동일한 POCO entiry 프레임 워크에서 사용하는 것과 동일한 것으로 다시 변환합니다.

3. 클라이언트 측 코드 구성 및 UI 렌더링

Eduardo Molteni 답변에는 좋은 예제 코드가 있습니다. 또한 나는 훌륭한 템플릿과 바인딩이 모두 있기 때문에 knockoutjs를 사용하는 것이 좋습니다. 많은 AJAX 호출에 JSON을 사용하면 UI 객체를 JS 객체에 자동 매핑하는 것이 시간을 절약하는 데 큰 도움이됩니다.

일반적인 질문들

복잡한 쿼리는 저장된 proc에 있어야합니다. (emeraldcode.com 의견 참조)

이 MVC를 사용하여 N 계층 아키텍처를 계속 유지합니다.


1

최근에 나열된 세 가지 기술을 사용하려는 경우 먼저 Orchard CMS 채택을 가정하여 시작해야한다고 생각했습니다 . 나는 이것이 귀하의 중앙 요구 사항에 대한 가장 좋은 대답이라고 생각합니다.

확장 성 및 풍부하고 빠르고 깨끗한 UI를 생성하는 기능을 유지하면서 코드와 논리를 구성하는 최적의 전략은 무엇입니까?

Ochard 시나리오에서는 구성 메커니즘을 통해 해결할 수없는 모든 항목을 무료 온라인 모듈 추가 또는 자체 모듈 작성 (물론 C #, 면도기 등)을 통해 처리 할 수 ​​있습니다. 코드 구성은 오차드의 강점입니다.

데이터 액세스에 관해서는, 마이크로 ORM이 최선의 방법이라고 생각하는 풀 보어 ORM에 충분한 장단점이 있습니다. Massive 또는 Dapper를 사용해보십시오 . 둘 다 Hanselminutes 에 소개되었습니다 . 나는 이것을 말함으로써 두 가지를 요약 할 것이다. SQL의 추상화는 프로젝트가 확장됨에 따라 거의 항상 분해된다. 결국 DB 액세스를위한 최상의 솔루션은 SQL (sarcasm의 비트이지만 사실)이라는이 추상화입니다. micro-ORM이 그 일을하게하면 금이 있습니다.

오차드를 마이크로 ORM과 함께 사용하면 버터처럼 강철을 슬라이스 할 수 있습니다. Er은 신속하게 개발하고 확장하며 핸드 오프를받는 팀이 쉽게 유지 관리 할 수있는 코드를 가질 수 있음을 의미합니다.


0

이 질문을 어떻게 놓쳤는 지 확실하지 않지만 2 년 후 2 센트를 추가하겠습니다.

클라이언트 MVC 대 서버 MVC? 내 프로젝트는 이미 서버 측 MVC 구조이므로 Backbone.js가 제공하는 것과 같은 클라이언트 MVC가 여전히 필요합니까?

MVC와 MV? 클라이언트 측으로 밀려 나기 전에도 기본적으로 마케팅 용어로 발전하여 실제로 데이터가 다른 아이디어와 분리 될 것이라고 약속하지만 실제로는 큰 아이디어이지만 DIY로는 어렵지 않습니다. 어떤 접근 방식을 사용하든 프리젠 테이션 또는 상호 작용 가능성에 영향을주는 HTML을 변경하기 직전 또는 그 중간에 비즈니스가 데이터를 사용하여 원하는 것을 정렬하는 것이 가장 끔찍한 장소입니다.

"보기 논리"에는 특별한 것이 없습니다. 모든 논리에 동일한 원칙이 적용되어야합니다. 즉, 지금 이전에 훨씬 더 의미가있는 일을하지 마십시오. 일부 데이터를 전달하거나 새로운 프로세스를 시작하기 전에 모든 오리가 한 줄에 있으면 이전 단계는 시스템에서 비슷한 작업을 수행하는 다른 사람에게 훨씬 더 재사용 될 가능성이 높습니다.

각 오브젝트 (예 : OrderHeader.js)에 대해 Javascript 파일을 작성한 후 빌드 중에 축소 / 병합해야합니까? 아니면 OrderHeader, OrderDetails, Reports 등에 대한 로직이있는 Order.js가 있어야합니까?

정말 당신에게 달려 있지만 한 파일, 한 클래스의 물건에서 벗어나려고합니다. 나는 그것이 왜 추상 파일과 인터페이스를 찾아야하고 구현하는 파일 등을 찾아야하는 이유를 이해하지 못했습니다. 더 넓은 관심사로 분류하십시오. Ctrl + F는 조금 오래 걸리면 사용하기가 어렵지 않습니다.

즉, 웹에서 파일을 작게 만들기 위해 JS를 다시 결합해서는 안됩니다. 브라우저는 JS를 캐시하므로 오래된 JS를 새 파일에 붙여서 동일한 JavaScript를 다시로드해야합니다. 엄청난 양의 JavaScript를 사용하지 않으면 페이지에 모든 JS가 없어야 할 유일한 시간은 특정 부분에 겹침 / 회색 영역이없는 사이트의 한 섹션에 매우 특정한 대량의 JS가 필요한 경우입니다. 페이지.

그리고 FFS는 웹에서 JavaScript를 사용하여 종속성 관리를 소홀히하지 않습니다. 중소형 웹 사이트의 Require.js를 사용하면 베이비 씰을 클럽으로 만들 수 있습니다. 타사 라이브러리를 맨 위 블록에 붙입니다. 두 번째 블록의 사내 라이브러리. 그런 다음 세 번째 bock에서 구현 코드 (사내 라이브러리 코드 (즉, 매우 간결하고 명확하고 이해하기 쉬운)의 10 분의 1이되어서는 안 됨)입니다.

복잡한 쿼리는 어떻게 처리해야합니까? 현재 내 주요 이론은 / Reports / Orders-By-Date / 또는 그 라인을 따르는 것입니다. 사용자 정의 데이터 세트 (또는 ViewModel)를 Razor View로 렌더링하는 사용자 정의 SQL 쿼리를 사용합니다. 그러나 페이징, 정렬 등은 어떻습니까? 클라이언트 또는 서버 측에서 수행하는 것이 더 낫습니까? (더 큰 데이터 세트-2 ~ 3 초 SQL 쿼리를 가정) Microsoft의 Project Silk를 읽었습니다. 이것이 좋은 방법입니까? Backbone.js 또는 다른 것과 어떻게 비교됩니까?

솔직히 말해서 고객에게 악영향을 미치지 않는 것이 무엇이든 말하고 싶습니다. 웹 페이지는 최신 기술에 매우 빠르게로드됩니다. Ajax로 구현하는 것이 많은 어려움을 겪고 있다면 그렇게하지 마십시오. 가장 잘 아는 내용으로 이동 한 다음 나중에 더 좋아지고 페이징에 대해 어떻게 마음에 드는지 알 수 있습니다. 처음부터 새로운 복잡한 앱을 구축하는 경우 필수부터 시작하여 나중에 깔끔하게 누르십시오.

나는 N 계층 아키텍처에 익숙합니다.이 개념이 다소 창밖으로 던져 지는가? MVC는 과거에 프론트 엔드 또는 최상위 계층에 있었던 미니 N 계층 섹션과 같습니다.

그것은 실제로 어떤 MV에 대한 환상의 아이디어에 달려 있습니까? 입니다. IMO는 소우주 물이 잘 작동하는 경향이 있습니다. 내부적으로 데이터, 통신 및보기 관련 항목을 분리하는 위젯 클래스가 효과적입니다. 클라이언트 측 웹에서 중요한 것은 IMO는 재 조립으로 사물을 이해하고 재사용하고 수정하는 것을 어렵게하는 작은 문제로 불필요하게 분할하지 않고 우려를 분리하는 균형을 유지하는 것입니다. 기본 "duh"OOP는 여기서 훌륭하게 작동합니다. 복잡한 프로세스를 원하지 않습니다. 당신은 분명히 움직일 수 있고 일을하도록 지시 할 수있는 것들을 원합니다. 그 앞면에 대한 몇 가지 팁이 있습니다.

  • KOO는 (OOP) 인터페이스 DOM 또는 jQuery 또는 핀치 타격 서버 측 개발자가 구현 코드에서 상당히 빨리 알아낼 수없는 것을보고 싶지 않습니다. 그 사람이 알아야 할 것은 div 컨테이너에서 어떤 클래스를 때리는 지와 주어진 페이지에서 상당히 일반적인 UI 세트를 만들기 위해 뒤집는 스위치입니다. 테마에 대한 변형은 document.get <anything>을 보거나 CSS의 가장 기초적인 것 이상의 것을 이해하기 전에 문서화되고 주석 처리 된 옵션 객체를 전달하여 수행해야합니다.

  • 좋아 어떻게 그렇게합니까? 글쎄, 우리는 이미 모델을 가지고 있습니다. 이것을 DOM이라고합니다. 그리고 우리는 이벤트 위임이 있습니다. 이벤트 버블 링을 무차별 적으로 종료하지 않으면 (하지 마십시오-유용하기 때문에 거기에 있습니다) 원하는 경우 몸에서 모든 싱글을 선택할 수 있습니다. 그런 다음 전달 된 이벤트 객체의 대상 속성을 검사하고 누가 '무엇을'했는지 결정합니다. HTML 문서를 현명하게 구성하는 경우이를 위임 모델로 사용하지 않을 이유가 없습니다. 행동과 내용 구조는 자연스럽게 연결되어 있습니다. 두 식별자가 겹치는 식별자는 괜찮습니다.

  • 데이터 바인딩 비용을 지불 하지 마십시오. 그리고 "지불"이란 "실제로 DIY하기 어려운 기적의 이점을 얻기 위해 라이브러리를 코드베이스에 두어 작업을하도록 요구합니다." JQ의 이벤트 시스템은 매우 쉽습니다.

예제 시간 :

function PoliticianData(){ //a constructor

    var
        that = this, //I hate 'that' but example so convention

        flavorsOfLie = {

            lies: "Oh Prism? Psh... no we're all good. There's a guy keeping an eye on that.",

            damnedLies: "50% of the people chose to not give a damn when asked whether it was better to let the terrorists win or not give a damn."

        }
    ;//end instance vars

    this.updateLies = function( lieType, newData ){
        flavorsOfLie[lieType] = newData;
        $(that).trigger({type:'update', lieType:lieType, newData: newData });
    }

    //so everytime you use the updateLies method, we can have a listener respond
    //and pass the data
}

var filthyLies = new PoliticianData();

$(filthyLies).on('update', function(e){
    stickNewDataInHTMLWithSomeFuncDefinedElsewhere(e.lieType, e.newData);
} );

filthyLies.update('damnedLies','50% of the people said they didn\'t give a damn');
//oh look, WaPo's front page just changed!
  • 웹을 숨기지 마십시오 서버 측 및 응용 프로그램 개발자가 클라이언트 쪽을 쉽게 만들 수 있도록하는 모든 초기 시도의 주요 원인은이 중요한 점에 달려 있습니다. HTTP 요청은 결코 복잡하지 않으며 결코 복잡하지 않습니다. 그들은 이해하기 쉽도록 18 개의 @@ $$ ing 레이어를 혼란스럽게 만들었습니다. 마찬가지로, 클라이언트 측에 대해 알아야 할 것이 많지만 HTML과 DOM에서 큰 거대한 모델을 두드려서 상호 작용하는 HTML에서 숨길 이유가 없습니다. 이미 큰 거대한 모델이며 매우 잘 작동합니다. 좀 더 관리하기 쉽게 만드는 데 필요한 것은 OOP 관행과 JS 및 DOM 지식입니다.

  • 융통성

EXTjs <==== 유연성 스케일 ====> jQuery (필요한 플러그인은 아님)

DIY를 빠르게 할 수있는 도구 인 IMO는 항상 더 나은 선택입니다. 머리 위의 사람이 세부 사항에 대해 특히 까다 롭지 않고 도움을 주어야 할 일에 대한 통제를 원하지 않는 경우에만 올바른 도구를 선택할 수 있습니다. 실제로 HTML의 유효성을 검사하여 플러그인이 동일한 디스플레이 특성을 가진 다른 종류의 요소를 몰래 들어 가지 않도록하는 플러그인을 보았습니다. 왜? 나는 이론 만 가지고있다. 나는 의도하지 않은 방식으로 자신의 물건을 사용하는 누군가의 아이디어를 정말로 싫어하는 완성 주의자들에게 달려 있다고 생각합니다. 그리고 그것은 항상 누군가가 당신이 UI에서하고 싶어하는 것입니다.

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