web-dev-qa-db-ja.com

Javascriptのモジュール性、サーバーベースのMVC、ビジネスの現実

私はこれが非常に幅広い質問であることを理解していますが、この問題のさまざまな側面を個別に扱っており、すべての概念と技術をまとめるのに苦労しています。

回答に次のテクノロジーが含まれるように指定します。

  • C#
  • MVC 3 w/Razor
  • JavaScriptとjQuery

それらを超えたもの( Backbone.jsEntity Framework など)は、次の質問への回答に役立つ場合、提案として歓迎されます。

上記のテクノロジーを使用して、スケーラビリティとリッチで高速でクリーンなUIを作成する機能を維持しながらコードとロジックを整理するための最適戦略とは何ですか?

理想的には、ビジネス/企業環境に展開されるソリューションに焦点を当てる必要があります。ただし、上記のテクノロジーリストは変更されませんので、「xxxの代わりにxxxを使用する必要があります。 yyy現在使用しています。

背景

私は毎日jQueryを使用しており、ASP.NETのMVCを採用しており、長い間C#を使用しています。そのため、これらのテクノロジーに関する中級から上級の知識を前提としたソリューションを提示できます。

質問を小さな部分に整理して、応答を簡単にします。

1。プロジェクト構造

ASP.NET MVC(Visual Studio 2010で)を使用していることを考えると、このタイプのメインレイアウトをある程度受け入れられるディレクトリ構造ソリューションが欲しいアプリケーションの。 Brunch のようなものだと思いますが、各フォルダに含まれる内容と、アプリの他の領域との連携方法についてもう少し詳しく説明します。

2。データアクセス

APIタイプの構造を使用して、データアクセスをできる限りモジュール化したいと思います。たくさんのPOCOオブジェクト(UserUserGroupCustomerOrderHeaderOrderDetailsなど)を想定できますが、データを多用する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の必要性はまだありますか?
  • 各オブジェクト(OrderHeader.jsなど)ごとにJavaScriptファイルを作成し、ビルド中に縮小/マージする必要がありますか?または、Order.jsなどのロジックを持つOrderHeader, OrderDetails, Reportsだけが必要ですか?
  • 複雑なクエリはどのように処理する必要がありますか?現在、私の主要な理論は/Reports/Orders-By-Date/またはそれらの線に沿った何かであり、カスタムデータセット(またはViewModel)をRazorビューにレンダリングするカスタムSQLクエリを使用しています。しかし、ページング、ソートなどはどうですか?これはクライアント側またはサーバー側で行う方が良いですか? (より大きなデータセットを想定-2〜3秒のSQLクエリ)
  • Microsoftの Project Silk を読みました。これは良い方法ですか? Backbone.jsや他のものと比較してどうですか?
  • 私はN層アーキテクチャーに非常に慣れていますが、これらの概念は多少それをウィンドウの外に捨てますか? MVCは、これまでフロントエンドまたはトップティアであったはずのミニNティアセクションの束のようなものです。

繰り返しになりますが、より具体的な-/より良い回答になります。 私は多くの高レベルのドキュメントと例を読みました、私はそれをよりよく理解しようとしています実世界の例

32
Terry

TerryR私の友人、あなたと私は飲み物を飲むべきです。同様の問題がいくつかあります。

1。プロジェクトの構造:MVCアプリのフォルダー構造には、何かが残されているというエドゥアルドに同意します。標準のControllers、Models、およびViewsフォルダーがあります。ただし、Viewsフォルダーは、コントローラーごとに異なるフォルダーと共有フォルダーに分割されます。また、各Views/ControllerNameまたはViews/Sharedは、EditorTemplatesとDisplayTemplatesに分類できます。ただし、Modelsフォルダーの編成方法を決定できます(サブフォルダーと追加の名前空間宣言の有無にかかわらず実行できます)。

エリア、コントローラー、モデル、ビューの各フォルダー構造を複製するエリアの使用を禁じます。

