Skip to content

Instantly share code, notes, and snippets.

@modeverv
Created September 12, 2020 13:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save modeverv/98b9787d2f753100270761f5ae861b6d to your computer and use it in GitHub Desktop.
Save modeverv/98b9787d2f753100270761f5ae861b6d to your computer and use it in GitHub Desktop.
// 1. PDPへの依頼とかPDPからの返却とか
// PDPに送る依頼とか返却値とか
class AuthorityResut<T : BaseBusinessLogic> (
val logic:Class<T>,
val limitation:String
) {
companion object {
// インスタンス取得処理はここに書く。
// ちょっと密結合かもしれません...
fun <E : BaseBusinessLogic> getInstance(authorityResult: AuthorityResut<E>/*,リクエスト*/): E {
val instance = authorityResult.logic.newInstance()
instance.logging(/*リクエスト*/)
instance.limitaion = authorityResult.limitation
return instance
}
}
}
// ----------------------------------
// 2. ベースのビジネスロジック
abstract class BaseBusinessLogic {
lateinit var limitaion:String
// ここにありがちなリソース制限は予め書いちゃうと良い
// 特有のリソース制限は個別のビジネスロジックにも書けば良い
// Javaで言うpublic static xxxx HOGE_HOGEはこうやって書く
companion object {
val ONRY_ME = "only me"
val IN_CLIENT = "in client"
val EVERYTHING = "everything"
}
fun logging(/*リクエスト*/){
println("リクエストを元にロギング処理")
}
abstract fun execute()
}
// ----------------------------------------------
// 3. とあるビジネスロジック
class ABussinesLogic :BaseBusinessLogic
{
constructor() {
println("ABussinesLogic初期化")
}
override fun execute() {
println(this.limitaion)
println("limitationに従って処理を行う")
}
}
// ----------------------------------------
// 4. PDP
class PDP {
companion object {
fun <T : BaseBusinessLogic>can(authority:AuthorityResut<T>):AuthorityResut<T>{
// PIP/PRPを使ってとても複雑な権限確認処理をここに書く
// セッションとか使う
// 権限チェックの結果制限が決まるし、何ならExceptionで終了する
authority.limitation = BaseBusinessLogic.ONRY_ME
return authority // 今はそのままかえすだけ
}
}
}
// ----------------------------------------
// 5.利用イメージ
// PDPに送る、PDPから帰ってくるのはAutyorityResut型
// 1操作 = 1ビジネスロジック(例: クライアントの編集で1ロジック)のイメージ
// DB周りなどのコードが重複してDRYじゃなくなるかもしれないが、その場合はAuthorityResultクラスに追加の属性を与えれば対応できそう
// まさにバランス感覚の世界
val authorityRequest = AuthorityResut(ABussinesLogic::class.java)
try {
// 駄目なときはcanが権限Exceptionを吐く
val authorityResult = PDP.can(authorityRequest)
// ビジネスロジックのインスタンスを取る、制限もセットされる、アクセスログのロギングも完了済み
val businessLogic = AuthorityResut.getBusinessLogicInstance(authorityResult/*,リクエスト*/)
// ビジネスロジックを動作させる
var result = businessLogic.execute()
// resultを返す
} catch(e: Exception/* TODO 権限Exceptionを作る*/){
// 権限エラーなので
// statuscode = 200, アプリステータス=権限エラーを返却する
} catch(e: RuntimeException/* TODO ロジックExceptionを作る*/) {
// ロジックのエラー = 不具合
// statuscode = 500
}
// 結果
/*
ABussinesLogic初期化
リクエストを元にロギング処理
only me
limitationに従って処理を行う
*/
// PEPとPDPを利用しつつ特定Businessロジックが動作するざっくりイメージが描けたと思う
// あとは定数クラスにAutyorityResult型の変数を羅列すれば良さそう値を持たせれば一元管理ができそう。
// いまきづいたけどOpenAPIのoperational-idの概念をAuthorityResultに混ぜるのを忘れている。だがこれは行けそうね。
// ちょっと密結合感があるかなーとは思うが、
// OPEN CLOSEDの原則的には沿っているかなと思う。
// ビジネスロジックを作成するときは単純に追記していけばよい。
// 良い感じと私の今の感想
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment