5

PHPでオブジェクトを最大限に活用する方法を誰かが理解するのを手伝ってくれるかどうか疑問に思っています。

PHPオブジェクトについての私の理解は、エンティティを表し、そのエンティティのプロパティを取得および変更するためのメソッドを提供する必要があるということです。たとえば、Postというタイトルのオブジェクトは、単一の投稿のすべてのプロパティを保持し、必要に応じてアクセスおよび変更できます。

私に混乱を引き起こしているのは、CodeIgniterのようなライブラリがこのマナーでオブジェクトを使用していないことです。これらは、クラスを関数のグループのラッパーのように扱います。したがって、CodeIgniterの「Posts」クラスは1つの投稿のプロパティを保持せず、投稿をフェッチ、編集、および削除するための関数を提供します。

では、データベースからすべての投稿を取得してPostオブジェクトに入れたい場合はどうなりますか?私の理解では、実際には2つのクラス「Posts」と「Post」が必要です。1つはPostオブジェクトを定義し、もう1つはデータベースからのPostのフェッチとPostオブジェクトへの配置を処理します。

これらの2つのタイプのクラスには名前がありますか(「適切な」オブジェクト/関数のコレクション)?そして、このように2つのクラスが連携することはよくあることですか、それともオブジェクトの使用方法を完全に誤解しているのでしょうか。

Postオブジェクトを使用する代わりに、配列を返すgetSinglePost($ id)というメソッドをPostsクラスに含める方が理にかなっていますか?

うまくいけば、その質問が理にかなっており、フィードバックを得るのを楽しみにしています。

4

3 に答える 3

5

はじめに、「PHPのクラスとは」を参照してください。

答えは、特にあなたの質問に答えるだけです。太字の用語を検索して、それらの意味について詳しく学んでください。

PHPオブジェクトについての私の理解は、エンティティを表し、そのエンティティのプロパティを取得および変更するためのメソッドを提供する必要があるということです。

エンティティは、オブジェクトの1つの可能な使用法にすぎません。ただし、値オブジェクトサービスオブジェクトデータアクセスオブジェクトなどもあります。オブジェクト指向ルートを使用すると、すべてが特定の責任を持つオブジェクトになります。

私に混乱を引き起こしているのは、CodeIgniterのようなライブラリがこのマナーでオブジェクトを使用していないことです。

はい、CodeIgniterは実際にはOOPを採用していません。彼らは、クラスベースのプログラミングアプローチをはるかに多く使用しています。これは、クラスを使用した手続き型プログラミングに似ており、OOPを少し振りかけるだけです。

これらは、クラスを関数のグループのラッパーのように扱います。したがって、CodeIgniterの「Posts」クラスは1つの投稿のプロパティを保持せず、投稿をフェッチ、編集、および削除するための関数を提供します。

それでも問題ありません。投稿クラスはリポジトリである可能性があります。たとえば、バックグラウンドでそれらを取得して永続化する追加の責任を持つ投稿エンティティのメモリ内コレクションです。デザインパターンとCodeIgniterは、独自のパターン解釈を使用することが知られているため、注意が必要です(たとえば、アクティブレコードはクエリオブジェクトに似ています)。

では、データベースからすべての投稿を取得してPostオブジェクトに入れたい場合はどうなりますか?

ここにはたくさんのオプションがあります。一般的なアプローチはデータマッパーを使用することですが、PDOを使用して、データ行を直接Postオブジェクトなどにフェッチすることもできます。

私の理解では、実際には2つのクラス「Posts」と「Post」が必要です。1つはPostオブジェクトを定義し、もう1つはデータベースからのPostのフェッチとPostオブジェクトへの配置を処理します。

これは、前述のリポジトリまたはデータマッパーアプローチになります。通常、これらをテーブルデータゲートウェイと組み合わせます。ただし、Postsクラスを持たず、Active Recordパターンを使用することもできます。これは、データベース内の行を、ビジネスロジックと永続性ロジックがアタッチされたオブジェクトとして表します。