/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インテリセンスを取得することでしたが、/ scriptsの配置に関係なくR#からJSインテリセンスを取得するようになったので、それから逸脱し、フォルダーごとにスクリプトを分割して、より適切に整理できると思います。 ReSharperを使用していますか?純金IMOです。

リファクタリングで大いに役立つもう1つの小さな金は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サービスを検討しましたか?または、別のデータベースで実行していますか?申し訳ありませんが、正確には何を求めているのかわかりません。 EF + LINQを使用しますが、ドメインクラスでレポートを生成する方法に関する特定の知識も使用します。したがって、コントローラーコールリポジトリを直接持つ代わりに、コントローラーコールドメインサービスコールリポジトリがあります。アドホックレポートの場合、SQLレポートサービスを使用しますが、これも完璧ではありませんが、ユーザーはデータを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" />

現時点ではajax成功関数を無視してください(これについては後で詳しく説明します)。一部のアクションについては、1つのスクリプトで済ますことができます。

$('.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();
                    }
                }
            }
        });
    }
});

上記のコードは確認を処理し、スピナーを表示し、待機メッセージを表示し、ajax呼び出しの完了後にスピナー/待機メッセージを非表示にします。目立たないライブラリのように、data- *属性を使用して動作を設定します。

一般的な質問

-クライアントMVC対サーバーMVC?コントローラがJSONを返しているように見えるため、成功関数で実行したアクションをライブラリ化しようとしませんでした。コントローラーがJSONを返す場合は、KnockoutJSを確認することをお勧めします。 ノックアウトJSバージョン2.0が本日リリースされました 。それはあなたのJSONに直接接続できるので、観察可能なクリックがデータをあなたのJavaScriptテンプレートに自動的にバインドすることができます。一方、ajaxアクションメソッドがJSONではなくHTMLを返すことを気にしない場合、それらはLIの子を持つすでに構築されたULを返すことができ、data-myapp-response =を使用して要素に追加できます。 "結果"。成功関数は次のようになります。

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

これに対する私の最良の答えを要約すると、アクションメソッドからJSONを返す必要がある場合、サーバー側のビューをスキップしているので、これは実際にはサーバーMVCではなく、単にMCです。 HTMLを含むPartialViewResultをajax呼び出しに返す場合、これはサーバーMVCです。したがって、アプリがajax呼び出しでJSONデータを返す必要がある場合は、KnockoutJSなどのクライアントMVVMを使用します。

どちらにしても、レイアウト(htmlタグ)と動作(非同期データロード)が混在するため、投稿したJSは好きではありません。部分的なhtmlビューを備えたサーバーMVCまたは純粋なJSONビューモデルデータを備えたクライアントMVVMを選択すると、この問題は解決しますが、JavaScriptでDOM/HTMLを手動で作成すると、問題の分離に違反します。

-JavaScriptファイルの作成どうやら 縮小機能は.NET 4.5で提供されます 。目立たない経路をたどる場合、JSのすべてを1つのスクリプトファイルにロードすることを妨げるものはありません。エンティティタイプごとに異なるJSファイルを作成する場合は注意が必要です。JSファイルが急増することになります。スクリプトファイルが読み込まれると、ブラウザーは将来の要求のためにそれをキャッシュする必要があります。

-複雑なクエリ私は、ページネーション、ソートなどの機能を複雑であるとは考えていません。私の好みは、URLとサーバー側ロジックでこれを処理し、dbクエリを必要に応じて制限することです。ただし、Azureにデプロイされているため、クエリの最適化は重要です。例えば: /widgets/show-{pageSize}-per-page/page-{pageNumber}/sort-by-{sortColumn}-{sortDirection}/{keyword}。 EFとLINQ to Entitiesは、.Take()、. Skip()、. OrderBy()、. OrderByDescending()などのメソッドを使用してページ分割と並べ替えを処理できるため、dbのトリップ中に必要なものを取得できます。まだclientlibの必要性を見つけていないので、正直に言ってそれらについてはあまり知りません。それに関するより多くのアドバイスについては他の答えを見てください。

