15

私は最近、MVC アプリでフォーム データを最適に処理する方法についてのディスカッションで、Jani Hartikainenによってサービス レイヤーについて紹介されました。いくつか読んだ後、私はこのアプローチの利点を本当に見ることができます. 私の質問はこれです:

サービス クラスはどのように構成する必要がありますか?

  • まず、モデルuser_service()に適切なクラス名user()はありますか、それとも別の標準がありますか?
  • 私のサービスのメソッドは 1 つのタスクしか実行しないため、これらは常にstatic function. サービス クラスはデータを表すのではなく、一連のアクションであるため、これは適切なようです。
  • サービス メソッドは 1 つだけを受け入れる必要argumentがありarrayます。

ユーザーデータを保存するために、フォームがコントローラーにデータを投稿したとします。

<?php

    class form_controller extends controller
    {

        public function process_submit()
        {
            if(user_service::update_preferences($_POST))
            {

                echo json_encode(array('success' => true));
            }
            else
            {
                echo json_encode(array('success' => false));
            }
        }

    }

    class user_service
    {

        // Accepts array()
        public static function update_preferences($fields)
        {

            // Check for required fields
            if((
                isset($fields['firstname']) and
                isset($fields['lastname']) and
                isset($fields['email'])
                ) == false
            {
                return false;
            }

            // Update user
            try
            {
                $s = new user();
                $s->set_firstname($fields['firstname']);
                $s->set_lastname($fields['lastname']);
                $s->set_email($fields['email']);
                $s->update();

                return true;
            }
            catch(Exception $e)
            {
                return false;
            }
        }
    }

次の理由から、これは良いアプローチだと思います。

  • controllerフォームに別のフィールドを追加できます。更新する必要はありませんservice。コントローラーは、渡されたデータが何であるかを気にする必要はなく、単に渡されたということは正しいようです。これにより、コントローラーが小さくなり、モデルのロジックが小さくなります。
  • を渡さなかった場合array、複数の引数を持つ関数をセットアップできました。たとえば、私の機能はupdate_preferences($firstname, $lastname, $email). ただし、これは 20 を超える引数を持つ関数 (大きなフォームの場合) を作成する可能性があり、その順序は操作するのがひどくなります。
  • を渡すこともできますがobject、それは意味がありますか? オブジェクトを作成している場合、それはそれが表すオブジェクト (この場合はユーザー) である必要がありますよね? しかし、コントローラーがユーザー オブジェクトをインスタンス化することに意味があるでしょうか。そもそもそれがサービス層の要点ではないでしょうか?
  • おそらく、複数の引数を持ついくつかのメソッド (1 つから 3 つしかない場合) と、配列を受け入れるいくつかのメソッド (多数のフィールドがある場合) を持つための議論があるかもしれません。特定のメソッドが何を求めているかを知るには、常にクラスを参照する必要があるため、これは悪夢のように思えます。

ここで行うべき正しいことについて誰か意見がありますか? 私は正しい軌道に乗っていますか?過去に何をしましたか?どうもありがとう!

4

1 に答える 1

25

あなたが私にメールを送るところまで行ったので、これに答えるかもしれません;)

まず、user_service() は私の user() モデルの適切なクラス名ですか、それとも別の標準がありますか?

それは許容できます。ただし、PEAR や ZF 規則など、確立された PHP コーディング規則のいずれかを使用する必要があります。どちらの場合も、クラス名はUpperCamelCaseおよび メソッド名lowerCamelCaseです。これを使用すると、クラスは次のようにUserなりますUserService

私のサービスのメソッドは 1 つのタスクしか実行しないため、これらは常に静的関数であると考えるのは正しいですか? サービス クラスはデータを表すのではなく、一連のアクションであるため、これは適切なようです。

いいえ。メソッドを静的にすることは、設計上の選択として適切ではありません。これは、サービスだけでなく、ほとんどのコードに当てはまります。サービスの場合の主な理由の 1 つは、通常、サービスがデータ ストアまたはデータ層を表す別のクラス (リポジトリ、データ アクセス オブジェクトなど) と対話する必要があることです。

サービスに静的メソッドがある場合、これは、メソッドで依存関係をインスタンス化する必要があることを意味します。これは、とりわけ、依存関係を簡単に置き換えることができないため、コードのテストが難しくなることを意味します。

これについては、たとえばここにいくつかの良い読み物があります(実際、そのブログのほとんどすべてがソフトウェア開発者にとって良い読み物です)

サービス メソッドは、配列である 1 つの引数のみを受け入れる必要がありますか?

これは、メソッドが何をするかによって異なります。フォームの結果セットを処理する例を想定すると、はい、これはおそらく機能します。他の場合には、それは悪い選択かもしれません。

フォームに別のフィールドを追加できます。コントローラーを更新する必要はなく、サービスだけを更新する必要があります。[ ... ]

配列を渡さなければ、複数の引数を持つ関数をセットアップできました。[ ... ]

ええ、私の意見では、これら2つのケースに対するあなたの議論は、このユースケースにかなり当てはまります.

オブジェクトを渡すことはできますが、それは意味がありますか? オブジェクトを作成している場合、それはそれが表すオブジェクト (この場合はユーザー) である必要がありますよね? しかし、コントローラーがユーザー オブジェクトをインスタンス化することに意味があるでしょうか。そもそもそれがサービス層の要点ではないでしょうか?

これは依存します。たとえば、フォームをオブジェクトとして表現できるフレームワーク ( Zend Framework やZend_Formなど) を使用している場合は、フォーム オブジェクトをサービスに直接渡すことを検討できます。

おそらく、複数の引数を持ついくつかのメソッド (1 つから 3 つしかない場合) と、配列を受け入れるいくつかのメソッド (多数のフィールドがある場合) を持つための引数があるかもしれません。特定のメソッドが何を求めているかを知るには、常にクラスを参照する必要があるため、これは悪夢のように思えます。

通常は、メソッドの名前に基づいて、パラメーターを少なくとも半分推測できるようにすることを目指してください。私が取り組んでいるものでは、たとえば企業と製品を持ち、企業が製品を後援できるモデルがあります。には、ビジネスと製品をパラメーターとして受け取る とProductService呼ばれるメソッドがあります。sponsorProductこの 2 つが必要であるとほぼ推測できます (とにかくコードベースに精通している場合)。

IDE も一般的にこれに役立ちます。IDE は、どの params 関数が取るかを表示するコードアシストを提供します。これが、特定の関数がパラメータとして必要とするものを正確に覚えているとは限らない大規模なプロジェクトで、IDE が非常に役立つと私が考える主な理由の 1 つです。

パラメータ数に関しては、通常は別々のパラメータを持つようにすべきだと思います。これにより、誰でも関数のシグネチャを見るだけで必要なパラメーターを簡単に確認でき、タイプヒントとデフォルト値を非常に簡単に定義できます。

ただし、非常に多くのパラメーターを取得すると、多すぎるポイントがあります。これは、メソッドの種類にもよりますが、おそらく +5 程度です。この場合、配列、またはパラメーター オブジェクトと呼ばれるものを使用することを検討できます。これは、基本的に、呼び出しのすべてのパラメーターを含むオブジェクトです。パラメータオブジェクトの詳細はこちら

于 2011-06-29T18:49:43.317 に答える