0

簡単な背景: 私は PHP でプログラミングしています。DB からのデータのフェッチとドメイン クラスの作成を担当する別のデータ アクセス層 (DAO クラス) を持つドメイン モデルがあります。

groupオブジェクトとgroupListオブジェクトの作成を担当する DAO クラスがあるとします。グループは、ソーシャル ネットワークのコンポーネントと考えることができます。ただし、この質問でそれらが何であるかは問題ではありません。

さまざまな基準に基づいてさまざまなgroupListオブジェクトを作成するように DAO に依頼できるようにする必要があります。

  • 最近追加されたグループ
  • 最も人気のあるグループ
  • 管理者によって「おすすめ」として識別されたグループ
  • 特定のタグが付けられたグループ
  • 特定のキーワードに一致するグループ
  • 特定のカテゴリ内のグループ
  • 特定の人が作成したグループ
  • 特定の日に作成されたグループ

これらのいくつかは、今は実際には必要ありませんが、プロジェクトが完了する前に必要になると想像できます. 今、私は素晴らしい単純な DAO メソッドであるcreateListから始めました。これはうまくいきました。擬似コードは次のように考えることができます。

find out how many groups
create SQL query to fetch group details
loop through results
{
   create group object
   add to group list object
}

アプリケーションの進行に合わせて、新しいメソッドcreateFeaturedListを作成しました。これはうまくいきました。しかし、実際にはcreateListと非常によく似ていて、クエリが少し異なります。約 150 行のコードの残りの多くは同一でした。

それで...必要なわずかに異なるすべてのケースについてどうすればよいですか? ほとんどの場合、特定の基準に基づいてリストをフィルタリングおよびソートしたいだけです。問題はこれです-私はすべきですか:

a)次のような集中的な作成方法をたくさん作成します。

  • createList()
  • createCategoryList( カテゴリオブジェクト )
  • createUsersList ( userObject )
  • createTagList (タグ)
  • createPopularList ()

また

b)すべてを実行できる 1 つの BIG メソッドを作成します。 - createList ( searchString, orderBy, filterByCategoryObject=null, filterByUserObject=null )

私のDAOインターフェイスはよりシンプルで、変更する必要がほとんどないため、(a)のアイデアが非常に気に入っています(たとえば、比較するために突然日付を渡す必要があるときに別のパラメーターを追加する)他のパラメーターと組み合わせたいキーワード。例: 検索されたカテゴリ リスト、検索された人気リスト、検索されたタグ リストなど... (a) は、私が始めたもののようなものです。

(b) へのリファクタリングをいじりましたが、SQL を構築するときのさまざまなケースに対処するために、メソッドが非常に大きく、非常に複雑になり、多くの "if" と "select" が発生することがわかります。メソッドに渡される多くのパラメーター。しかし、少なくともすべてが 1 か所にあります。そして、物事を組み合わせることができます。例: blah でタグ付けされた、キーワード blah に一致するユーザーのグループ。

4

5 に答える 5

1

オプション Bのbigメソッドは、コードの再利用を減らし、複雑さとメンテナンス時間を増やすことがほぼ保証されています。

個人的には (そして Code Complete によれば)、メソッドは 1 つのことをうまく行うべきであり、すべてを詰め込もうとするのではありません。

于 2009-09-10T08:30:20.900 に答える
1

厳密にはどちらかまたはどちらかの状況ではないと思います。オプション a は、DAO が公開する便利なインターフェイスなので、そのままにしておく必要があると思います。私には、オプション b は実装固有のロジックのように思えます。したがって、BIG メソッドが目的に合っている場合は、それを使用して、オプション a のようにインターフェイスを公開しながら、実際の処理ロジックを実行することをお勧めします。

とはいえ、BIG メソッドがあまりにも複雑で複雑になり、コードの再利用が実際にコードの複雑さを増大させ、アプリケーションの保守性を低下させている場合は、インターフェイス メソッドごとに個別の SQL ステートメントを保持するようにリファクタリングする必要があるかもしれませんが、ヘルパー メソッドには共通のロジックを実行させます。結果の解析。

于 2009-09-10T07:54:24.463 に答える
1

すべてのパブリック メソッドが呼び出すプライベート メソッドを作成できます。IE

private function _createList ( searchString, orderBy, ... )
{
    ...
}

public function createList()
{
    return $this->_createList('...', 'id');
}

public function createCategoryList()
{
    return $this->_createList('...', 'category_id');
}

そうすれば、後で _createList 関数を変更する必要がある場合、この DAO を使用するすべてのクラスではなく、この DAO のパブリック メソッドをリファクタリングするだけで済みます。

于 2009-09-10T07:49:52.307 に答える
0

プログラミングの基礎: コードをセクションまたは関数に分割することをお勧めします。

オプション (a) を選択します。コードを保守およびデバッグする必要があります。バグが発生した場合は、コードをさまざまなメソッドに分割したことを非常に嬉しく思います。

また、メソッド名を書くことで、何をしているのかを理解するのに役立ちます。

これを比較してください:

オプション (a)

$obj->AddNewList( /* params */ );
$obj->UpdateList( /* params */ );

この:

オプション (b)

$obj->parse( /* first set of params */ );
$obj->parse( /* second set of params */ );

人間は左から右に読むので、時間を節約できます。そのため、関数名とメソッド名は常に左側にあります。

于 2009-09-10T07:28:59.277 に答える
0

パフォーマンスが大きな問題ではない場合、またはグループの変化が十分に遅い場合は、クエリ キャッシングを有効にして、フィルタリング関数を記述して渡すことができます。グループをループしていて、フィルタリング メソッドのオプションの配列がある場合は、ループ次のようになります。

for(group in group) {
    cont = true
    for(f in functions) {
        if ! f(group) {cont = false; continue;}
    }
    if(cont) Continue
    add group to list
}

これにより、関数を作成または変更するだけで、ループを変更せずにフィルタリング パラメータを変更できます。

于 2009-09-10T07:34:08.943 に答える