-Project silkこれは聞いたことがないので、チェックする必要があります。私はスティーブサンダーソン、彼の本、彼のBeginCollectionItem HtmlHelper、そして彼のブログの大ファンです。とはいえ、私はKnockoutJSの運用経験はありません。私はそのチュートリアルをチェックアウトしましたが、少なくともバージョン2.0になるまではコミットしないようにしています。先ほど述べたように、KnockoutJS 2.0がリリースされたばかりです。

-N層層によって異なる物理マシンを意味する場合、いいえ、何もウィンドウから出ていくとは思わない通常3層とは、3台のマシンがあることを意味します。そのため、ユーザーのマシンで実行されるファットクライアントをプレゼンテーション層として使用する場合があります。ファットクライアントは、アプリケーションサーバーで実行され、XMLまたは何でもファットクライアントに返すサービス層にアクセスする場合があります。また、サービス層は3番目のマシンのSQLサーバーからデータを取得する場合があります。

MVCは1層の1層です。コントローラ、モデル、およびビューはすべて、物理アーキテクチャの1層であるプレゼンテーション層の一部です。 MVCは、Model-View-Controllerパターンを実装します。このパターンには、追加のレイヤーが表示される場合があります。ただし、これらの3つの側面を層または層として考えないようにしてください。これら3つすべてをプレゼンテーション層の問題と考えてください。

pres/bus/dataコメント後に更新

さて、あなたは層と層を交換可能に使用しています。私は通常、「レイヤー」という用語を論理/プロジェクト/アセンブリの分割に使用し、層を物理ネットワークの分離に使用します。混乱させて申し訳ありません。

エンティティデータモデルにMVCの「モデル」を使用したり、ビジネスロジックにコントローラーを使用したりしないでくださいと言う人がMVCキャンプにかなりいます。理想的には、モデルはビュー固有のViewModelである必要があります。 Automapperのようなものを使用して、ドメインモデルからエンティティを取得し、ビューで使用するために特別にスカルプトされたViewModelsにエンティティをDTOします。

ビジネスルールもドメインの一部である必要があり、ドメインサービス/ファクトリパターン/ MVCプレゼンテーションレイヤーではなく、ドメインレイヤーで適切なものを使用してそれらを実装できます。コントローラは、モデルほど馬鹿ではありませんが、馬鹿である必要があり、ビジネスの知識を必要とするあらゆるものに対してドメインに責任を与える必要があります。コントローラーはHTTP要求と応答のフローを管理しますが、実際のビジネス価値を持つものはすべてコントローラーの賃金水準を超えている必要があります。

そのため、MVCをプレゼンテーションレイヤーとして使用して、レイヤードアーキテクチャを維持できます。設計方法に応じて、アプリケーション層、サービス層、またはドメイン層のクライアントです。ただし、最終的には、エンティティモデルはMVCのモデルではなく、ドメインの一部である必要があります。

10
danludwig

完全な回答を書くつもりはありませんが、いくつかのヒントを共有したいと思います。

私のヒント:

1。プロジェクト構造
デフォルトのMVC構造が適切でないことがわかりました。私は通常、同じエンティティ(製品、注文、顧客など)のコントローラー、ビュー、モデルで同時に作業します。そのため、ファイルは同じフォルダー内にありますが、名前空間が異なります。

2。データ
Linq-to-SQLまたはEFを使用する場合、後で後悔します。
私は、マッピングの苦痛なしにSQLを実行してレコードを更新できるPetaPocoを使用していますが、新しい方法を習得せず、パフォーマンスの悪夢もありません。

PetaPoco属性を使用して最初のPOCOクラスを作成し、フィールドが追加または削除されたときにクラスを変更するコードジェネレーターがあります。

PetaPoco は動的クラスと標準クラスで機能するため、妥協する必要はありません(Massiveはすべて動的で、Dapperはすべての標準クラスです)。

また、組み込みのSqlBuilderを使用して、エンティティのすべての標準結合を含むmasterSQLを生成しますが、WHEREがないため、同じSQLを再利用して1つのエンティティまたはリスト。

3。 Jquery一般的なjQuery呼び出しを使用して、UIの一部を標準化できます(HTML要素内にデータを詰め込みます)。

