8

私は現在、完全に手続き型PHPで書かれたかなり大きなアプリケーションを持っています。私はPHPの経験をさらに深め、オブジェクト指向の手法を使用してアプリケーションの大部分を再コーディングしたいと考えています。

OOPがコードの量を減らし、読みやすくするのに役立つ領域はたくさんあります。ただし、いくつか質問があります。

1) 1つのクラスが任意の数のオブジェクトの青写真として使用されることは私の理解ですが、1つのクラスは1つのオブジェクトのみを表し、複数のオブジェクトを表すことはありません。したがって、1つのクラスでプレーヤーを表すことはできますが、複数のプレーヤーを表すことはできません。

2)含めるクラスがかなりあるので、「ローダー」クラスを使用してそれらすべてを使用してロードしますか、それともアプリケーションのプログラムファイルでspl_autoload_register使用しますか?spl_autoload_register

編集:それで、私のオートローダーは、オートローディングを開始するためのインスタンスを作成するクラスになるのでしょうか、それとも、複数のファイルで同じコードを繰り返さないようにするために含める関数とspl_autoload_registerを含むphpファイルですか?

3)私のクラスのいくつかは他のクラスに依存しています。私はこれまでにこれに遭遇したことがないので、正直に答えを知りません。メインプログラムファイルにすべてのクラスを含めても、プレーヤークラスに機能する必要のあるクラスが含まれていない場合、メインプログラムにはプレーヤーが依存するクラスが含まれているため、プレーヤークラスは機能しますか?

編集: 1つのクラスがPlayerタイプのオブジェクトをインスタンス化し、Playerクラスがこのクラスに直接含まれていない場合でも、コントローラークラスにはPlayerクラスが含まれているため、引き続き機能ますか?

4)作成しているオブジェクトで作業する必要がある場合が複数あります。どうすればいいのかしら。たとえば、私のPlayerクラスでは、あるプレーヤーから別のプレーヤーに何かを送信する必要がある場合があります。それで、2人のPlayerをパラメーターとして受け取り、転送を行う静的メソッドをPlayerクラスに実装しますか、それとも他のことをしますか?

編集:わかりました。静的メソッドは避けてください。今、私は深刻な問題を抱えています。アプリケーションで複数回実行されるメソッドがありますが、静的メソッドとして実装することはできません。それらをインスタンスメソッドとして実装することになっていますか?たとえば、あるプレーヤーから別のプレーヤーに送信します。Playerオブジェクトを受け取り、そこに送信する、またはそこから送信するインスタンスメソッドを作成ます

5)クラスのどのインスタンスにも実際には属していないメソッドがたくさんあり、静的メソッドとしても適切ではありません。これらは、Commonまたは同様の静的メソッドとして独自のクラスで宣言する必要がありますか?この状況で実際に行われていることは何ですか?

編集:これらのメソッドは、使用されている特定のアプリケーションファイルに属しているのでしょうか、それとも独自の「functions.php」ファイルに保存されているのでしょうか。

6)名前空間の使用方法を学びたいのですが、自分のコードが他の人に使用されることはなく、自分のアプリケーションで他の人のコードを使用することもありません。名前空間は私のアプリケーションに不必要に追加されていますか、それとも名前空間の使用方法を学ぶのは良い考えですか?とにかく、1つのアプリケーションに1つの名前空間(アプリケーション名?)がありますか、それとも各クラスはそれ自体の名前空間に属しますか?

7)最後に、データベース接続用に1つのクラスがあり、ネットワークメソッド用に1つのクラスがあるのが一般的ですか?私のアプリケーションには両方が必要です。オブジェクト指向技術を使用するようにコードを変換する際に私が抱えている主な問題は、現在、すべてが1つのモノリシックファイルにあるため、どのメソッドをどこに配置するかを決定することだと思います。

あなたが提供できるどんな助けと洞察にも感謝します。

4

3 に答える 3

4

1)1つのクラスが任意の数のオブジェクトの青写真として使用されることは私の理解ですが、1つのクラスは1つのオブジェクトのみを表し、複数のオブジェクトを表すことはありません。したがって、1つのクラスでプレーヤーを表すことはできますが、複数のプレーヤーを表すことはできません。

クラスは何も表していません。正しく述べたように、クラスは任意の数のオブジェクトの青写真にすぎないからです。複数のプレーヤーを表す同じクラスの複数のインスタンス(オブジェクト)を持つことができます。

2)含めるクラスはかなり多いので、「ローダー」クラスを使用して、spl_autoload_registerを使用してすべてをロードしますか、それともアプリケーションのプログラムファイルでspl_autoload_registerを使用しますか?

