5

このコードに出くわしたとき、私はブログ投稿を読んでいました:

<?php
include_once 'config.php';
class User
{
//Database connect 
public function __construct() 
{
$db = new DB_Class();
}

コメントで、誰かが次のように投稿しました。

コンストラクターでデータベース接続を開始しないでください

しかし、すべてのコメント ウォリアーと同様に、彼らは決して理由を述べません。なぜこれが間違っているか、または悪い習慣なのですか?

4

4 に答える 4

8

コンストラクターは実際の作業を行うべきではありません:

コラボレーターの作成/初期化、他のサービスとの通信、独自の状態を設定するロジックなどのコンストラクターでの作業は、テストに必要なシームを削除し、サブクラス/モックに不要な動作を強制的に継承させます。コンストラクターでの作業が多すぎると、テストでのインスタンス化やコラボレーターの変更が妨げられます。

代わりに、依存性注入を使用して、コラボレーターをコンストラクターに渡します。これにより、テストしやすいコードが作成されます。ctor で何かを行う場合、 Test Doublenewを使用してそれをモック/スタブするのははるかに困難です。

また、コラボレーターを注入することで、コラボレーターをさまざまな実装に簡単に交換できるようになるため、結合が減り、コードの再利用が促進され、具体的な実装ではなくインターフェイスに向けてコーディングされます。

于 2013-01-03T12:09:27.440 に答える
1

「依存性注入」と呼ばれるコンストラクターにデータベースのインスタンスを渡します。これは、オブジェクトの分離、つまりオブジェクト間の依存関係を下げるために行われます。デカップリングの利点の 1 つは、システムの柔軟性の向上、保守の容易さ、単体テストの作成です。

ただし、主に、設計パターンを使用してソフトウェアを構築し、テスト駆動開発を実践し、明確に定義されたアーキテクチャ (たとえば、ドメイン駆動設計で実践されている) を使用する場合、これらすべての利点を享受できます。

しかし、ソフトウェア開発の OOP の方法を探求し始めたばかり、またはプログラミング全般を学び始めたばかりの場合は、まだこの種の質問に悩まされるべきではないかもしれません。

于 2013-01-03T12:16:33.837 に答える
0

この特殊なケース、おそらくユーザーデータを操作するためのモデルでは、非常に便利です。しかし、突然このクラスを移植可能にして別のデータベースで動作させたい場合はどうでしょうか。別のプロジェクトでユーザーマネージャークラスを使用したいときに、これに遭遇しました。

于 2013-01-03T12:13:20.823 に答える
0

コンストラクターで DB 接続を初期化することは、コンストラクターの一般的な契約に違反していると私は主張します。new User()ユーザーを説明するオブジェクトを取得することを期待するとき。これが有効なデータベース接続を必要とする場合、接続の確立に失敗した場合、オブジェクトの状態はどうなりますか? コンストラクターは、適切なオブジェクトの状態を確保することが唯一の目的であるため、例外をスローするべきではありません。(少なくともそれが私の見解です...他の人がコンストラクタからの例外が悪いとは思わないことは知っています.しかし、私はそうします。)

さらに、オブジェクト内にカプセル化されている場合、データベース接続を再利用することはできません。

于 2013-01-03T12:10:22.237 に答える