これらの2つのタイプのクラスには名前がありますか(「適切な」オブジェクト/関数のコレクション)?そして、このように2つのクラスが連携することはよくあることですか、それともオブジェクトの使用方法を完全に誤解しているのでしょうか。

はい、彼らは一緒に働きます。OOPとは、オブジェクトのコラボレーションに関するものです。

Postオブジェクトを使用する代わりに、配列を返すgetSinglePost($ id)というメソッドをPostsクラスに含める方が理にかなっていますか?

これは、レコードセットを返すテーブルデータゲートウェイになります。CRUDアプリケーションのように、ビジネスロジックがあまりなく、ドメインモデルを節約できる場合は問題ありません。

于 2012-10-07T11:55:09.880 に答える
0

オブジェクトについてのあなたの理解は正しいです。投稿は、クラスの単一のオブジェクトですPost。ただし、もちろん、データベースから投稿を取得したり、別の場所から投稿を収集したりする関数が必要です。したがって、いわゆるファクトリクラスがあります。それが混乱を引き起こす可能性があります。

ファクトリはシングルトンにすることができます。これは通常、このクラスのインスタンスが1つあることを意味します。ただし、ファクトリをインスタンス化する必要はまったくありません(代わりに、静的関数を使用して機能にアクセスします)。

$posts = PostFactory::getPosts();

そして、関数:

static function getPosts() {
  $list = array();
  $sql = "select ID from posts order by datetime desc"; // example, ID is the primary key
  // run your sql query and iterate over the retrieved IDs as $id
  {
  ...
    $post = new Post($id);
    array_push($list, $post);
  }
  return $list;
}

このファクトリ内には、オブジェクトの作成(データベース単位)やオブジェクトの取得など、他の場所には適合しない「アクセス」関数のコレクションがあります。2番目の部分(取得)では、(リレーションの観点から)「親」オブジェクトがない場合にのみ、関数をファクトリに配置する必要があります。したがって、クラスのエンティティを持つことができBlog、ブログをインスタンス化してから、ブログインスタンスを介してブログの投稿を取得します。別のファクトリは必要ありません。

命名はあなたが理解するのを助けるためだけにあります。クラスを呼び出すことはお勧めしません。クラスは簡単に混同される可能性があり、コードが読みにくいため、PostファクトリPostsです(詳細に注意する必要があります)。私は通常、クラス名に「ファクトリ」という言葉を混ぜているので、実際にはファクトリクラスであり、他の人にも見られます。

さらに、特定のエンティティクラスに実際には関連しないヘルパークラスを作成することもできます。したがってPostHelper、オブジェクトクラスにもファクトリにも適合しない機能を保持できるシングルトンを持つことができます。Postオブジェクトに役立つ関数は思いつかないのですが。例としては、ものを計算するソフトウェアがあり、Helperさまざまなタイプのオブジェクトを使用して実際の計算を実行するがあります。

于 2012-10-07T11:54:54.033 に答える
0

クラスは、理想的にはPHPの他の場所と同じ解釈を持つ必要があります。クラスは抽象化から始まり、不要なものを洗練させます。したがって、クラスを希望どおりに定義するのは完全にあなた次第です。Codeigniterには、オブジェクトを開始してアクセスする奇妙な方法があります。主に、一度ロードされて後で使用されるため、データに関する機能が妨げられます。それを回避する方法があり、クラスの通常の処理はまだ可能です。私は通常、オートローダーを使用し、通常のクラスを使用します。「では、データベースからすべての投稿を取得してPostオブジェクトに入れたい場合はどうなりますか?私の理解では、実際には「Posts」と「Post」の2つのクラスが必要です。データ(「投稿」)にアクセスするためのモデルと「投稿」を表すエンティティ。

$this->load->model("posts");
$this->posts->get_all(); // <- This can then initiate set of objects of type "Post" and return. Or even standard classes straight out from DB.
于 2012-10-07T11:55:22.077 に答える