왜 "vs"? "vs"가 아닙니다. Aspect Oriented 프로그래밍은 기능 프로그래밍과 함께 사용할 수 있지만 Object Oriented 프로그래밍과 함께 사용할 수도 있습니다. "vs"가 아니라 " Object Oriented Programming을 사용한 Aspect 지향 프로그래밍"입니다.
나에게 AOP는 일종의 "메타 프로그래밍"이다. 코드를 추가하기 만하면 AOP가 수행하는 모든 작업을 수행 할 수 있습니다. AOP는이 코드를 작성하는 것을 막아줍니다.
Wikipedia에는이 메타 프로그래밍에 대한 가장 좋은 예 중 하나가 있습니다. 많은 "set ... ()"메소드가있는 그래픽 클래스가 있다고 가정하십시오. 각 설정 방법 후에 그래픽의 데이터가 변경되어 그래픽이 변경되어 그래픽을 화면에서 업데이트해야합니다. 그래픽을 다시 페인트한다고 가정하면 "Display.update ()"를 호출해야합니다. 고전적인 접근 방식은 더 많은 코드 를 추가하여이 문제를 해결하는 것입니다 . 각 set 메소드의 끝에서
void set...(...) {
:
:
Display.update();
}
세 가지 set-methods가 있으면 문제가되지 않습니다. 200 (가설)을 가지고 있다면 어디서나 이것을 추가하는 것이 정말 고통 스럽습니다. 또한 새로운 set-method를 추가 할 때마다이를 마지막에 추가하는 것을 잊지 않아야합니다. 그렇지 않으면 방금 버그를 생성 한 것입니다.
AOP는 많은 양의 코드를 추가하지 않고이 문제를 해결하고 대신 측면을 추가합니다.
after() : set() {
Display.update();
}
그리고 그게 다야! 업데이트 코드를 직접 작성하는 대신 set () pointcut에 도달 한 후에는이 코드를 실행해야하며이 코드를 실행한다고 시스템에 알려 주면됩니다. 200 개의 메소드를 업데이트 할 필요가 없으며 새로운 set-method에이 코드를 추가하는 것을 잊지 않아도됩니다. 또한 포인트 컷이 필요합니다.
pointcut set() : execution(* set*(*) ) && this(MyGraphicsClass) && within(com.company.*);
그게 무슨 뜻이야? 에 관계없이 메소드가 리턴 (첫번째 별표) 또는 무슨 일이 걸리는 (제 3 별표) 어떤 매개 변수의 방법의 이름은 경우 의미 "세트를 *"(모든 이름을 설정 한 후 수행 할 수 * 수단) 과 는 MyGraphicsClass의 방법 및 이 class는 "com.company. *"패키지의 일부이며, set () 포인트 컷입니다. 그리고 우리의 첫 번째 코드는 "말한다 후 세트 포인트 컷있는 모든 방법을 실행, 다음 코드를 실행합니다."
여기서 AOP가 어떻게 문제를 우아하게 해결하는지보십시오. 실제로 여기에 설명 된 모든 것은 컴파일 타임에 수행 될 수 있습니다. AOP 전처리 기는 클래스 자체를 컴파일하기 전에 소스를 수정할 수 있습니다 (예 : 모든 set-pointcut 메서드 끝에 Display.update () 추가).
그러나이 예는 AOP의 큰 단점 중 하나도 보여줍니다. AOP는 실제로 많은 프로그래머들이 " 안티 패턴 " 이라고 생각하는 것을하고 있습니다. 정확한 패턴을 " 원거리에서의 동작 "이라고합니다.
먼 거리에서의 행동은 프로그램의 한 부분에서의 행동이 프로그램의 다른 부분에서의 작동을 식별하기 어렵거나 불가능한 것에 따라 크게 변하는 반 패턴 (인식 된 일반적인 오류)입니다.
프로젝트의 초보자로서 디스플레이 메소드를 업데이트하지 않는 것처럼 모든 set-method의 코드를 읽고 깨진 것으로 간주 할 수 있습니다. 나는하지 않는 참조 그냥이 실행 된 후, 다른 코드가 "마술"디스플레이를 업데이트하기 위해 실행됩니다, 세트 - 메소드의 코드를보고. 나는 이것이 심각한 단점이라고 생각합니다! 메소드를 변경하면 이상한 버그가 발생할 수 있습니다. 특정 것들이 올바르게 작동하는 것처럼 보이지만 명확하지 않은 코드 흐름을 이해하는 것은 어렵습니다 (내가 말했듯이 마술처럼 작동합니다 ...).
최신 정보
명확히하기 위해 : 일부 사람들은 내가 AOP가 나쁘다는 말과 같은 인상을 가질 수 있습니다. 그것은 내가 말하는 것이 아닙니다! AOP는 실제로 훌륭한 기능입니다. 난 그냥 "주의해서 사용"이라고 말합니다. AOP는 동일한 Aspect에 대해 일반 코드와 AOP를 혼합 한 경우에만 문제를 일으 킵니다 . 위의 예에서는 그래픽 객체의 값을 업데이트하고 업데이트 된 객체를 페인팅하는 측면이 있습니다. 그것은 실제로 단일 측면입니다. 절반을 일반 코드로 코딩하고 나머지 절반을 측면으로 코딩하면 문제가 발생합니다.
로깅과 같이 완전히 다른 측면에 대해 AOP를 사용하는 경우 안티 패턴 문제가 발생하지 않습니다. 이 경우 프로젝트의 초보자는 "이 로그 메시지는 어디에서 왔습니까? 코드에 로그 출력이 표시되지 않습니다"라고 궁금해 할 수 있지만 큰 문제는 아닙니다. 그가 프로그램 논리를 변경하면 로그 기능이 거의 손상되지 않으며 로그 기능이 변경되면 그의 프로그램 논리가 거의 손상되지 않습니다. 이러한 측면은 완전히 분리되어 있습니다. 로깅에 AOP를 사용하면 프로그램 코드가 수행해야 할 작업에 전적으로 집중할 수 있으며, 수백 개의 로그 메시지로 코드를 복잡하게 만들지 않고도 정교한 로깅을 수행 할 수 있다는 이점이 있습니다. 또한 새 코드가 도입되면 올바른 내용의 올바른 메시지가 적시에 표시됩니다.
따라서 예제에서 AOP를 잘 사용하면 set 메소드를 통해 값이 업데이트 된 경우 항상 기록하는 것입니다. 이것은 안티 패턴을 만들지 않으며 문제의 원인이 될 수 없습니다.
AOP를 쉽게 남용하여 많은 문제를 일으킬 수 있다면 모두 사용하는 것은 나쁜 생각입니다. 그러나 어떤 기술을 남용 할 수 없습니까? 데이터 캡슐화를 남용하고 상속을 남용 할 수 있습니다. 거의 모든 유용한 프로그래밍 기술이 남용 될 수 있습니다. 남용 할 수없는 기능 만 포함하도록 프로그래밍 언어를 제한하십시오. 기능은 처음에 의도 된 대로만 사용할 수있는 언어입니다. 그러한 언어는 너무 제한되어서 실제 프로그래밍에 사용될 수 있다면 논쟁의 여지가 있습니다.