-
AOP vs OOP 차이점Spring 2024. 9. 12. 17:10728x90반응형
1. AOP의 목적: 횡단 관심사 분리
- AOP는 로깅, 보안, 트랜잭션 관리와 같은 공통 기능을 비즈니스 로직과 분리하기 위해 존재합니다. 만약 비즈니스 로직 안에서 AOP를 사용하게 된다면, 결국 AOP의 주요 이점 중 하나인 비즈니스 로직과 횡단 관심사 간의 분리가 무너지게 됩니다.
- 예를 들어, 메서드 안에 로깅이나 트랜잭션 관리 코드를 직접 작성하는 것은 기존 방식의 절차적 프로그래밍으로 돌아가는 것과 같습니다.
2. 비즈니스 로직 내에서는 이미 구체적인 작업이 수행됨
- 비즈니스 로직 내에서는 특정한 작업(예: 결제 처리, 데이터 계산)이 수행되고 있습니다. AOP는 이 작업에 직접적으로 개입하는 것이 아니라, 이 작업 전후 혹은 에러 발생 시점에서 개입해야 합니다.
- 비즈니스 로직 안에 Advice나 Pointcut을 직접 포함하는 것은, AOP의 역할인 비즈니스 로직과 공통 관심사 간의 분리를 손상시키고, 코드 복잡도를 증가시킬 수 있습니다.
3. AOP는 주로 프레임워크에서 관리
- AOP는 스프링이나 AspectJ 같은 프레임워크에서 Aspect, Advice, Pointcut을 정의하고, 런타임이나 컴파일 시점에서 비즈니스 로직과 분리된 상태로 적용됩니다. 즉, AOP는 비즈니스 로직 외부에서 관리되는 것이 일반적입니다.
- 이러한 구조 덕분에 비즈니스 로직은 주요 기능에만 집중할 수 있으며, 반복적인 공통 관심사는 프레임워크가 자동으로 처리합니다.
AOP의 장점은 비즈니스 로직 외부에서 관리된다는 점입니다
AOP는 주로 다음과 같은 공통 기능을 분리할 때 사용됩니다:
- 로깅: 각 메서드가 호출될 때마다 직접 로깅 코드를 작성하는 대신, AOP로 로깅을 구현하여 모든 메서드에 동일한 방식으로 적용합니다.
- 트랜잭션 관리: 데이터베이스 트랜잭션을 관리할 때 비즈니스 로직 안에 트랜잭션 처리 코드를 삽입하지 않고, AOP로 처리할 수 있습니다.
- 보안: 메서드 호출 전에 인증 및 권한 확인을 하려면, AOP로 보안 기능을 적용할 수 있습니다.
AOP와 비즈니스 로직의 역할 구분
- 비즈니스 로직: 핵심 비즈니스 로직을 처리하며, 사용자의 요청을 받아 처리하는 역할을 합니다. 예를 들어, 결제 처리, 사용자 등록, 데이터 연산 등을 수행합니다.
- AOP: 비즈니스 로직과 별도로 **횡단 관심사(로깅, 트랜잭션 관리, 보안)**를 처리하며, 비즈니스 로직에 부가적인 기능을 제공합니다. AOP는 비즈니스 로직에 개입하지 않고, 비즈니스 로직의 실행 전후나 에러 발생 시에 작동합니다.
비즈니스 로직 안에서의 AOP 대체 방법
비즈니스 로직 안에서 AOP와 비슷한 기능을 구현하려면, 직접 로직 내에 로깅이나 트랜잭션 관리 코드를 넣어야 하지만, 이는 AOP를 사용하는 것에 비해 코드가 복잡해지고 유지보수성이 떨어집니다. AOP는 이러한 문제를 해결하기 위해 존재하는 것입니다.
차이점
- OOP(객체 지향 프로그래밍):
- 공통적으로 사용되는 메서드들을 한 클래스에 모아두고, 여러 비즈니스 로직에서 이를 직접 호출하여 사용합니다.
- 클래스 상속이나 인터페이스 구현을 통해 메서드를 재사용하거나, 유틸리티 클래스를 만들어 반복적인 코드를 줄이는 방법입니다.
- 공통 기능을 비즈니스 로직에서 명시적으로 호출해야 하므로, 코드를 호출하는 위치에서 해당 메서드가 필요하다는 사실을 알고 있어야 합니다.
- AOP(관점 지향 프로그래밍):
- AOP는 공통된 기능을 명시적으로 호출하지 않아도 비즈니스 로직에 자동으로 적용되도록 하는 방식입니다.
- 로깅, 트랜잭션 관리, 보안과 같은 기능은 비즈니스 로직에 직접 호출할 필요 없이 특정 지점(메서드 호출 전후, 예외 발생 시 등)에 자동으로 적용됩니다.
- 즉, 비즈니스 로직과 완전히 분리된 상태에서 Advice나 Aspect로 구현된 기능들이 특정 지점에서 자동으로 실행되기 때문에, 비즈니스 로직이 공통 기능을 알 필요가 없습니다
OOP 방식의 예 (공통 기능을 유틸리티 클래스에 담아 호출하는 경우)
public class LoggingUtil { public static void log(String message) { System.out.println("Log: " + message); } } public class PaymentService { public void makePayment() { LoggingUtil.log("Payment is being processed"); // 실제 결제 처리 로직 System.out.println("Payment completed."); } }
위의 예에서는 LoggingUtil 클래스에 로깅 메서드를 정의하고, PaymentService에서 이를 직접 호출합니다. 이는 OOP 방식으로 공통 기능을 모듈화하여 재사용하는 방법입니다. 그러나 비즈니스 로직 내에서 직접 호출해야 하며, 코드 간섭이 발생합니다.
AOP 방식의 예 (공통 기능을 분리한 후 자동으로 적용하는 경우)
@Aspect public class LoggingAspect { @Before("execution(* PaymentService.makePayment(..))") public void logBefore() { System.out.println("Log: Payment is being processed"); } } public class PaymentService { public void makePayment() { // 실제 결제 처리 로직 System.out.println("Payment completed."); } }
위의 예에서는 LoggingAspect에 로깅 로직을 분리해 두고, AOP를 통해 PaymentService의 makePayment() 메서드가 실행되기 전에 자동으로 로깅을 실행합니다. 비즈니스 로직 내에서는 로깅 코드를 호출할 필요가 없으며, AOP가 이를 처리합니다.
요약
- OOP 방식: 공통 기능을 유틸리티 클래스나 상속을 통해 모듈화하고, 각 비즈니스 로직에서 직접 호출하여 사용합니다. 이 방식은 코드 재사용성을 높이지만, 비즈니스 로직과 공통 기능이 명시적으로 결합되어 있습니다.
- AOP 방식: 공통 기능을 비즈니스 로직과 완전히 분리한 상태로, 비즈니스 로직에 자동으로 적용됩니다. 비즈니스 로직에 코드가 들어가지 않아 보다 모듈화된 방식입니다.
따라서, 공통으로 사용하는 메서드를 한 클래스에서 관리하고 각 비즈니스 로직에서 이를 호출하는 방식은 AOP가 아니라 객체 지향 프로그래밍에서 흔히 사용하는 코드 재사용 방법입니다. AOP는 명시적인 호출 없이 비즈니스 로직에 공통 기능을 적용하는 프로그래밍 패러다임입니다.
728x90반응형'Spring' 카테고리의 다른 글
Spring에서 @Autowired를 사용하는 것보다 생성자 주입 방식이 나은 이유? (0) 2024.07.24 Spring boot에서 AWS S3에서 받은 파일들을 Zip파일로 압축후 response하기 (in memory) (0) 2023.05.23 [Spring] @Component 클래스 생성자에서 @value값이 null일 경우 해결법 (0) 2022.12.18 @RequestParam ,@RequestBody 차이점 완전정복 (0) 2022.11.03 SPRING BOOT을 이용한 쇼핑몰 만들기(Chapter1) - 스프링 환경셋팅 *with intellij,jsp,mybatis,tomcat,postgreSql (0) 2022.05.16