「私のアプリケーションのプログラムファイル」が何を意味するのかわからなくても、私はそう言います。オートローダーを使用してください。オートローダーは機能するだけで、心配する必要はありませんrequire_*

3)私のクラスのいくつかは他のクラスに依存しています。私はこれまでにこれに遭遇したことがないので、正直に答えを知りません。メインプログラムファイルにすべてのクラスを含めても、プレーヤークラスに機能する必要のあるクラスが含まれていない場合、メインプログラムにはプレーヤーが依存するクラスが含まれているため、プレーヤークラスは機能しますか?

すべてのクラスをロードするのではなく、使用するクラスのみをロードします。これも、オートローダーを使用するときに心配する必要はありません。ただし、クラスがロードされると、アプリケーション全体でインスタンス化できます。

通常は、アプリケーションのブートストラップフェーズでautploaderを起動する必要があります。

4)作成しているオブジェクトで作業する必要がある場合が複数あります。どうすればいいのかしら。たとえば、私のPlayerクラスでは、あるプレーヤーから別のプレーヤーに何かを送信する必要がある場合があります。それで、2人のPlayerをパラメーターとして受け取り、転送を行う静的メソッドをPlayerクラスに実装しますか、それとも他のことをしますか?

OOPPHPで静的メソッドを使用することは避けてください。ほとんど必要ありません。あるプレーヤーから別のプレーヤーへの「データの送信」を処理するプレーヤーのプールのように機能する別のクラスを用意することを考えることができます。

したがって、インスタンス化を試みる前に発生する限り、クラスを含むファイルがどこに含まれているかは関係ありません。

5)クラスのどのインスタンスにも実際には属していないメソッドがたくさんあり、静的メソッドとしても適切ではありません。これらは、Commonまたは同様の静的メソッドとして独自のクラスで宣言する必要がありますか?この状況で実際に行われていることは何ですか?

繰り返しますが、静的メソッドは使用しないでください。他のクラス内でそれらを使用する場合、クラスの単体テストを困難にするだけであり、隠れた依存関係が導入されます。私の経験では、何かのためにどこかに単一のメソッドがあることはほとんどありません。おそらく、あなたはメソッドがやりすぎだと思います。

しかし、それはあなたの質問を読むだけではわかりません。たぶんあなたはコメントで例をあげることができますか?

6)名前空間の使用方法を学びたいのですが、自分のコードが他の人に使用されることはなく、自分のアプリケーションで他の人のコードを使用することもありません。名前空間は私のアプリケーションに不必要に追加されていますか、それとも名前空間の使用方法を学ぶのは良い考えですか?

PHPの名前空間は、構造化に関するものです。他の誰もあなたのコードを使用することはありませんが、どこかのクラスに同じ名前を使用することを心配する必要はありません。これは、アプリケーションが大きくなると、後で発生します。

とにかく、1つのアプリケーションに1つの名前空間(アプリケーション名?)がありますか、それとも各クラスはそれ自体の名前空間に属しますか?

名前空間に関しては、PSR-0をよくフォローします。

7)最後に、データベース接続用に1つのクラスがあり、ネットワークメソッド用に1つのクラスがあるのが一般的ですか?私のアプリケーションには両方が必要です。オブジェクト指向技術を使用するようにコードを変換する際に私が抱えている主な問題は、現在、すべてが1つのモノリシックファイルにあるため、どのメソッドをどこに配置するかを決定することだと思います。

単一責任の原則を念頭に置き、一般的にはSOLIDを念頭に置いてください。

また、これらを見て、理解するまで見続けることを強くお勧めします。

于 2013-03-14T22:30:53.173 に答える
2

1)1つのクラスが任意の数のオブジェクトの青写真として使用されることは私の理解ですが、1つのクラスは1つのオブジェクトのみを表し、複数のオブジェクトを表すことはありません。したがって、1つのクラスでプレーヤーを表すことはできますが、複数のプレーヤーを表すことはできません。

通常、オブジェクトのコレクションを表すクラスもあります。たとえば、すべてのプレーヤーのコレクションから1人のプレーヤーを取得するために使用できるクラス「Players」です。

$players = new Players();
$john = $players->findByName("john");

2)含めるクラスはかなり多いので、「ローダー」クラスを使用して、spl_autoload_registerを使用してすべてをロードしますか、それともアプリケーションのプログラムファイルでspl_autoload_registerを使用しますか?

これは、プロジェクトの複雑さに大きく依存します。通常は単純なオートローダー関数で十分ですが、ZendFrameworkAutoloaderクラスを確認することもできます。

3)私のクラスのいくつかは他のクラスに依存しています。私はこれまでにこれに遭遇したことがないので、正直に答えを知りません。メインプログラムファイルにすべてのクラスを含めても、プレーヤークラスに機能する必要のあるクラスが含まれていない場合、メインプログラムにはプレーヤーが依存するクラスが含まれているため、プレーヤークラスは機能しますか?

