2

私は現在、Zend Frameworkプロジェクトに取り組んでいます。これにより、ユーザーがアプリケーションを移動した結果、結果を含む大きなテーブルが表示されます。このテーブルにはさまざまな数の行を含めることができ、そのほとんどは計算の結果として生成されます。ここまでは順調ですね。

最初; 小さなハードルはありますが、テーブルを水平に表示する必要があるということです。つまり、見出しは列1にあり、追加の各列はデータエンティティ項目を表します。例えば:

フォアネーム| ジェームズ| リチャード
姓| ジョーンズ| メイフェア

繰り返しますが、これは問題ではありません。私がテーブルをきちんと構築するようになると、問題が発生します。ビルダーパターンを使用して、テーブル、グループ、行の3つのクラスがあります。これらは次のように使用できます。

$table = new Table($attribs);
$group = new Group(); // Nothing special about groups, they're just there for helping with presentation

$row = new Row();
$row->setTitle('Forename')
    ->setData(array('item1' => 'James', 'item2' => 'Richard'))

$row2 = new Row();
$row2->setTitle('Surname')
     ->setData(array('item1' => 'Jones', 'item2' => 'Mayfair'))

$group->addRow($row)
      ->addRow($row2);

$table->addGroup($group);

上記のコードスニペットは、コントローラーのアクション内に表示されます。次に、テーブルオブジェクトがビューに渡され、自分の仕様でテーブルに出力するビューヘルパーがあります。

しかし、私が直面している課題は、非常に厄介な「結果」モデルになってしまったことです。たとえば、私はたくさん持っています:

$group->addRow($this->_resultsModel->getSurnameRow());

'_resultsModel'プロパティは、次のことを行う多くのメソッドを含むオブジェクトです。

public function getSurnameRow()
{
    $row = new Row();
    $row->setTitle('Surname');
    $row->setData($this->_getAssociateArrayOfSurnames());
    return $row;
}

さらに、resultsオブジェクトは、生データのアクセサー、セッター、および計算メソッドを含む結果抽象クラスを拡張します。これらの「計算」メソッドはそれぞれ、行オブジェクトに割り当てることができるデータの連想配列を返します。結果オブジェクトと抽象化されたクラスはどちらも長く、ばらばらに見えます。

要約すると...すべての計算を実行し、すべての行オブジェクトを返す1つの大きな結果モデルになりました。それは機能しますが、私は物事を行うためのより良い方法があると確信しています。コントローラで行を作成する必要がありますか?モデルからの計算のみを呼び出す必要がありますか?誰かがこのようなものを抽象化した経験がありますか?

申し訳ありませんが、これは不十分な説明です。誰かが私が答えることができる質問があれば、私に知らせてください。

4

1 に答える 1

0

まず、コントローラーの内部にロジックが多すぎないようにする必要があります。コントローラーは、モデルへの入力を処理し、結果を出力(ビュー)に転送するためのものであり、計算するためのものではありません。

第二に:あなたの結果には他にもやるべきことがたくさんありますが、なぜそれはテーブル表現を扱わなければならないのですか?また、文字列のみが異なる多数の個別の関数が必要なのはなぜですか?

私は宣言型配列と一緒に何かをするだろうと思います:つまり、私は次のような宣言型配列を収集します:

$table_description = [
     'group1' => ['surname', 'firstname', 'whatever'],
     'group2' => ['other', 'rows', 'as', 'needed']
];

この説明を解析して実際のデータで埋める何かを構築します(必要に応じてリフレクションを使用)

主な問題は、形態は機能に従う、アルゴリズムはデータ構造に従うということです。

テーブル、グループ、行に分割されたデータ構造がある場合は、同じことを行うアルゴリズムがある可能性があります。

2番目の質問は、変更はどこで発生する可能性が高いかということです。テーブルスキームを簡単に変更できる場合は、それらを「config」(記述子)に入れます。行のフォーマットが簡単に変更される可能性がある場合は、それらが自己フォーマットであることを確認してください(または、行に実際に何が含まれているかを知らなくても、誰かがフォーマッターを要求する方法を知っています)

デフォルトにフォールバックできるようにすることをお勧めします。つまり、ほとんどの行がデフォルトの方法で作成されている場合は、次のようなデフォルトの方法を使用できることを確認してください。

class Row {
   public $formatter;
   private $data_assoc;
   private $title;
   public function __construct($title, $data, RowFormatter $formatter=NULL){
       if ($formatter == NULL){
          $this->formatter = DefaultFormatter::getInstance();   
       }
       /*set title, data_assoc...*/
   }
   public function setFormatter(RowFormatter $formatter){/*obvious*/}
   public function format(){
       return $this->formatter->format($this->data_assoc);
   }
}

さて、あなたのresultsModelにはあまりにも多くの責任があるようです、あなたはこれらのプレフィックス名(getSurnameRow)を持っています-なぜresultsModelは行についてまったく知っている必要がありますか?また、連想配列(マップ)は、特にPHPでは非常に優れた構造です。getData('Surname')では不十分なのはなぜですか?Rowがタイトルと関連データからそれ自体を構築できないのはなぜですか?

同じことを実行したいが、プロパティが異なる場合は、列挙型または文字列を使用します。時々プラグインできるようにする必要がある場合は、プロパティ名に基づいてインデックステーブルを検索し、例外でない場合はデフォルトの実装にフォールバックするファクトリを使用します。

$row = RowFactory::getRow('Surname');
$row->setData($this->data['Surname']);

このようなコードの複製は、2つのプロパティと単純な直交性(getX、getYなど)である限り問題ありません。しかし、プロパティの数が無限であるため、それは単なる複製だと思います。

于 2012-07-23T22:15:33.873 に答える