これをmvcとしてタグ付けしたので、DAO がモデル レイヤー内に既に存在すると仮定します。私が理解しているように。DAO はData Mappersと同じタスクを担当し、ストレージ (SQL データベースの場合もそうでない場合もある) からModel Layer内のドメイン オブジェクトに情報を提供します。
この問題に対処する最善の方法は、モデル レイヤー内にデータ アクセス オブジェクトを作成するファクトリを用意することです。これにはいくつかの利点があります。
- 異なる DAO のクラス名から切り離す
- 最初の DAO がいつ初期化されたかを知る機能
- すべての DAO インスタンス間で単一の DB 接続を共有する
これは私がそれのようなものを実装する方法です:
class DaoFactory
{
protected $connection = null;
protected $provider = null;
public function __construct( $provider )
{
$this->provider = $provider;
}
public function create( $name )
{
if ( $connection === null )
{
$connection = call_user_func( $this->provider );
}
$instance = new $name;
$instance->setConnection( $connection );
return $instance
}
}
使用法は次のようになります。
$connectionProvider = function()
{
$instance = new \PDO('mysql:host=localhost;dbname=testdb;charset=utf8',
'username', 'password');
$instance->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
$instance->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
return $instance;
};
$daoFactory = new DaoFactory( $connectionProvider );
次に、$daoFactory
DAO の作成に必要なオブジェクトに変数を渡します。create()
このようにして、必要に応じて、(同じメソッドのフットプリントを実装している限り) ファクトリを完全に異なるものに簡単に置き換えることができます。ドメインのビジネス ロジックは、このような変更によってまったく影響を受けません。
このファクトリを使用するオブジェクトは、データベース接続が存在すること、および DAO が機能するためにデータベース接続が必要であることを完全に認識しなくなりました。また、データベースへの接続を確立する必要さえないという状況に陥ることさえあります。
Rant
コードベースにデータ アクセス オブジェクトがあるため、OOP を使用しようとしていることを示しています。または、少なくとも似たようなもの。しかし、静的クラス/関数/変数は OOP パラダイムの一部ではありません。静的のみのメソッドといくつかの静的変数を持つクラスがある場合、実際に作成したのは、たまたまクラスのように見える名前空間にラップされた、グローバル変数を持つ単純な php 関数です。
PHP コミュニティは、この COP (クラス指向プログラミング) をジョークとして呼びがちですが、本質的には手続き型のコードです。