1. ホーム
  2. design-patterns

[解決済み] PHPプロジェクトにおいて、ヘルパーオブジェクトを保存し、アクセスし、整理するためにどのようなパターンが存在するのでしょうか?[クローズド]

2022-09-27 01:05:26

質問

PHPベースのオブジェクト指向プロジェクトにおいて、データベースエンジン、ユーザー通知、エラー処理などのヘルパーオブジェクトをどのように整理し、管理するのでしょうか?

大規模なPHPのCMSを持っているとします。 CMSはさまざまなクラスで構成されています。いくつかの例を挙げます。

  • データベースオブジェクト
  • ユーザー管理
  • アイテムの作成/変更/削除のためのAPI
  • エンドユーザーへのメッセージを表示するためのメッセージングオブジェクト
  • 正しいページに移動するためのコンテキストハンドラ
  • ボタンを表示するナビゲーションバークラス
  • ロギング・オブジェクト
  • おそらく、カスタムエラー処理

などです。

私は、これらのオブジェクトを、それを必要とするシステムの各部分にアクセスできるようにするために、どのようにしたら最も良いかという永遠の問題に取り組んでいます。

何年も前の私の最初のアプローチは、これらのクラスの初期化されたインスタンスを含む$applicationグローバルを持つことでした。

global $application;
$application->messageHandler->addMessage("Item successfully inserted");

その後、Singletonパターンとファクトリー関数に変更しました。

$mh =&factory("messageHandler");
$mh->addMessage("Item successfully inserted");

が、これにも満足はしていません。ユニットテストとカプセル化は私にとってますます重要になり、私の理解では、グローバル/シングルトンの背後にあるロジックは、OOPの基本的なアイデアを破壊しています。

それから、もちろん、各オブジェクトに、それが必要とするヘルパーオブジェクトへのいくつかのポインターを与える可能性があります。おそらく、非常にクリーンで、リソースを節約し、テストに適した方法ですが、私は、長い目で見て、この保守性に疑問があります。

私が調べたほとんどのPHPフレームワークは、シングルトンパターンか、初期化されたオブジェクトにアクセスする関数のどちらかを使用します。どちらも素晴らしいアプローチですが、私が言ったように、私はどちらにも満足していません。

私は、ここにどのような共通のパターンが存在するかについて、私の視野を広げたいと思います。私は、例、追加的なアイデア、および、(代表的な) API からこれを議論するリソースへのポインターを探しています。

長期的 , 現実的 のような視点が必要です。

また、専門的な、ニッチな、あるいは 変なもの といったアプローチも聞いてみたいですね。

どのように解決するのですか?

Flaviusが提案したSingletonのアプローチは避けたいと思います。このアプローチを避ける理由は数多くあります。それは、優れた OOP の原則に違反しています。google testing blogには、Singletonとそれを回避する方法に関する良い記事がいくつかあります。

http://googletesting.blogspot.com/2008/08/by-miko-hevery-so-you-join-new-project.html http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html http://googletesting.blogspot.com/2008/08/where-have-all-singletons-gone.html

代替品

  1. サービス プロバイダ

    http://java.sun.com/blueprints/corej2eepatterns/Patterns/ServiceLocator.html

  2. 依存性注入

    http://en.wikipedia.org/wiki/Dependency_injection

    とphpの説明があります。

    http://components.symfony-project.org/dependency-injection/trunk/book/01-Dependency-Injection

これらの代替案について、良い記事です。

http://martinfowler.com/articles/injection.html

依存性注入(DI)を実装する。

Flaviusの解決策についてもう少し考えてみました。 この投稿をアンチ投稿にしたいわけではありませんが、依存性注入が、少なくとも私にとっては、グローバルよりも優れている理由を見ることが重要だと思います。

たとえそれが「真」の シングルトン の実装であるにもかかわらず、私はフラビウスが間違ったことをしたと思っています。 グローバルステートは悪い . なお、このような解決策では 静的メソッドのテストが難しい .

多くの人がそれを行い、承認し、使っていることは知っています。しかし、Misko Heverysのブログの記事を読むと( Googleのテスト容易性の専門家 )を読み、それを再読し、彼の言うことをゆっくりと消化することで、デザインの見方が大きく変わりました。

もしあなたがアプリケーションをテストできるようにしたいのであれば、アプリケーションを設計するために異なるアプローチを採用する必要があるでしょう。テストファーストのプログラミングをすると、次のようなことが難しくなります。次に、このコードの部分でロギングを実装したいと思います。基本的なメッセージをログに記録するテストを最初に書いてみましょう」そして、置き換えられないグローバルロガーを書いて使用することを強制するテストを考え出すのです。

私はまだ もがいている のブログから得たすべての情報で、必ずしも簡単に実装できるわけではなく、多くの疑問があります。しかし、Misko Heveryが言っていたことを把握した後、以前のように(そう、グローバルステートとシングルトン(大きなS))戻ることはできません :-)。