Aspect 지향 프로그래밍 vs. 객체 지향 프로그래밍


199

이곳과 전세계의 대부분의 개발자와 마찬가지로, OOP (Object-Oriented Programming) 기술을 사용하여 수년 동안 소프트웨어 시스템을 개발해 왔습니다. 따라서 AOP (Aspect-Oriented Programming)는 기존 OOP가 완전히 또는 직접적으로 해결되지 않는 많은 문제를 해결한다는 사실을 읽습니다.

나는이 AOP 패러다임의 열쇠를 배우려고 노력하는 많은 정보를 읽었고 같은 장소에 있기 때문에 실제 응용 프로그램 개발에서의 이점을 더 잘 이해하고 싶었습니다.

누군가 대답이 있습니까?


7
모든 답변은 매우 좋았습니다. 이것은 하나의 커뮤니티 편집 답변에 대한 완벽한 사례입니다. 모두 같은 말을하지만 다른 방식으로 말하고 전체적인 가치를 더하는 다른 예를 사용합니다
Vinko Vrsalovic

답변:


323

왜 "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를 쉽게 남용하여 많은 문제를 일으킬 수 있다면 모두 사용하는 것은 나쁜 생각입니다. 그러나 어떤 기술을 남용 할 수 없습니까? 데이터 캡슐화를 남용하고 상속을 남용 할 수 있습니다. 거의 모든 유용한 프로그래밍 기술이 남용 될 수 있습니다. 남용 할 수없는 기능 만 포함하도록 프로그래밍 언어를 제한하십시오. 기능은 처음에 의도 된 대로만 사용할 수있는 언어입니다. 그러한 언어는 너무 제한되어서 실제 프로그래밍에 사용될 수 있다면 논쟁의 여지가 있습니다.


4
로깅은 AOP로 인해 거리에서 동작하지 않는 특정 예입니다. 현재 wikipedia는 보안 검사와 같은 측면을 사용하여 프로그램 흐름을 훨씬 더 이해하게 만드는 예제로 사용합니다.
kizzx2

7
@ kizzx2 : 실제로 로깅에 대한 요점-실제로 AOP에 대해 많이 알지 못하고 지금까지 AOP의 장점을 보았던 최고의 예입니다. 공유해 주셔서 감사합니다!
blunders

@Mecki, 귀하의 예는 지나치게 단순화되었으며 일반적인 사용 사례를 반영하지 않습니다. 귀하의 예에서는 Display.update인수를 취하지 않습니다. 인수를 전달해야하는 경우 (예 : 일반적으로 log함수에 message매개 변수 가 필요함 )? 그런 다음 AOP 방식으로 많은 상용구 코드를 추가해야합니까?
Pacerier 2016 년

3
@Pacerier SO는 강의 포럼이 아니기 때문에 제 예제가 단순화되었습니다. 나는 단지 질문자에 대한 질문에 대답하고 있었을 것입니다. AOP에 대해 더 알고 싶다면 프로그래머 문서를 읽고 자세한 질문이 있으면 여기에 물어 보지 않겠습니까? 아니오, 의견이 아니라 가서 새로운 질문을 만드십시오. 왜냐하면 그것이 SO의 전부 이기 때문 입니다 . 나는 누군가가 당신의 의심을 답장에서 풀 수있을 것이라고 확신합니다.
Mecki

2
@Pacerier 죄송 합니다만, 요점을 알 수 없습니다. 여기를 참조하십시오 : stackoverflow.com/a/8843713/15809 이 코드는 모든 메소드 인수 유형 및 값을 포함하여 모든 공용 메소드에 대한 모든 호출을 기록합니다. 이 코드를 정확히 한 번 작성하면 모든 메소드에 추가 된 상용구 코드가 없으며 응답에 표시된 코드 일뿐입니다.
Mecki

29

Aspect 지향 pogramming은 로깅, 보안과 같은 교차 문제를 구현하는 좋은 방법을 제공합니다. 이러한 크로스 커팅 문제는 여러 곳에 적용해야하지만 실제로 비즈니스 로직과 관련이없는 로직입니다.