はい。ただし、自動読み込みを使用すると、これについてまったく心配する必要はありません。自動読み込みを使用しない場合は、クラスを定義するファイルに必要なクラスを含めることをお勧めします(require_once()同じファイルを複数回含めないようにするために使用します)。

4)作成しているオブジェクトで作業する必要がある場合が複数あります。どうすればいいのかしら。たとえば、私のPlayerクラスでは、あるプレーヤーから別のプレーヤーに何かを送信する必要がある場合があります。それで、2人のPlayerをパラメーターとして受け取り、転送を行う静的メソッドをPlayerクラスに実装しますか、それとも他のことをしますか?

静的メソッドは、ほとんどの場合、間違ったアプローチです。通常のメソッドはインスタンス(つまり特定のプレーヤー)に属し、静的メソッドはクラス、つまりプレーヤーの一般的な「アイデア」に属します。あるプレーヤーから別のプレーヤーにデータを転送する必要がある場合は、次のように実装してみませんか。

class Player {
    public function transferMoney(Player $recipient, $amount) { ... }
}

$tom = new Player("tom");
$marc = new Player("marc");

$tom->transferMoney($marc, 500);

5)クラスのどのインスタンスにも実際には属していないメソッドがたくさんあり、静的メソッドとしても適切ではありません。これらは、Commonまたは同様の静的メソッドとして独自のクラスで宣言する必要がありますか?この状況で実際に行われていることは何ですか?

私はこれに合理的に答えることができません。ただし、PHPには、このような場合に最適な方法と思われる単純な関数がまだあります。ただし、OOPを正しく実行すれば、このような問題が発生することはほとんどありません。これは通常、クラスの設計に問題があり、これらのメソッドがどのオブジェクトにも属していないことになります。

6)名前空間の使用方法を学びたいのですが、自分のコードが他の人に使用されることはなく、自分のアプリケーションで他の人のコードを使用することもありません。名前空間は私のアプリケーションに不必要に追加されていますか、それとも名前空間の使用方法を学ぶのは良い考えですか?とにかく、1つのアプリケーションに1つの名前空間(アプリケーション名?)がありますか、それとも各クラスはそれ自体の名前空間に属しますか?

名前空間は素晴らしいですが、名前空間がなくてもコードはおそらく問題なく動作します。名前空間はネストできるため、通常は最上位の名前空間があり、コンポーネントごとにサブ名前空間が設定されます。

7)最後に、データベース接続用に1つのクラスがあり、ネットワークメソッド用に1つのクラスがあるのが一般的ですか?私のアプリケーションには両方が必要です。オブジェクト指向技術を使用するようにコードを変換する際に私が抱えている主な問題は、現在、すべてが1つのモノリシックファイルにあるため、どのメソッドをどこに配置するかを決定することだと思います。

これは、実際の状況をどのようにモデル化するかによって異なります。データベース接続と「ネットワーク」が2つの異なるものである場合は、2つのクラスが最適です。

于 2013-03-14T22:33:08.700 に答える
1
  1. APlayerCollectionは有効なクラスになります。もちろん、その目的は複数のプレーヤーの1つのコレクションです。

  2. spl_autoload_register、periodを使用します。PSR-0標準に準拠し、PSR-0準拠の既存のオートローダー(つまりSymfonyローダー)を使用するのが最適です。

  3. それが動作します。ただし、オートローダー(2を参照)を使用しているため、クラスを含める必要はまったくありません。

  4. プレーヤー1からプレーヤー2にメッセージを送信することは、プレーヤー1でプレーヤー2のメソッドを呼び出すことで簡単に変換されます。ただし、「物を送る」と「オブジェクトで作業する」は多くのことを意味する可能性があるため、答えは次のとおりです。ただし、一般的には静的メソッドを避けることをお勧めします。

  5. これは手続き的思考によく似ています。申し訳ありませんが、ここで特効薬の答えを出すことはできません。それらを適用するには、オブジェクト指向設計の原則を学び、理解する必要があります。Webには、いくつかの標準的な文献と多くの有用なリソースがあります。また、例による学習も役立つ場合があります(オープンソースである他のOOアプリケーションとフレームワークを見てください)

  6. 「1つのアプリケーションに1つの名前空間(アプリケーション名?)がありますか、それとも各クラスが独自の名前空間に属していますか?」-答えはその中間です。名前空間は、一緒に機能するものをグループ化するのに役立ち、誰がコードを使用または表示するかに関係なく役立ちます。

  7. オブジェクト指向設計の最初のルール:1つのクラス、1つの責任。

于 2013-03-14T22:31:54.267 に答える