출석체크 이벤트 기능을 구현 중이다.
관리자페이지에서 해당 이벤트에 대한 지급 쿠폰을 등록할 수 있다.
1. 출석체크 시 무조건 지급하는 일일 쿠폰
2. 연속 출석 시 지급하는 연속 쿠폰 -> admin에서 연속 출석 일수를 설정할 수 있다.
각 쿠폰마다 여러 장 등록될 수 있다.
ex) 일일 쿠폰 3장 / 연속 쿠폰 2장
사용자가 출석 체크 이벤트에 참여하면
서버에서는 해당 이벤트로 등록된 쿠폰 목록을 모두 조회하고,
사용자의 이벤트 참여 상태에 따라 어떤 쿠폰을 지급해야할 지 판단한다.
쿠폰 목록을 조회할 때, 일일/연속 구분 없이 해당 이벤트로 등록된 모든 쿠폰을 조회한다.
쿠폰 조회 후, 쿠폰마다 가지고 있는 type으로 일일/연속 쿠폰으로 분리한다.
일일 쿠폰 타입 : D
연속 쿠폰 타입 : C
// 출석체크 이벤트 쿠폰 조회
List<AttendCoupon> attendCoupons = dao.getCoupontList(event.getEventId());
// 쿠폰 타입별 분리
List<AttendCoupon> dailyCoupons = new ArrayList<>(); // 일일 쿠폰
List<AttendCoupon> consecutiveCoupons = new ArrayList<>(); // 연속 쿠폰
for (AttendCoupon coupon : attendCoupons) {
if ("D".equals(coupon.getType())) {
dailyCoupons.add(coupon);
}
if ("C".equals(coupon.getType())) {
consecutiveCoupons.add(coupon);
}
}
스트림으로도 구현해볼 수 있지 않을까.
// 출석체크 이벤트 쿠폰 조회
List<AttendCoupon> attendCoupons = dao.getCouponList(event.getEventId());
// 쿠폰 타입 기준 grouping
Map<String, List<AttendCoupon>> groupedCoupons = attendCoupons.stream()
.collect(Collectors.groupingBy(AttendCoupon::getType));
List<AttendCoupon> dailyCoupons = groupedCoupons.getOrDefault("D", new ArrayList<>());
List<AttendCoupon> consecutiveCoupons = groupedCoupons.getOrDefault("C", new ArrayList<>());
스트림으로 작성 후, 실행했는데 에러가 발생했다.
Caused by: org.aspectj.apache.bcel.classfile.ClassFormatException: File: '파일위치':
Invalid byte tag in constant pool: 18
AspectJ가 바이트 코드를 제대로 처리하지 못하고 있다는 내용을 담고 있다.
자바 컴파일러가 스트림/람다의 바이트 코드를 생성했지만
AspectJ가 해당 바이트 코드를 지원하지 않아 발생한 문제로 확인된다.
AspectJ가 바이트 코드를 지원하지 않은 이유
프로젝트의 Java 버전과 aspectJ 버전이 맞지 않아서다.
현재 Java 8 을 사용 중이고, aspectJ는 Java 7 버전까지만 지원하는 1.6.11 버전을 사용 중이다.
AspectJ 같은 바이트코드 조작 라이브러리는 특정 자바 버전에서의 바이트코드 구조에 의존한다.
Java 7 까지는 invokestatic, invokevirtual, invokeinterface, invokespecial 을 사용했지만
Java 8 은 새로운 기능인 스트림, 람다를 처리하기 위해 invokedynamic 라는 새로운 바이트 코드 명령어를 사용한다.
현재 사용 중인 aspectJ 버전에서 invokedynamic 을 인식하지 못해 에러가 발생한 것이다.
어떻게 해결할 수 있을까?
aspectJ를 최신 버전으로 업데이트하여 스트림을 사용하거나, 단순 반복문을 사용함으로써 해결할 수 있다.
현재 프로젝트에서는 스트림이 사용된 로직이 없고, 복잡한 로직이더라도 전부 반복문으로 구현되어 있다.
갑자기 스트림으로 작성된 코드를 본다면 의문을 품을 수밖에 없다.
일관성을 지키고자 반복문을 선택했다.
스트림으로 구현할 수 있는 코드이더라도, 어쩌면 스트림으로 작성하는 것이 더 좋은 코드일지라도,
읽는 사람에게 혼동을 줄 수 있다면 코드의 일관성을 지키는 게 좋지 않을까.
'Language > Java' 카테고리의 다른 글
Readable Code 적용 (2) | 2024.10.24 |
---|