私はあまり単体テストを行っていないことを認めます...しかし、私はしたいと思います。そうは言っても、ユニットテストを容易にするために最適化したい非常に複雑な登録プロセスがあります。将来、より簡単にテストできるように、クラスを構造化する方法を探しています。このロジックはすべて MVC フレームワーク内に含まれているため、コントローラーはすべてのインスタンスが作成されるルートであると想定できます。
簡単にするために、私が本質的に求めているのは、CRUD 更新を使用して任意の数のサードパーティ モジュールを管理できるシステムをセットアップする方法です。これらのサードパーティ モジュールはすべて RESTful API 駆動型であり、応答データはローカル コピーに保存されます。ユーザー アカウントの削除などは、関連するすべてのモジュール (私はプロバイダーと呼んでいます) の削除をトリガーする必要があります。これらのプロバイダーは別のプロバイダーに依存している可能性があるため、削除/作成の順序は重要です。アプリケーションをサポートするために具体的にどのデザイン パターンを使用する必要があるのかに興味があります。
登録は複数のクラスにまたがり、データを複数の db テーブルに格納します。さまざまなプロバイダーとメソッドの順序は次のとおりです (静的ではなく、簡潔にするためにそのように記述されています)。
Provider::create('external::create-user')
特定のプロバイダーの特定のステップで登録を開始します。最初のパラメーターの二重コロン構文は、クラスが で作成をトリガーする必要があることを示しますproviderClass::providerMethod
。メソッド、とProvider
のインターフェースになる一般的な仮定は、他のすべてのプロバイダーがそれを実装するというものでした。これがどのようにインスタンス化されるかは、おそらくあなたが私を助ける必要があるものです.create()
update()
delete()
$user = Provider_External::createUser()
外部 API でユーザーを作成し、成功を返し、ユーザーがデータベースに保存されます。$customer = Provider_Gapps_Customer::create($user)
サードパーティ API で顧客を作成し、成功を返し、ローカルに保存します。$subscription = Provider_Gapps_Subscription::create($customer)
サードパーティ API で以前に作成した顧客に関連付けられたサブスクリプションを作成し、成功を返し、ローカルに保存します。Provider_Gapps_Verification::get($customer, $subscription)
外部 API から行を取得します。この情報はローカルに保存されます。簡潔にするためにスキップする別の呼び出しが行われます。Provider_Gapps_Verification::verify($customer, $subscription)
外部 API 検証プロセスを実行します。その結果はローカルに保存されます。
実際のコードは、少なくとも 6 つの外部 API 呼び出しと、登録時に作成された 10 を超えるローカル データベース行に依存しているため、これは非常に単純なサンプルです。コンストラクター レベルで依存性注入を使用しても意味がありません。コントローラーで 6 つのクラスをインスタンス化する必要があり、そのすべてが必要かどうかさえわからないからです。私が達成しようとしているProvider::create('external')
のは、登録を開始するための開始ステップを指定するだけのようなものです。
問題の核心
ご覧のとおり、これは登録プロセスのほんの一例です。サインアップ、更新、削除などを行う必要がある数百のサービス プロバイダー (外部 API モジュール) を持つことができるシステムを構築しています。これらの各プロバイダーは、ユーザー アカウントに関連付けられます。
新規プロバイダー作成のトリガーとなる操作順序(ステップ)を指定できるようにシステムを構築したいと考えています。別の言い方をすれば、作成は非常に多くのステップにまたがることがあるため、一連のイベントで次にトリガーされるプロバイダー/メソッドの組み合わせを指定できるようにします。現在、この一連のイベントは、サブジェクト/オブザーバー パターンを介して発生しています。このコードをデータベース テーブル に移動する可能性を検討していますprovider_steps
。ここでは、各ステップをリストし、(ロールバックと削除の場合)success_step
およびfailure_step
(ロールバックと削除) を示します。テーブルは次のようになります。
# the id of the parent provider row
provider_id int(11) unsigned primary key,
# the short, slug name of the step for using in codebase
step_name varchar(60),
# the name of the method correlating to the step
method_name varchar(120),
# the steps that get triggered on success of this step
# can be comma delimited; multiple steps could be triggered in parallel
triggers_success varchar(255),
# the steps that get triggered on failure of this step
# can be comma delimited; multiple steps could be triggered in parallel
triggers_failure varchar(255),
created_at datetime,
updated_at datetime,
index ('provider_id', 'step_name')
ここで行う決定は非常に多くあります...継承よりも構成を優先し、いくつかのインターフェイスを作成する必要があることはわかっています。また、工場が必要になる可能性が高いことも知っています。最後に、私はここで多くのドメイン モデルのたわごとを行っているので、ビジネス ドメイン クラスが必要になる可能性があります。聖杯の追求において、完全な混乱を引き起こすことなく、それらをすべてメッシュ化する方法がわかりません.
また、データベースクエリを実行するのに最適な場所はどこですか?
各データベース テーブルのモデルは既にありますが、特定のモデル メソッドをインスタンス化する場所と方法を知りたいと思っています。