プログラミングパターン-観点ガイド(AOP)


注意事項!


学習と執筆の文章.間違った内容や不実な説明があれば教えてください.😁

概要


「計算において、観点に向けたプログラミング(Asspect-oriented Programming)は、横方向の注目点の分離を許容することによってモジュール性を高めるプログラミングモードである」
オブジェクト向けの設計に十分に従っても,複数のクラスに共通の機能が分散して存在する可能性があり,これらの分散した共通の機能を注目点と呼ぶ.これらの懸念点をモジュール化し、必要に応じて使用する場所に接続することで、メンテナンスまたは再使用性をさらに向上させます.そして、OOPをもっとOOPに補充するのがAOPです.

上図に示すブロックのうち、オレンジ色、青、赤のブロックが探査ブロックである.

用語


AOPで使用される複数の用語の意味は以下の通りである.
  • Aspect
    これは
  • の複数の場所で使用されているコードをモジュール化したものである.
  • Target
  • は、どこに適用されるかを評価します.
  • Advice
  • 計画における実際の機能の実施体.
  • Join point
  • Adviceがターゲットに適用されるタイミング.(アクセスメソッド、呼び出しジェネレータ等)
  • Point Cut
  • Join Pointの詳細仕様を定義します.

  • AOPの前と後の最も有名な例を使用します.オブジェクトを実行し、実行に要する時間の例を出力します.

    AOPを適用する前に

    public interface EventService {
    	public void created();
        public void operation();
        public void deleted();
    }
    @Component
    public class SimpleServiceEvent implements EventService{
    
    	@override
    	public void created(){
        	long begin = System.currentTimeMillis();
            try{
            	Thread.sleep(1000);
            } catch (Exception ex) {
            	ex.printStackTrace();
            }
        System.out.println("Created");
        System.out.println(System.currentTimeMillis() - begin);
        
        }
        
        @override
    	public void operation(){
        	long begin = System.currentTimeMillis();
            try{
            	Thread.sleep(2000);
            } catch (Exception ex) {
            	ex.printStackTrace();
            }
        System.out.println("Operation");        
        System.out.println(System.currentTimeMillis() - begin);
        
        }
        
        @override
        public void deleted(){
        	long begin = System.currentTimeMillis();
            try{
            	Thread.sleep(3000);
            } catch (Exception ex) {
            	ex.printStackTrace();
            }
        System.out.println("Delete");
        System.out.println(System.currentTimeMillis() - begin);
        
        }
    EventServiceインタフェースが作成され、インプリメンテーションが作成されました.各メソッドは、実行に要する時間を出力します.
    次に、クラスを使用するコードを生成します.
    @Component
    public class AppRunner implements ApplicationRunner {
    	
        @Autowired
        EventService eventService;
        
        @Override
        public void run(ApplicationArguments args) throws Exception{
        	eventService.create();
            eventService.operation();
            eventService.delete();
        }
    }
    上記のコードを実行すると、次のような出力が得られます.
    Created
    1006
    Operation
    2008
    Delete
    3011
    オブジェクト向けの設計方式を十分に守っているが,以下の実行時間を記録するコードは多くの場所で重複していることが分かった.この例では、10行以内の単純なコードですが、検証、記録、セキュリティのコードが重複すると、コードは非常に長くなり、メソッドが変更されると、修正作業も非常に困難になります.
    繰り返しコード
    long begin = System.currentTimeMillis();
    ...
    System.out.println(System.currentTimeMillis() - begin;
    次に、Asspectを使用してAOPでこのコードを改善します.

    AOP適用後

    @Component
    @Aspect //Aspect 정의
    public class PerfAspect {
      @Around("execution(* com.example..*.EventService.*(..))") // 해당 패키지에 적용
      // Advice 정의 (*Around -> 메서드 실행 전, 후 실행)
      public Object logPerf(ProceedingJoinPoint pjp) throws Throwable {
        long begin = System.currentTimeMillis(); // 메소드 실행 전에 작동
        Object retVal = pjp.proceed(); // proceed() -> 메소드 실행 *Around 사용 시 반드시 있어야 함.
        System.out.println(System.currentTimeMillis() - begin); //메소드 실행 후 작동
        return retVal;
      }
    }
    上記の側面を定義し、重複するコードを消去すると、次のコードが生成されます.
    @Component
    public class SimpleServiceEvent implements EventService{
    
    	@override
    	public void created(){
            try{
            	Thread.sleep(1000);
            } catch (Exception ex) {
            	ex.printStackTrace();
            }
        System.out.println("Created");
        
        }
        
        @override
    	public void operation(){
            try{
            	Thread.sleep(2000);
            } catch (Exception ex) {
            	ex.printStackTrace();
            }
        System.out.println("Operation");        
        
        }
        
        @override
        public void deleted(){
            try{
            	Thread.sleep(3000);
            } catch (Exception ex) {
            	ex.printStackTrace();
            }
        System.out.println("Delete");
        
        }
    AppRunnerを再実行すると、同じ結果が得られます.

    使用方法



    Asspectを生成する過程で、初めて見た文法があるはずで、初めて見た@Aroundはadvicesです.方法は何を意味し、いつするか.ここの「何」はlogPerf()メソッドです.
    「いつ」は@Around、「いつ」は5種類あります.
    時点説明@Beforeメソッドは、メソッドの結果にかかわらず、呼び出しの前に機能を実行し、メソッドが完了すると、呼び出しの前に@Aroundメソッドを実行し、呼び出し後に機能を実行したときに結果を正常に返すと、@AfterThrowingメソッドを実行するときに異常が放出されます.
    青い箱の"execution(* com.blogcode.board.BoardService.getBoards(..))"はアデビスの価値です.この文字列はポイントカット式と呼ばれ、ポイントカット式は指定子、ターゲットリストの2種類に分けられ、9種類ありますが、最もよく使われるのはAnnotationとExecution方式です.
    指定子説明実行()アクセス制限子、戻りタイプ、パラメータタイプ、クラス/インタフェース、メソッド名、パラメータタイプ、例外タイプなど、特定の構文を組み合わせ可能な指定子@annotationターゲットメソッドに指定します.

    効果


    AOPを適用することで、重複コードをクリアすることができます.また、各関数の機能に加えて、実行時間の測定も担当します.これにより、単一の責任原則に違反するコードをより簡潔にし、自分の役割に集中することができます.

    ソース


    https://jojoldu.tistory.com/71?category=635883