常に多くの場合、それぞれがこれらの繰り返し動作、管理の1つの以下の点を書き、繰り返し業務を持って日々の開発に冗長性を感じます。今日、私はこの問題の開発に遭遇したが、ダニエルのプロジェクトチームは良い運用管理を繰り返すように私を助けていたので、彼らは密かにこの---テンプレートのデザインモードを学び、それについて尋ねます。
テンプレートのデザインパターンは、次の点に注意してくださいするには:
-
テンプレートの抽出動作設定を複製。
-
マネージャー一元管理への実装クラステンプレートの実現。
-
唯一のビジネスマネージャーとの時間では、実装クラスのテンプレートを無視します。
後、我々は今日の戦闘フェイズを開始し、要点を把握し、プロジェクトが必要とする、これは次のとおりです。
-
(商品がログテーブルに対応する)まず、商品がログテーブルの特定のタイプを持って見つけ、そこに商品やログテーブルとの対応関係をテーブルログ
-
次に、ログテーブル内核注入情報(ログテーブルのフィールド)は、結果を返すかどうかを検証します。
-
このログ表8-10のベッド。
実際には、それを10回書き込み、需要が逃げるために再びそれをチェックするために、各テーブル特に簡単であるが、問題は、同じロジックのですか?あなたはより多くのテーブルを支払う場合は、だけでなく、それの主な流れのロジックを変更するには?それを行うには良い方法はありますか?
私たちは、テンプレート、テンプレートクラスの最初の解体の作業を複製下:
/ ** *アブストラクトテンプレートは、すべての処理ロジックはプロセッサを定義 * * @author fanpengyi * @version 1.0 * @date 2019年7月28日 * / パブリック 抽象 クラス AbstractTemplateProcessor <T> を実装 DataSupplier <T> 、InitializingBean { // 全て商品の種類 の専用セット<certtype> タイプ、 公共AbstractTemplateProcessor(){ この .typesの= getTypes(); } / ** *抽象テンプレート実行方法 * * @param 必要なパラメータ上paramListビジネスレイヤパス * @param項目の上にDタイプのビジネス層のパスタイプ金額 * / 公共のレスポンス<ボイド>プロセス(ParamList paramList、セット<certtype> 種類){ // 取得します。パラメータ T =電源供給(paramList); // プロセス決意 のIF ((サプライを受け入れます、タイプ)){ // 実際の実装プロセス 戻りdoProcess(paramList.getUseId()); } 戻り)Response.successを(; } / ** *あらかじめ決め行う判定処理法 * * @paramのprojectCode商品番号を * @ PARAM 種類の製品タイプ * @return * / 保護された 抽象 ブール(T projectCode、セット<certtype>受け入れるタイプを); / ** *処理方法の実際の実装 * * @param bizId * / 保護された 抽象レスポンス<ボイド> ; doProcess(BIZ文字列同上) / * * *各プロセッサの種類がサポート取得 * * @return * / パブリック 抽象セット<certtype> getTypes(); / ** *ポスト処理負荷クラス、プロセッサへのレジスタは、 * * @throws 例外 * / @Override 公衆 ボイド afterPropertiesSet()スロー例外{ TemplateProcessorMananger.getInstanceを()(登録。これを) } }
/ ** *パラメータを渡すために使用される抽象テンプレートに必要 * @author fanpengyi * @version 1.0 * @date 2019年7月28日 * / パブリック インターフェイス DataSupplier <T> { / ** *各プロセッサに応じて取得が必要paramList処理 * @param paramListパラメータリスト * @return * / T電源(paramList paramList); }
最終テンプレートクラスで見た、あなたは注意するマネージャのプロセッサ、管理ポイントが必要になります。
-
Managerは、単一の実施形態でなければなりません
-
Managerの操作は、スレッドの安全性を確保するためにロックする必要
/ ** *登録プロセス・マネージャ・プロセスおよびすべてのプロセスを実行するため * @author fanpengyi * @version 1.0 * @date 2019年7月28日 * / @NoArgsConstructor(アクセス = AccessLevel.PRIVATE) パブリック クラスTemplateProcessorMananger { / ** *静的参照、シングルトン * / @Getter プライベート 静的 TemplateProcessorManangerインスタンス= 新しい新TemplateProcessorMananger(); // レジストラ、均一な配置プロセス、もし順番ノート プライベートリスト<AbstractTemplateProcessor>プロセッサ= 新しい新しい LinkedListは<> (); プライベートロック= ReentrantReadWriteLock 新しい新しいReentrantReadWriteLock(); / ** *登録方法 * / パブリック 無効レジスタ(AbstractTemplateProcessorプロセッサ){ 試み{ // ロックはそれ以外の場合はエラーCopyOnWriteListはスレッドセーフであり、安全を確実にするためである (lock.writeLock()ロック。 ); processors.add(プロセッサ); } 最後に{ lock.writeLock()UNLOCK();. } } 公共の一覧<レスポンス<ボイド>>プロセス(paramList paramList、セット<certtype> 種類){ 試み{ // ロックプロセッサを動作させるときに、他のスレッドを読むことを許可されていません lock.readLock()ロック(); 戻りprocessors.stream() .MAP(O - >(レスポンス<ボイド> )o.process(paramList、タイプ)) .collect(Collectors.toList())。 } 最後に{ lock.readLock()(アンロック)。 } } }
それは訪問あたりの商品の同じタイプを保証するものではありませんので、上記以外のテンプレートクラスやマネージャーから、また、グローバルパラメータを定義し、各プロセッサの具体的な結果を保存し、同時アクセスする必要があるので、ここではThreadLocalをの形をしています各スレッドパラメータのセキュリティを確保するためにステップ移動によってステップ、及びグローバルパラメータを初期化し、インターセプタに実装さ破壊します。
/ ** *グローバル変数に似各スレッドプライベート変数を、各スレッドは、独自のコピーを持っている *インターセプターの初期化と破壊入れ、初期化、破壊があり、そうでない場合はメモリリークのリスクが存在します * * @author fanpengyi * @version 1.0 * @date 2019年7月28日 * / パブリック クラスDataHolder { プライベート 静的にThreadLocal <ParamList> THREADLOCAL; / ** * theadLocalを初期化 * / パブリック 静的な 無効スタート(){ IF(== THREADLOCAL NULL ){ THREADLOCAL = 新しい新しい THREADLOCAL <> (); } IF(threadLocal.get()== NULL ){ threadLocal.set(新しいParamList())。 } } パブリック 静的 ParamListのGET(){ 返すthreadLocal.get();} 公共の 静的な 無効更新(ParamList paramList){threadLocal.set(paramList);} 公共の 静的な 無効シャットダウンを(){ 場合(!THREADLOCAL = ヌル){ THREADLOCAL .remove()。 } } }
/ ** *インターセプタのThreadLocalを初期化し、破壊する >コントローラクラスの実行条件を実行- * @ConditionalOnClass(Controller.class) * @author fanpengyi * @version 1.0 * @date 2019年7月28日 * / @Configuration @ConditionalOnClass (コントローラ。クラス) パブリック クラス WebMvcConfig 実装WebMvcConfigurer { @Override 公共 ボイドaddInterceptors(InterceptorRegistryレジストリ){ registry.addInterceptor(新しい新しい(){からHandlerInterceptor @Override パブリック ブールpreHandle(HttpServletRequestのリクエスト、HttpServletResponseの応答、オブジェクト・ハンドラ)がスロー例外{ DataHolder.startを(); 返す 真; } @Override 公共 ボイド postHandle(HttpServletRequestのリクエスト、HttpServletResponseの応答、オブジェクトハンドラ、@NullableのModelAndViewのModelAndView)がスロー例外{ // の違いを無視不做处理 } @Override 公共 ボイド afterCompletion(HttpServletRequestのリクエスト、HttpServletResponseの応答、オブジェクトハンドラ、@Nullable例外EX )スロー例外{ DataHolder.shutdown(); } })。 } }
これらの3つのコアクラスでは、我々は最終的にマネージャーに登録され、互いに独立して、独自の方法を達成するために、各プロセッサ抽象テンプレート実装クラスを作成する必要があり、かつ、プロセス法上のビジネスメソッドのコールマネージャこれは、異なるプロセッサの製品タイプ別の呼び出し元の目的で行くことができます。
/ ** *ビジネスメソッド * / パブリック 無効doTemplate(){ // セットアップパラメータ ParamList paramList = 新新ParamList(); paramList.setUseId( "6666" ); セット <certtype> =設定新しい新しい HashSetのは、<> (); セット。追加(CertType.TYPE_3); sets.add(CertType.TYPE_1) 。TemplateProcessorMananger.getInstance()プロセス(paramList、セット); // 1つだけを実行するように期待のプロセッサ3 地図の<string、オブジェクト> = resultMaps DataHolderは。 GET()getResultMaps();. 用(S文字列:resultMaps.keySet()){ log.info(S + "------>" + resultMaps.get(S))。 } } }
テンプレートパターンのリピートビジネスオペレーションを使用する侵襲的な代替、統一された管理操作の利点は、小さな容易に拡張し、管理しやすいの主な流れの時に新しい任務を追加し、繰り返されます。
参考文献:
https://github.com/fanpengyi/template
----テキストコードのgitリポジトリ