web-dev-qa-db-ja.com

特定の種類の関数をMVC構造のどこに配置するか

MVCデザインパターンを使用したプログラミングの使用を開始したばかりですが、それを正しく理解しているかどうか、特定の場所に配置する必要があるかどうかを知りたいです。

だから私はすべてのファイルを3つのフォルダのうちの1つに置くべきだと理解しました(または単にコードを分離します):

モデル-データベースモデル。

Controllers-モデルに格納された情報をビューに移動する、またはその逆のロジック。

View-ユーザーに表示するロジック。

したがって、私の質問は、モデルの処理に役立つ関数がいくつかあるかどうかですが、モデル自体ではありません。どこに配置すればよいですか?

たとえば、次のモデルがあるとします:ユーザー、投稿、コメント。そして、「追加」という関数を作成し、そのモデルの「モデル名」と「プロパティ」という2つの引数を受け取り、関数は要求されたモデルを使用し、データベースに追加するために必要なすべての作業を行いません。

そして、あなたが私が見るべきだと思う良い構造パターンはありますか?

編集:受け取った回答が両方とも矛盾しているのを確認したので、ここにもっと良い例があります。

たとえば、記事、ブログ、ビデオなど、さまざまな種類の「エントリ」があるとします。すでに、それぞれのモデルと、それらのコメントとコメントとの間に適切な関係があるモデルがあります。

これらのエントリはすべて、共通の「基本構造」を共有しており、動的に作成できます。

そこで、これらのエントリの管理に役立つ関数を作成しました。この関数は、エントリの名前とデータベースに保存するプロパティを受け取り、その関数がそのデータを適切なモデルに送信します。

次に、関数を表す疑似コードを示します。

function add( modelName, properties ) {

    // Checking the inputs.

    // Checking if a model with that model name exists

    // Pass the properties to the right model

    // Try to save it to the database

    // Return errors/updates.
}

編集:すみません、多くの質問で更新しています。これは、内容を理解するために知っている最良の方法です:)

だから別の質問:ユーザー入力を検証するための適切な場所はどこですか?それはモデルに行くべきですか?

また、ユーザーが情報にアクセスする権限をどこで確認すればよいですか?

私が正しく理解している場合、ほとんどのロジックはモデルに含まれますか?

最後に、MVCのほとんどの用語をよく知らないので、できるだけ簡単に説明してください。

2
Samuel E.

モデルの処理に役立つ関数がいくつかあるが、モデル自体ではない場合、どこに配置すればよいですか?

これらがモデルのヘルパークラスである場合、モデルと一緒に配置する必要があります。また、モデルはデータベースモデルだけでなく、実際にはドメインモデルでもあることに注意してください。そこには、ビジネスエンティティだけでなく、ビジネスロジックとビジネスルールが存在します。

「追加」という関数を作成しました。そのモデルの「モデル名」と「プロパティ」という2つの引数を受け取り、関数は要求されたモデルを使用して、データベースに追加するために必要なすべての作業を行います。

これは永続化レイヤーのように聞こえます。 MVCにはさまざまなバリエーションがありますが、永続性はモデルの一部である必要があります。少なくとも、それは私がモデルを使用した方法であり、そうである必要があると思います。

一部のコード、クラス、関数などを配置する場所(M、V、またはC)を決定する際には、MVCが存在する基本的な理由を念頭に置いて、問題を分離することをお勧めします。優れたMVC実装では、CまたはVを別の実装に置き換えるのは比較的簡単です。それを行うとき、「追加」の別の実装を提供する必要がありますか、それともM内ですでに利用可能である必要がありますか? (*)


(*)=永続性をMと密接に結合する必要があると言っているわけではないことに注意してください-必要に応じてモックまたは置換できる永続性レイヤーが必要です(たとえば、DBからWebサービスの使用まで)- Mと一緒に行くと言っています。

編集:あなたが尋ねた新しい質問に答える

ユーザー入力を検証するための適切な場所はどこですか?それはモデルに行くべきですか?

検証はモデルとコントローラーの両方で行われます。ただし、検証には2種類あります。

ユーザー入力はコントローラー内で検証されます。ユーザーはすべての必須フィールドに入力しましたか?モデルを呼び出すために必要なものをすべて受け取りましたか?この種のもの。次に、コントローラーはモデルのパラメーターへの入力をマッサージします。たとえば、通常はものを文字列として送信しますが、モデルは整数を期待する場合があります。コントローラーは入力データを適応させ、それがモデル呼び出しに対して有効であることを確認します。

これで、モデルは独自の検証を行います。受信したパラメータの確認とビジネスルールの確認。それはユーザー入力を気にせず、呼び出しで受信したパラメーターを気にします。上で述べたように、アイデアはMVCのパーツの交換について考えることです。コントローラを交換し、新しい実装にバグがあり、パラメータをモデルに送信する適切な処理を行わない場合、モデルはそれらを信頼し、検証のために何もしないでください。それらを検証する必要があります。

また、ユーザーが情報にアクセスする権限をどこで確認すればよいですか?

MVCでは、これはほとんどの場合コントローラー内に配置されます。これは、ユーザーとモデルの相互作用がコントローラーを通過するためです。コントローラーがエントリーポイントです。ほとんどの人はそこで立ち止まります。適切な権限がないことをコントローラーが確認した場合、モデルは呼び出されません。ここでも、コントローラーを交換するか、新しいコントローラーを追加する場合、新しい実装はモデルを保護する必要があります。バグがあるか、開発者が忘れた場合は、想定されていなかったものの、モデルイベントへの呼び出しが行われる可能性があります。

したがって、セキュリティはコントローラとモデルの両方に適用する必要があります。モデルはビジネスコールが許可されていることを確認し、コントローラーはエントリポイントが許可されていることを確認します。たとえば、ログインしているかどうかにかかわらず、URLには問題なくアクセスできます(コントローラーはどちらの方法でも許可します)が、ログインしている場合にのみ、そのURLから一部の機能にアクセスできます(モデルでは匿名ロールは許可されません)。

これがお役に立てば幸いです。回答で述べたように、MVCにはさまざまな種類があり、アプリケーション、ニーズ、開発者の理解、アクセスメディア(Web MVCとデスクトップアプリMVC)などに応じて、特定の動作がさまざまな方法で実装される場合があります。

1
Bogdan

Model View Controler は、実際には3つの個別の懸念、つまり責任をグループ化することについてのみです。これは、オブジェクトを相互作用させる方法を知る前に作成された古いデザインパターンです。

表示-ユーザーに表示するためのロジック。

正しい。これらが複数ある可能性があることを覚えておいてください。

モデル-データベースモデル。

はい、どのモデルもそうです。これはあなたのプログラム state です。自分がどこにいるかを覚えているところではね。文字列、int、whatnotなどの一部の value objects の可能性があります。

コントローラ-モデルに格納された情報をビューに移動する、またはその逆を処理するロジック。

番号。

これは、MVCの特定の実装にのみ当てはまります。つまり、次のようになります。

あなたができること。しかし、あなたも行うことができます:

ここでは、コントローラーはビューが存在することすら知りません。 「何について何を知っているの?」私が知っている建築の最高の質問です。

MVCには他にも 多数 の形式があります。勉強していて、多くのことがうまくいっていないような気がする場合は、注意を払っています。

これがMVCの使用を決定するということは、それほど多くの意味を持ちません。それでも、何について何を知り、どのように話すかを決める必要があります。

私がモデルにいるとき、私はすべてが状態を作成する基本的な方法であることを期待しています。決定を下すロジックに対処したくありません。

したがって、私の質問は、モデルの処理に役立つ関数がいくつかあるかどうかですが、モデル自体ではありません。どこに配置すればよいですか?

たとえば、次のモデルがあるとします:ユーザー、投稿、コメント。そして、「追加」という関数を作成し、そのモデルの「モデル名」と「プロパティ」という2つの引数を受け取り、関数は要求されたモデルを使用し、データベースに追加するために必要なすべての作業を行いません。

モデルには、変更を可能にする基本的なAPIが必要です。これがそうであれば、これがモデルです。そうでない場合。これが基本モデルAPIの上にある豪華なレイヤーである場合、それは実際にはモデルではありません。

そして、あなたが私が見るべきだと思う良い構造パターンはありますか?

はい、そうです。 MVCは、アーキテクチャとデザインパターンの両方の原始的なグーです。始めるには良い場所ですが、住むには貧しい場所です。

まず最初に observer pattern について調べます。それは実際にイベントが何であるかを教え、これらの図の矢印のいくつかが同じではない理由を説明します。

依存関係の逆転の原則 とは何かを学びます。それはあなたがあなたの責任の周りに描く線を意味のあるものにするのに役立ちます。

アーキテクチャの準備ができたら、 六角形アーキテクチャ を読んでください。これは、レイヤードアーキテクチャを見る別の方法です。六角形のアーキテクチャの素晴らしいバリエーションは クリーンアーキテクチャ です。

私が得ることができるものはもっとたくさんありますが、それはあなたがしばらく噛むのに十分なはずです。

2
candied_orange

モデルとの関係を確立する必要があります。関係には、1:1、1:多、多:1、多:多があります。

あなたの例を考慮に入れる:-

1人のユーザーが複数の投稿を作成できます

1つの投稿に複数のコメントを付けることができます。

したがって、基本的にモデルクラスをコーディングすると、次のようになります。

 /*
   Disclaimer: This is just an illustration. The actual code may differ depending on the technologies or frameworks that you use. 
 */

 class User {
    private String name;
    private String createddatetime;
    ....
    ....
    @OneToMany
    private Collection<Post> posts = new ArrayList<Post>();
 }

 class Post {
   ...
   ...
   @OneToMany
   private Collection<Comments> comments = new ArrayList<Comments>();
 }
 class Comments {
    private String freeText;
 }

それが言われたら、あなたのクエリに来ましょう:-

したがって、私の質問は、モデルの処理に役立つ関数がいくつかあるかどうかですが、モデル自体ではありません。どこに配置すればよいですか?

それはコントローラーの責任です。

コントローラはモデルにコマンドを送信して、モデルの状態を更新できます(ドキュメントの編集など)。また、関連するビューにコマンドを送信して、モデルのビューのプレゼンテーションを変更することもできます(ドキュメントをスクロールするなど)。

コントローラは、サービスのメソッドを呼び出すか、モデルをインスタンス化するDaoメソッドを呼び出すことができます。

0
Mitesh Manani