たとえば、私はこれを削除するために持っています。

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で一部を更新します。 この優れた記事を参照

複雑なクエリの処理方法(これをレポートと呼びましょう)
私は、レポートパラメーターをプロパティとして持つクラス(MVC自動マッピングを使用するのに便利)と、クエリを実行してカスタムクラスのリストに入力するGenerateメソッドを使用します(そうでない場合) ViewModelに適合するクラスを持っている)
このクラスをビューのモデルとして使用し、生成されたリストをテーブルに入力できます。

MicrosoftのProject Silk
オーバーアーキテクチャー。反対方向にできるだけ速く走る。

6
Eduardo Molteni

1。プロジェクト構造

私のソリューションには2つのプロジェクトファイルがあります

1)サービス/ビジネス層すべてのビジネスロジック、DBアクセスコード、POCOをこの個別のプロジェクトに配置します。 ORMがすでにDBレイヤーを抽象化しているため、ORMを使用している場合は、データアクセスレイヤーは必要ありません。

2)UIレイヤーにはすべてのビュー、コントローラー、モデル、スクリプト、CSSが含まれます

私はコントローラー、ビュー、スクリプト、CSSのすべてが同様のフォルダー構造を使用するようにしています。また、URLパスにできるだけ一致するようにファイルを構造化します。カスタムルーティングを書く必要を避けるため。

DisplayTemplates、EditorTemplates、Partialビュー、およびSharedフォルダをできるだけ使用します。

次に、すべてのスクリプトを構造化して、c#ファイルの同じエリア、コントローラーに一致させます。そのため、ルートにcommon.jsファイル、ページごとにjsファイル、各エリアにcommon.jsファイルを配置します。

通常、2 + nのCSSファイル(nはエリアの数)1番目のCSSファイルは、ランディングページのCSSであり、ページの読み込み時間の短縮に役立ちます(おそらく、ビジネス/企業環境ではそれほど重要ではありません)2番目のCSSファイル他のすべてのページのすべてのスタイルを持つcommon.cssです。次に、各領域の別のcommon.cssファイル、たとえば、すべての管理ページのCSSを持つAdminArea.cssファイル。

2。データアクセス

Entity Frameworkを使用する場合、POCOSで非常にうまく機能し、維持するモデルがないため、CodeFirstを使用します。 nHibernateははるかに強力ですが、学習曲線が段階的です。 DB結果のページングでは、すべてのビューに使用する再利用可能なutil c#クラスと空間ビューがあります。

複雑なクエリとレポートの生成には、ストアドプロシージャを使用します。記述や保守がはるかに簡単で、LINQのパワーが向上します。 SSRSなどの他のサービスでも再利用できます。 automapperを使用して、返されたデータセットを変換して、entryフレームワークが使用するのと同じPOCOに戻します。

。クライアント側のコード編成とUIレンダリング

Eduardo Molteniの回答には良いサンプルコードがあります。また、テンプレートとバインディングの両方が優れているため、knockoutjsの使用をお勧めします。すべてのAJAX呼び出しにJSONを使用する場合、私が頻繁に使用するので、UIをJSオブジェクトに自動マップすることで時間を大幅に節約できます。

一般的な質問

複雑なクエリは、ストアドプロシージャに存在する必要があります。 (emeraldcode.comコメントを参照)

このMVCを使用して、N層アーキテクチャーを維持します。

3
Daveo

私は最近、あなたがリストした3つのテクノロジーを使用する予定がある場合、まず Orchard CMS の採用を想定することから始めるべきだと信じるようになりました。私はそれがあなたの中心的な要件に対する最良の単一の答えであると信じています:

スケーラビリティと、リッチで高速でクリーンなUIを作成する機能を維持しながら、コードとロジックを整理するための最適な戦略は何ですか?

