私のチームは現在、PHPで中規模アプリケーションの大規模なリファクタリングに取り組んでいます。モジュール(注文、ユーザー、製品)ベースでコードをリファクタリングするために最善を尽くしています。私が現在疑問に思っている問題は、ユーザーがシステムで実行できることの処理に関係しています。
現在、これは主にユーザーのシステムへのアクセスレベルに依存しています。時には、上位のグループが何かを行う(注文する)ことが許可されているかどうかを確認するために所有グループを参照し、その権限を推移的にユーザーに渡す必要がある場合があります。
これまでに思いついたのは「ガーディアン」というクラスです。 Guardianはユーザーを取り込み、「canPlaceOrder」や「canViewOrderReport」などの機能を持ちます。このアプローチの利点の1つは、アクセス許可を必要とするシステム上のすべてのアクションを1か所で確認できることです。さらに、これにより、許可ロジックをフロントエンドモデルおよびドメインモデルから分離できます。
ただし、これは完全にスケーラブルなソリューションではないことがわかりました。 OOP原則として、クラスは拡張のために開かれ、変更のために閉じられるべきであるという原則に従います。システムに権限を追加すると、Guardianクラスもメソッドを追加する必要があることがわかります。 。
1つのクラスを使用して人間が読める方法ですべてのアクセス許可を適切に定義することの利点が気に入っているので、正しい基準をチェックしていることが常にわかります。しかし、スケーラビリティが心配です。この問題に対する他のアプローチはありますか?
私の質問は本当に:これを処理する良い方法は何ですか?私の解決策は大丈夫ですか?
ガーディアンスホールドには
public boolean checkPermission(String permissionTag, int userID);
方法。
そうすれば、新しい権限が存在するようになったときに、保護者が変更する必要はありません。
使用法
if (guardian.checkPermission("PLACE_ORDER",loggedUser)) {
// place order
}
いくつかの良い方法があります。
常にファクトリを使用してGuardianを取得し、前のバージョンを継承するGuardianのサブタイプを返すことで、open-closedを実装できます。新しい機能は、最新のサブタイプにキャストできます。
メソッドを追加するだけで開閉を実装することもできます。そして、他人に触れないことを知っています。これは失敗する方が簡単ですが、はい、何をしているのかを知っている必要があります。残念ながら、彼らが何をしているのかを知らない開発者は、前述のメソッド(より一般的には、オープン/クローズを実装する方法として引用されています)を台無しにします。
「許可」ベースタイプのリストを作成することもできます。 Wireup/startupは、オブジェクトをリストに追加します。次に、継承されたアクセス許可を追加するだけです。クエリを実行するために、最新のコードはリストからそのサブタイプを検索し、それを呼び出すことができます。
たとえば.netでは、メソッドを作成することもできます(ここではphpが弱いですが、これもコンパイルしないでください)。 }
使用法:can_do_this = GetPermission()。NeedManagerApproval();
そして...他にも多くの方法があります。
はい、これはアスペクト/横断的関心事です。だが...
プロジェクトにAOPフレームワークを追加するのが悪い方法だと思います
あなたの解決策は大丈夫です。
セキュリティとアクセシビリティはシステムに広まっているため、権限が追加されたときにメソッドを追加する必要があります。
PHPプログラムでは、文字列を使用してパーミッションを識別しても問題ありません。とにかく実行時までコードが間違っていることがわからないためです。文字列も構成できます。
if ( guardian.checkPermissions(["PLACE_ORDER", "MODIFY_ORDER"]) ) {
// place a modified order
}
あなたのソリューションに関する私の懸念は、所有しているユーザー数とユーザーの離職率に応じて、ユーザー権限を維持するオーバーヘッドです。
新しいユーザーを取得するたびに、「canViewProduct」、「canViewOrders」、「canPlaceOrder」などの権限のスタック全体を追加する必要があります。
より大きな店では、これは通常、問題を2つに分割することで処理されます。
「ロール」を作成します。 「manager」、「retailCustomer」、「wholeSaleCustomer」、「badCreditCustomer」。
次に、これらのロールにアトミック権限を割り当てます。
新しいユーザーを取得したら、1つまたは2つの役割を割り当てるだけです。 「badCreditCustomers」を代金引換のみに制限する必要があると判断した場合は、その役割から「canOrderOnCredit」を削除するだけです。