2013-03-18 8 views
5

私は保守可能で読みやすいコードを作成するために、PHPで別々のレイヤーを扱うことについて研究し、多くのことを読んできました。 しかし、エンティティとデータベースアクセスが1つのクラスに配置されているコードが多数あります。たとえば :php DAL - エンティティとデータベースを分離しますか?

class User{ 
    public $id; 
    public $username; 
    public $database; 

    function add(){ 
      $database->query .... 
    } 
} 

ここにあなたが維持することがより困難にデータベース要素とUserクラスを混合しているので、私は、これはかなり奇妙見つけます。

私はこのような作業のように:

  • 別々のデータベースクラス
  • ユーザークラス
  • のuserdataクラス

これは、このように動作します:

$database = new Database(); 
$database->openConnection(); 
$dataUser = new DataUser($db); 
$user = new User(1,"myname"); 
$dataUser->saveUser($user); 

だから私は思っています、私は働いていますコードを作成する最初の方法は正しい方法ですか? データベースの操作を処理する別個のエンティティと別のデータベースクラスがあるため、管理が非常に簡単です。

+0

+1素敵な質問:) –

+1

素敵なご質問にはあまりにも1 ... –

答えて

1

あなたが別のエンティティと別の データベースクラス

を持っているので、あなたがData Mapper/Entity/RepositoryアプローチにActive Recordアプローチから脱却したいことを言っている思わ維持しやすいです。それは懸念のより良い分離を採用しているので、移動するための良い方向です。あなたはこの自分自身を構築することができますが、それはあなたがの線に沿って何かを行うことができますDoctrineのようなソリューションを見てみたいことがあります

$product = new Product(); 
$product->setName($newProductName); 
$entityManager->persist($product); 

$productエンティティはちょうどPOPO(プレーン旧PHPオブジェクト)であることレコードデータを含み、永続性がどのように保持されているかを認識せず、永続性が必要な場合は、格納を処理するためにエンティティマネージャに渡されます。私は何

+0

ありがとうございます。私は単なるエンティティを分離したいので、オブジェクトとして取得することができます。たとえば、データなどの配列として取得することはできません。 私はDoctrineを調べます。 – randomizer

1

個人的には、抽象化UserDataからUserが過剰殺しそうです。この場合には、UserDataは、例えばProductDataと非常に類似していると思われる、として - 彼らはまだあなたのケースではadd($data)find($id)など

を含めるつもりだ、UserMVCアプローチではモデルであり、そしてありますデータベースストア/検索ロジックを含むことは完全に許容可能です。しかし、他のモデルで持っているUserクラスの同じDBメソッドを作り直していることに気付くでしょう。ここで、ORMの実装を見てみましょう。その場合、共通のDBアクセスメソッドは抽象クラスで定義され、すべてのモデルが拡張され、必要に応じてオーバーライドされます。

+0

私は再びこのトピックを読んでいたと私は本当にあなたの最後の行を理解していません。 はその正常でない私などUserdataの、ProductData、すべて含まれている彼らは別のテーブルにクエリを実行する必要があるための「発見」し、「削除」、「保存」機能を言わせて。 ここで抽象クラスの利点を得ることはできません。データベースアダプタをインスタンス化してすべてのxDataクラスで使用できるように抽象クラスを使用します。 – randomizer

1

私のモデルは、(私は教義を使用していない)データベースにリンクされているエンティティ、ありませんので、「アクティブなレコード」の方法ではありません。オブジェクトはその依存関係をフェッチする方法を知らない(たとえば、ユーザーがn個のコメントを持つ可能性があり、モデルがコメントを取得する方法を知らない)。

class User{ 
private $name; 
private $password; 
// getter and setters 
} 

私は、プロバイダからモデルをフェッチできるビジネスロジックを持つサービスを持っています。サービスには多くのプロバイダがあります。

class UserService{ 
    function __construct(IUserProvider $userProvider){ 
     $this->userProvider = $userProvider 
    } 
    function getUsers(){ 
     // return an array of user objects 
     return $this->userProvider->getUsers(); 

    } 
} 

最終的に私は、テキストファイル、JSONファイル、Webサービス、データベースから件のデータを要求する方法を知っているデータプロバイダを持っている:

class UserProvider implements IUserProvider{ 
     function __construct(Connection $connection){ 
     $this->connection = $connection; 
     } 
     function getUsers(){ 
     return $this->toUsers($this->connection->fetchAssoc("Select * from users")); 
     } 
     function toUsers(array $datas){ 
      // convert user records to an array of User 
      (...) 
      return $users; 
     } 
} 

、インターフェイス

interface IUserProvider{ 
    /**@return array an array of User */ 
    function getUsers(); 
} 

私はユーザーのコメントを取得する必要がある場合、私のコメントサービスは、どのようにユーザーIDからコメントを取得するのか知っています。だから、ユーザーとそのコメントを得るためには、私はデータベースへの2つの要求が必要です。 1つはUserProviderのもの、もう1つはCommentProviderのものです。コマンドラインインタフェースで動作するように持っているとされていない(

  • 私のサービス層(何でも...要求に応答し、表示ユーザー)

    • 私のアプリケーション層:

      ので、私は3つの層を持っています通常、私が使用するフレームワークにバインドされ、ACLが多分詰めされたパスワードのエンコードを除いて私のWebアプリケーション、...)

    • を認識して他の層について何も知らない私のデータアクセス層、

    私のレイヤーが通信する唯一の方法は、モデルからレイヤーに渡すことです。

    そして、すべて私のクラスは、依存性注入コンテナを使用して構築されているので、配線は問題ではありません。ここで

    は私が作ったアプリのexempleあり、それはオープンソースです:https://github.com/Mparaiso/silex-bookmarkly

    任意の考えを歓迎します。

  • 関連する問題