AOP를 OOP의 대체물로 보아서는 안되며, 추가 기능이 뛰어나 코드가 더 깨끗하고 느슨하게 결합되어 비즈니스 로직에 집중됩니다. 따라서 AOP를 적용하면 2 가지 주요 이점이 있습니다.

  1. 각 관심사에 대한 논리는 이제 코드베이스 전체에 흩어져있는 것이 아니라 한 곳에 있습니다.

  2. 클래스는 주요 관심사 (또는 핵심 기능)에 대한 코드 만 포함하고 2 차 관심사는 측면으로 이동했기 때문에 더 깨끗합니다.


27

OOP와 AOP는 상호 배타적이지 않습니다. AOP는 OOP에 추가 될 수 있습니다. AOP는이 표준 코드로 메소드 코드를 막지 않고 로깅, 성능 추적 등과 같은 표준 코드를 메소드에 추가 할 때 특히 편리합니다.


10

나는 AOP가되지 않습니다이다 주목해야 할이 질문하지만, 한 가지에 대한 일반적인 응답이 없다고 생각 교체 OOP를 있지만 특정 분해를 추가합니다 해당 주소 소위 기능 지배적 인 성분의 폭정 ( 1 ) (또는 크로스 커팅 우려).

그것은 확실히 당신이 특정 프로젝트에 사용할 도구와 언어의 제어에있어만큼 어떤 경우에 도움이뿐만 아니라 측면의 상호 작용 등 추가 도구의 필요성에 대한 복잡성의 새로운 수준의 추가 AJDT 여전히 이해에를 당신의 프로그램.

Gregor Kiczales는 Google Tech Talks에서 AOP에 대한 흥미로운 입문 강연을 한 적이 있습니다. Aspect Oriented Programming : Radical Research in Modularity .


8

우선 AOP는 OOP를 대체하지 않습니다. AOP는 OOP를 확장합니다. OOP의 아이디어와 관행은 관련성을 유지합니다. 좋은 객체 디자인을 사용하면 측면으로 쉽게 확장 할 수 있습니다.

AOP가 제공하는 아이디어가 중요하다고 생각합니다. 우리는 클래스 자체를 변경하지 않고도 프로그램의 다른 클래스에 대해 교차 절단 문제를 구현할 수있는 방법을 찾아야합니다. 그러나 AOP는 결국 우리가 사용하는 다른 도구의 일부가 될 것이며 별도의 도구 나 기술이 아니라고 생각합니다. 우리는 이미 이런 일이 일어나는 것을 봅니다.

Ruby 및 Python과 같은 몇 가지 동적 언어에는 동일한 문제를 해결하는 믹스 인과 같은 언어 구성이 있습니다. 이것은 AOP와 비슷하지만 언어에 더 잘 통합됩니다.

Spring and Castle과 몇 가지 다른 의존성 주입 프레임 워크에는 주입하는 클래스에 동작을 추가하는 옵션이 있습니다. 이것은 런타임 위빙을 수행하는 방법이며 이것이 많은 잠재력을 가지고 있다고 생각합니다.

AOP를 사용하기 위해 완전히 새로운 패러다임을 배울 필요는 없다고 생각합니다. 아이디어는 흥미롭지 만 기존 도구와 언어에 서서히 흡수됩니다. 정보를 얻고 이러한 도구를 사용해보십시오.


1

AOP는이 개념을 다루는 새로운 프로그래밍 패러다임입니다. 양태는 애플리케이션의 특정 비 기능적 부분을 구현하는 소프트웨어 엔티티이다.

이 기사는 Aspect Oriented Programming으로 시작하기에 좋은 곳이라고 생각합니다 .


1

나는이 질문에 대해 늦게 늦었지만 가장 좋아하는 주제 중 하나이므로 내 견해를 공유 할 수 있습니다.

OOP 는 주로 비즈니스 로직 을 구성하는 데 사용되는 반면 AOP 는 감사, 로깅, 트랜잭션 관리, 보안 등과 같은 비 기능적인 항목 을 구성하는 데 도움이됩니다.

이러한 방식으로 비즈니스 로직을 코드를보다 깔끔하게 만드는 논픽션 로직과 분리 할 수 ​​있습니다.

수달의 장점은 비즈니스 로직을 건드리지 않고 수정을위한 뛰어난 유연성을 제공하는 인터페이스를 구현하지 않고도 조언 (예 : 감사)을 일관되게 적용 할 수 있다는 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.