SOY CMS / SOY Shop

ブログトップ

SOY2フレームワークの解説 3回目 SOY2 SOY2Action SOY2Logic

2010年04月19日

 

第三回目はビジネスロジックの中心であるSOY2、SOY2Logic、SOY2Actionの3パッケージについて解説します。

 

 

○SOY2

 

SOY2が解決するのは、オブジェクト指向でプログラミングをした際に問題となる以下の2点です。

 

-クラス・ソースコードのインポート

-オブジェクトの変換

 

大量のクラスファイルが複雑に関連するため、includeするかしないのかが重要になってきます。全てを最初から読み込むのではパフォーマンスが下がります。

単独ファイルの読み込み、SOY2::import()、ディレクトリ以下全ての読み込みSOY2::imports()の二個のメソッドがあり、設計に応じて柔軟に使用します。

 

クラスの役割を分割するためにはオブジェクトの変換が必須です。

 

class A{

    private $name;

    private $value;

}

class SamplePrint{

    private $name;

    private $value;

    function print(){

          echo $this->name . " is " . $this->value;

    }

}

二種類のクラスがあり、同じパラメータを持つが機能が異なることはよくあると思います。

Aクラスはシンプルなデータ保持用のクラスです。

SamplePrintはprint()というメソッドを持ちます。

 

SamplePrintがAの子クラスであれば問題ありませんが、そうでない場合に力を発揮します。

 

$a = new A;

$print = SOY2::cast('SamplePrint', $a);

$print->print();

SOY2::cast()メソッドでオブジェクトの値をそのまま特定のクラスにコピーすることが出来ます。例えばstdClassに書き出してJSONに変換すればJavaScriptとの連携に使うことが出来ます。

echo json_encode("object", $someLargeClass);

 

○SOY2Action

 

SOY2ActionとSOYLogicはどちらもビジネスロジックを記述するための物です。

システムの多くのメソッドはこのLogicとActionに集中します。

 

2種類用意しているのは、HTTPに関連するかしないか、の2種類です。

 

SOY2ActionはPOST/GETで飛んで来た値のチェックとオブジェクトの変換を同時に行うことが出来ます。

フォームが固定でかつデータのバリデーションが重要な場合はSOY2Actionが有効です。

 

また違う画面に同じフォームが表示されていることが多いなどの場合も、リクエストとデータの変換をカプセル化するため効率があがります。

 

SOY2Actionは以下のクラスで構成されます。

・SOY2Action

処理を記述。

・SOY2ActionRequest

$_REQUESTの管理クラス

・SOY2ActionResult

SOY2Actionの結果

・SOY2ActionForm

POST/GETから自動変換。その際にバリデーションを行う。

 

全てのActionは同じ書き方で実行することが出来ます。

その実行結果はシンプルに【成功】【失敗】の属性を持ちます。

呼び出し元は成功したか失敗したかの判定に応じて処理を分けられるため、ソースコードの見通しがあがります。

 

$action = new SampleSOY2Action();

$result = $action->run();

if($result->success()){

    //成功の場合

}else{

    //失敗の場合

}

 

○SOY2Logic

 

SOY2Logicは同じくビジネスロジックを記述します。SOY2Actionと違い特定の実行メソッドを持ちません。

以下の特徴があります。

 

・実装クラスを切り替えることが出来る

・単体で動作可能(動作が可能になるように作る、の意味含め)

 

他のパッケージと違い内部で機能をあまり持ちません。

単体テストが行いやすいようにロジックを設計すること、複雑なトランザクションの記述など、最終的なシステムの見通しをあげるためにはロジックでの実装が必要になってきます。

 

こんな使い方が出来ます。

 

要求:注文情報がDBに入っているが、クラスの肥大化を防ぐためにOrderクラスには

getter、setter以外のメソッドを持たないようにしたい。

 

実装:

class Order{}

class OrderLogic extends Order implements SOY2LogicInterface{

        function doOrder(){

             //注文実行処理

             //注文完了メール送信

             //etc...

        }

        function doCancel(){

             //注文キャンセル処理

        }

}

--

$order = SOY2DAOFactory::create("OrderDAO")->getById($id);

$logic = SOY2::cast("OrderLogic",$order);

try{

 $logic->doOrder();

}catch(Exception $e){

    $logic->doCancel();

}

※本来ならばエラーがあった場合はdoCancelを呼ぶはdoOrderに組み込むべきですが

わかりやすくするために書いています。

 

このように、Orderクラスはシンプルなままに注文を実行するというビジネスロジックを追加することが出来ます。

システム全体の見通しとメンテナンス性をあげるのに効果的ではないでしょうか。

 

 

 

○まとめ

 

このあたりは他のフレームワークでもある「あたりまえ」の機能です。

 

大事なのはそのシステムでどのようなポリシーで設計を行うかという点につきます。

小さなプログラムであればSOY2Action・SOY2Logicを使わない設計もありますし、開発途中で機能が肥大化したためLogicを分割することもあると思います。

 

そのためにはパッケージ間が疎であることが必要だと考えています。

 

次回、パッケージとパッケージを繋げる、フレームワークの中心であるSOY2Controllerについて解説します。