Ochardのシナリオでは、無料のオンラインモジュールを追加するか、独自のモジュール(もちろん、C#、かみそりなど)を作成することで処理できる構成メカニズムでは対処できないものがあります。コード編成はオーチャードの強みです。

データアクセスに関しては、フルボアORMには十分な長所と短所があり、マイクロORMが最善の方法であると私は思います。 Massive または Dapper を試してください。どちらも Hanselminutes で紹介されました。この2つを要約すると、次のようになります。SQLからの抽象化は、プロジェクトがスケールアップするにつれて、ほぼ必ず失敗します。結局、DBアクセスの最良のソリューションは、SQLと呼ばれるこの抽象化です(皮肉のビットですが、本当です)。 micro-ORMでこれを機能させると、ゴールドが手に入ります。

オーチャードをマイクロORMと組み合わせれば、バターのように鋼をスライスできます。 Er、つまり、迅速に開発し、スケーリングし、ハンドオフを受けたチームが容易に保守できるコードを作成できることを意味します。

1
Brent Arias

どのようにしてこの質問を逃したかわかりませんが、2年後に2セントを追加します。

クライアントMVC対サーバーMVC?私のプロジェクトはすでにサーバー側のMVC構造なので、Backbone.jsが提供するようなクライアントMVCの必要性はまだありますか?

MVCとMV?それがクライアント側にプッシュされる前であっても、基本的にマーケティング用語に進化しており、データが他の要素から分離されることを約束しているだけです。どのようなアプローチをとっても、プレゼンテーションやインタラクションの可能性に影響を与えるHTMLの変更を行う直前または途中で、ビジネスがデータに対して何をしたいのかを整理するのに最も恐ろしい場所です。

「ビューロジック」について特別なことは何もありません。同じ原則がすべてのロジックに適用されます。そして、それは今までに行う方がずっと意味のあることを今は行わないでください。データを渡す前、または新しいプロセスを開始する前に、すべてのアヒルが並んでいるとき、前のフェーズは、システム内の他の何かが同様のことを行う場合にはるかに再利用可能になる可能性があります。

オブジェクトごとに(OrderHeader.jsなどの)Javascriptファイルを作成し、ビルド中に縮小/マージする必要がありますか?または、OrderHeader、OrderDetails、Reportsなどのロジックを持つOrder.jsだけがありますか?

それは本当にあなた次第ですが、私は1つのファイル、1つのクラスのものから逃れるように努めます。抽象ファイルやインターフェース、実装ファイルなどを見つける必要があるなど、なぜそれが役に立ったのか、私には理解できません。 Ctrl + Fは、少し長くなると使いにくくなりません。

そうは言っても、Web上でファイルを小さくするためにJSを再結合しないでください。ブラウザはJSをキャッシュするので、古いJavaScriptを新しいファイルに貼り付けることで、同じJavaScriptのリロードを強制するだけです。驚異的な量のJavaScriptを除いて、ページにすべてのJSを表示すべきではない唯一のケースは、オーバーラップ/グレー領域のないサイトの1つのセクションに非常に固有である非常に大量のJavaScriptが、特定の場所で必要になることがないときです。ページ。

また、FFSは、Web上のJavaScriptによる依存関係管理に煩わされることはありません。中から低複雑度のWebサイトでRequire.jsを使用すると、赤ちゃんのアザラシを隠したくなります。上部のブロックにサードパーティのライブラリを貼り付けます。 2番目のブロックの社内ライブラリ。そして、その3番目のブロックの実装コード(社内のライブラリコード(つまり、非常に簡潔で明確で理解しやすいもの)の10分の1になることはありません)。

複雑なクエリはどのように処理する必要がありますか?現在、私の主要な理論は/ Reports/Orders-By-Date /またはそれらの線に沿った何かであり、カスタムデータセット(またはViewModel)をRazorビューにレンダリングするカスタムSQLクエリを使用しています。しかし、ページング、ソートなどはどうですか?これはクライアント側またはサーバー側で行う方が良いですか? (大きなデータセットを想定-2〜3秒のSQLクエリ)MicrosoftのProject Silkを読みました。これは良い方法ですか? Backbone.jsや他のものと比較してどうですか?

正直なところ、お客様にとって悪臭を放さない、もっと簡単なことは何でも言っておきます。最新のテクノロジーでは、Webページの読み込みがかなり速くなります。 Ajaxでの実装があなたにとって多くの苦痛であるならば、そうしないでください。自分が最もよく知っているものを使用してください。そうすれば、後でファンシーになり、ページングでそれがどのように好きかを確認できます。新しい複雑なアプリをゼロから構築する場合は、必須のものから始めて、後できちんと実行してください。

私はN層アーキテクチャーに非常に慣れていますが、これらの概念は多少それをウィンドウの外に捨てますか? MVCは、これまでフロントエンドまたはトップティアであったはずのミニNティアセクションの束のようなものです。

それは本当に誰がどのMVの空想のアイデアに依存するのですかです。 IMO、小宇宙のものは非常にうまく機能する傾向があります。データ、通信、およびビュー関連のものを内部的に分離するウィジェットのクラスは、うまく機能します。クライアント側のWebで重要なのは、IMOは、懸念事項を不必要に分離せずに、再構築によって物事を理解し、再利用および変更することが困難な小さな懸念事項に分割することなく、バランスを保つことです。基本的な "duh" OOPここでうまく機能します。複雑なプロセスは必要ありません。移動して何かを実行するように指示できる、明確に名前が付けられたものを必要とします。その前にいくつかのヒントがあります。

  • KISS that(OOP)interface DOMやjQueryやその他のピンチヒットのサーバー側の開発者が、実装コードですぐに理解できなかったのを見たくありません。その人が知っておく必要があるのは、divコンテナー上でどのクラスを叩くか、特定のページでかなり一般的なUIのセットをアクティブにするためにフリップするスイッチについてだけです。テーマのバリエーションは、document.get <anything>を見始めたり、CSSの最低限の基本を超えて何かを理解したりする前に、十分に文書化された/コメントの付いたオプションオブジェクトを渡すことによって実現する必要があります。

  • それで、どうやってそれを行うのですか?さて、すでにモデルがあります。これはDOMと呼ばれます。そして、イベントの委任があります。イベントのバブリングを無差別にシャットダウンしていない場合は(そうしないでください-便利なのでそこにあります)、必要に応じて、ボディからでもすべてのシングルを取得できます。次に、渡されたイベントオブジェクトのターゲットプロパティを調べて、「何をしたか」を判断します。 HTMLドキュメントを適切に構造化している場合委任モデルとして使用しない理由はありません。動作とコンテンツ構造は自然にリンクされます。 2つが重複する識別子を持つことは問題ありません。

  • データバインドにお金を払わないでくださいそして「支払う」とは、当然、「ライブラリをコードベースに平手打ちして、あなたが常に何かをしなければならないことを主張することで、奇跡的なメリットを得るために、実際に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!
  • Webを非表示にしないクライアント側をサーバー側に簡単にしようとするすべての初期の試みにおける吸血鬼の主な原因は、この重要な点にかかっています。 HTTPリクエストは複雑ではなく、決して複雑ではありません。理解しやすくするために、18の!@#$ ingレイヤーに各ステージのイベント名を混乱させる必要はありませんでした。同様に、クライアント側について多くのことを知っておく必要がありますが、巨大な巨大なモデルをその上で叩くことによってHTMLと対話するDOMから隠す理由はありません。それはすでに大きな巨大なモデルであり、非常にうまく機能します。少し管理しやすくするために必要なのは、いくつかの賢明なOOPプラクティスといくつかのJSおよびDOMの知識です。

  • お気に入りの柔軟性

EXTjs <==== flexibility scale ====> jQuery(必ずしもそのプラグインのどれでもない)

IMO、DIYを迅速に行えるツールは常に優れた選択肢です。あなたのためにすべてを行ったツールは、頭の上の誰もが細部に特にこだわっていない場合にのみ正しい選択です。 HTMLを検証して、まったく同じ表示特性を持つ別の種類の要素をこっそり入れないようにするプラグインを実際に見ました。どうして?私には理論しかない。それは、誰かが意図していない方法で自分のものを使用するという考えを本当に嫌う完成主義者に要約されていると私は思います。

0
Erik Reppen