2012-10-09 4 views
7

私はPHPでOOPに移行しています。私はphp.netで説明を読んでいるが、私はここでいくつかの特定の答えを得ることができたと思っていた。PHPでクラスを構造化する方法

私の質問を説明するために、次の例を作成しようとしました。 「データベース」、「製品」、「ユーザー」クラスがあり、ユーザーがアクセスできる場合は製品を表示するとします。

"Products"クラスを "showProducts()"関数と呼びます。これは "User"クラスのインスタンスを作成し、 "Database"オブジェクトのインスタンスを作成し、ユーザーのアクセスレベルを確認します。

ユーザーがアクセスできる場合、 "showProducts()"関数は "Database"オブジェクトの別のインスタンスを作成し、データベースに照会します。

class Database{ 

    public function query(){ 
     //runs query here 
    } 

    public function __construct() { 
     //sets up connection here 
    } 

} 

class User{ 

    public function checkAccess(){ 
     $db = new Database(); 
     $db->query(//pass in query to check access) 
     //does stuff, then returns true or false 
    } 

} 

class Products{ 

    public function showProducts(){ 

     $user = new User(); 

     if($user->checkAccess()) 
     $db = new Database(); 
     $db->query(//pass in query to get products) 
     } 

} 

私は誰かがこれを正しい方法で行う方法を説明できると考えていました。

「データベース」オブジェクトの複数のインスタンスを作成することなく、アクセスする必要のあるすべてのクラスで使用できる1つの「データベース」オブジェクトを作成するコントローラクラスを用意したいと思います。私は、ユーザークラスで同じことをしたいので、 "User"クラスで何かを使う必要があるたびに、新しいオブジェクトを作成することなく、すべてのクラスがアクセスできる1つの$ usersオブジェクトがあります。

私の質問が明確でない場合はお詫び申し上げます。ご回答いただきありがとうございます。

返信いただきありがとうございます。

答えて

11

手続き型からオブジェクト指向プログラミングに移行するときは、クラスを構築する方法だけを理解する必要があります。 OOPは、OOPのベストプラクティス、原則、パターンに従ったクラスの作成ではありません。

新しいオブジェクトを別のインスタンスにインスタンス化しないでください。Userオブジェクト、Userが依存するDatabaseオブジェクト、コンストラクタ、またはsetterメソッドを渡す必要があります。それはDependency Injectionと呼ばれます。目標は、コンストラクタまたはセッタメソッドを使用してオブジェクトを必要とするクラスにオブジェクトを与えることです。そして、彼らはそのクラスの外からインスタンス化されるべきで、クラスを構成するのが簡単です。そして、クラスを構築するときに、そのクラスにどのような依存関係があるのか​​を簡単に見てほしい。あなたはここに制御原理の反転について読むことができます:IoC

をそれではあなたのコードは次のようになります。

<?php 

// User object that depends on Database object, and expects it in constructor. 

class User 
{ 
    protected $database; 

    public function __construct($database) 
    { 
     $this->database = $database; 
    } 

    // -- SNIP -- 
} 

?> 

あなたがこれを行う、そのユーザークラスを使用する:

<?php 

    $database = new Database($connParams); 
    $user = new User($database); 

?> 

することができます依存関係を設定するためにセッターメソッドを使ってDependency Injectionを使うこともできますが、私は自分自身でそれをグーグルにします:)

それは、原理、および依存性注入と依存性注入コンテナについては、クラスを管理するための最良の方法です。

私は "OOP"であるPHPコードをたくさん見ていて、実際にはクラスを機能の名前空間としてしか使用していません:)したがって、joustはOOPの原則とパターンについて学びます。

楽しくお楽しみください! :)

+0

返信いただきありがとうございます!だから私は別のクラスを参照している場合は、ユーザークラスでは、私はパラメーターとして同様に$ユーザーオブジェクトを渡すだろうか? – Ben

+0

はい、できます!あなたは好きなだけ多くのクラスを渡すことができます。オブジェクトが実際にそのオブジェクトを必要とする場合は、コンストラクタを介してオブジェクトを渡すことができます。オブジェクトがオプションの場合は、setterメソッドを渡すことができます。複雑な依存関係を取得したら、依存関係を記述するDependency Injection Containerの使用について考えることができ、Containerは他のオブジェクトからオブジェクトをアセンブルして返すことができます:) Dependency Injection and Dependency Injection Container :http://fabien.potencier.org/article/12/do-you-need-a-dependency-injection-container – otporan

0

すべてのコードを使用する1つのオブジェクトSingletonパターンにするには:

class Database{ 
    private $db_descriptor; 

    private function __construct(){ 
     /* connect and other stuff */ 
    } 
    public static function getInstance(){ 
     static $instance; 
     if($instance === null){ 
      $instance = new self(); 
     } 
     return $instance; 
    } 
} 

をそして、あなたがユーザーと同じ技術を使用することができ、私はあなたがシングルトンパターンを1つの形質を使用することができ、PHP 5.4でもっと言います。 最後のヒント:データベースやその他の重いものを扱うときは、lazy initializationというテクニックを使用してください。あなたのOOPスキルを向上させるときは、Doctrine Projectを見てください。彼らはそのテクニックをたくさん使っています!

+0

実際に、私は今、エンタープライズフレームワークの例を見て、物事がどのように行われているかを感じることを推奨します。すぐに使用する必要はないかもしれませんが、物事を構成する方法についての良い考えが得られます。 – prodigitalson

+0

アドバイスはありますか?私は以前彼らと一緒に仕事をしていませんでした。 – kirugan

+1

Symfony2とZend2 Frameworksは、見ていく価値のある唯一のフレームワークです:)私はこれについて多くの投票を受けることがわかります。しかし、この2つは、PHPで適切なOOPを学ぶのに最適です! – Limeni

2

コンストラクタやその他のメソッド内でオブジェクトをインスタンス化しないでください。パラメータとして、好ましくは工場と呼ばれる別のクラスの内部に渡します。これにより、コードのテストが簡単になりますが、オブジェクトの作成も簡単になります。

また、シングルトンを使用しないでください。これは "グローバル変数"のオブジェクト指向バージョンであり、グローバル変数を使用したくない場合です。これはあなたのコードのテストを本当に難しく、ほとんど不可能にします。

このビデオを見るhttp://www.youtube.com/watch?v=-FRm3VPhseIシングルトンを使用することが悪い理由を理解する。特に、19:00のクレジットカードの例は価値があります。

あなたが本当にそれを最先端のものにしたいのであれば、 "依存性注入"の概念を見てください。基本的には、外部から必要なものをクラスに渡すことは秘密ですが、自動的にこれを行うフレームワークがありますので、自分でファクトリを書き込む必要はありません。これらは「依存性注入コンテナ」または「DIC」と呼ばれます。

+0

ありがとう! Googleのファクトリクラスですウェブサイトのクラス構造を設定するための一般的なチュートリアルを知っていますか?私は原則を理解し始めましたが、現実的な実装では、まだ少し失われています。 – Ben

+0

まず、オートローディングをお勧めします。これを簡単にするシステムはいくつかありますが、ファイルごとに1つのクラスをディレクトリツリーに編成し、それに応じてクラス名を整列させることで、必要なクラス名だけをパラメータとして取得できるオートローダーが構築できますクラスが存在するはずのパスとファイル名です。生き生きした例として、Zend Framework(1または2)を見てください。あなたは、他の人がどのようにクラスに名前を付けたかについてのアイデアを得るかもしれません。 – Sven

関連する問題