꼭 안드로이드일 필요는 없지만, AspectJ를 통해서 아키텍처 규칙 위반사항을 체크하는 예제를 공유합니다.

(제가 다니는 회사에서 적용 중인 애스팩트를 살짝 수정한 것입니다)


import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Pointcut;

import android.app.Activity;


/**

 * 아키텍처 규칙 위반을 체크하는 애스펙트.

 */

@Aspect

public class ArchitectureRuleCheckAspect {

    private static final String PREFIX = "[아키텍처 규칙위반]";


    //공통 액티비티(하위 액티비티)가 아닌 곳에 선언된 메소드 실행시

    @Pointcut("!within(com.mycompany.xxx.BaseActivity+) && execution(* *(..))")

    private void notInBaseActivity() {

    }


    @DeclareError("@annotation(com.mycompany.xxx.Click) && notInBaseActivity()")

    static final String useClickAnnotationOnlyInBaseActivity = "@Click 어노테이션은 BaseActivity 하위클래스의 메소드에만 적용할 수 있습니다.";


    @DeclareError("call((@com.google.inject.Singleton *).new(..))")

    static final String dontCreateSingletonDirectly = "@Singleton 클래스 인스턴스를 직접 생성하면 안됩니다. @Inject를 사용하세요.";


    @DeclareError("within(com.mycompany.xxx.Controller+) && call(com.mycompany.xxx.Controller+.new(..)) ")

    static final String dontUseAnotherControllerInControllers = PREFIX + "콘트롤러에서 다른 콘트롤러를 사용할 수 없습니다.";


    @DeclareError("call(* com.mycompany.xxx.Controller+.*(..)) && (within(*..*Action) || within(*..*Connector)) ")

    static final String useControllerOnlyInPresentationLayer = PREFIX + "콘트롤러는 프리젠테이션 레이어에서 사용해야합니다.";


    @DeclareError("within(*..*Connector) && call(* *.*Action.*(..)) ")

    static final String dontCallActionInConnectors = PREFIX + "커넥터 레이어에서는 비즈니스 레이어(액션)를 호출할 수 없습니다.";


    @DeclareError("call(* android.app.Activity+.*(..)) && (within(*..*Action) || within(*..*Connector)) ")

    static final String useActivityOnlyInPresentationLayer = PREFIX + "액티비티는 프리젠테이션 레이어에서 사용해야합니다.";


    @DeclareError("@annotation(com.mycompany.xxx.Rest) && !within(*..*Connector) ")

    static final String useRestAnnotationOnlyInConnectors = PREFIX + "@Rest 어노테이션은 커넥터 레이어에서만 사용할 수 있습니다.";


}


저의 경우 앱 개발시에 레이어 구조와 MVC 패턴을 적용한 아키텍처 표준을 정해놓고 개발합니다.

레이어 구조는 Presentation(Activity) -> Business(Action) -> Connector(Connector)가 되고, 

MVC패턴은 Presentation 레이어에 적용됩니다.


위 애스펙트 예제는 이러한  아키텍처 상에서 레이어간 역참조 및 MVC 담당 모듈을 엉뚱한 레이어에서 사용하는 것을 방지하고 있습니다.


아키텍처 표준뿐 아니라 자체 제작한 유틸리티 어노테이션을 올바른 곳에서 사용하고 있는지 체크하는 규칙을 포함하며, 

Injection에 의해 주입받아야할 컴포넌트를 직접 instance화하는지도 검사합니다.




Posted by 에코지오
,