5

私は、PHP で個別のレイヤーを操作して保守可能で読み取り可能なコードを作成することについて、多くのことを調査し、読んでいます。ただし、エンティティとデータベースへのアクセスが 1 つのクラスに配置されている多くのコードを目にします。例えば:

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);

だから私は疑問に思っています、私は正しい方法で作業していますか、それとも最初の方法がコードを作成するためのより良い方法ですか? データベース アクションを処理する別のエンティティと別のデータベース クラスがあるため、保守が非常に簡単になる場合があります。

4

3 に答える 3

2

私がやること :

私のモデルはデータベースにリンクされたエンティティではない(教義を使用していない場合)ため、「アクティブなレコード」メソッドはありません。オブジェクトはその依存関係を取得する方法を知りません (たとえば、ユーザーは 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 ファイル、webservice からデータを要求する方法を知っているデータ プロバイダーがあります。

 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つの層を持っています:

  • 私のアプリケーション層(ユーザーの表示、リクエストへの応答...)
  • 私のサービスレイヤー(コマンドラインインターフェイスで動作する必要があり、私のWebアプリケーションを認識しません。通常、私が使用するフレームワークにバインドされているパスワードエンコーディングと、おそらくACLスタッフ...)
  • 他のレイヤーについて何も知らない私のデータアクセスレイヤー、

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

また、すべてのクラスは依存性注入コンテナーを使用して構築されているため、配線は問題になりません。

これは私が作ったアプリの例です。これはオープンソースです: https://github.com/Mparaiso/silex-bookmarkly

どんな考えでも大歓迎です。

于 2013-03-18T09:29:48.970 に答える
1

別のエンティティと別のデータベース クラスがあるため、保守が容易

Active RecordアプローチからData Mapper/Entity/Repositoryアプローチに移行したいとおっしゃっているようです。関心のより良い分離を採用しているため、これは良い方向です。これを自分で構築することもできますが、Doctrineのようなソリューションを見て、次のようなことができるようにすることをお勧めします。

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

エンティティは、$productレコード データを含む単なる POPO (Plain Old PHP Object) であり、それがどのように永続化されるかを認識せず、永続化が必要な場合はエンティティ マネージャーに渡されて保存されます。

于 2013-03-18T09:16:46.540 に答える