Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DEV-29] CalculateDetailGraduationUseCaseResolver 구현 #252

Merged
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.plzgraduate.myongjigraduatebe.graduation.api;

import com.plzgraduate.myongjigraduatebe.graduation.application.usecase.CalculateDetailGraduationUseCase;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory;

public interface CalculateDetailGraduationUseCaseResolver {

CalculateDetailGraduationUseCase resolveCalculateDetailGraduationUseCase(GraduationCategory graduationCategory);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.plzgraduate.myongjigraduatebe.graduation.api;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import com.plzgraduate.myongjigraduatebe.graduation.application.usecase.CalculateDetailGraduationUseCase;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory;

@Component
public class SingleCalculateDetailGraduationUseCaseResolver implements CalculateDetailGraduationUseCaseResolver {

private List<CalculateDetailGraduationUseCase> calculateDetailGraduationUseCases;

private final ApplicationContext applicationContext;

@Autowired
public SingleCalculateDetailGraduationUseCaseResolver(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
initCalculateDetailGraduationUseCase();
}

@Override
public CalculateDetailGraduationUseCase resolveCalculateDetailGraduationUseCase(
GraduationCategory graduationCategory) {
return calculateDetailGraduationUseCases.stream()
.filter(calculateDetailGraduationUseCase -> calculateDetailGraduationUseCase.supports(graduationCategory))
.findFirst()
.orElseThrow(() -> new RuntimeException("No calculate detail graduation case found"));
}

private void initCalculateDetailGraduationUseCase() {
Map<String, CalculateDetailGraduationUseCase> matchingBeans = applicationContext.getBeansOfType(
CalculateDetailGraduationUseCase.class);
this.calculateDetailGraduationUseCases = new ArrayList<>(matchingBeans.values());
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 코드만 보면 생성자 주입으로 모든 CalculateDetailGraduationUseCase의 빈을 주입하는 것과 큰 차이는 없어보이는데, ApplicationContext를 사용함으로서 얻는 장점이 있나?

Copy link
Member Author

@5uhwann 5uhwann Apr 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

생각해보니 그렇네요..! 빈 조회 후 특정 방법에 대한 정렬이나 기본 빈 처리 전략 없이 해당 타입으로만 조회를 하니 List로 주입받는것과 다름이 없군요
원래는 GraduationCategory에 해당하는 빈만 조회하고 싶었는데 className 기반으로 조회를 할 경우 변경에 대한 유연성이 너무떨어져 해당 방식은 기각했는데 그렇다면 각 CalculateDetailGraduationUseCase 빈 등록시 @Quilipier를 통해 GraduationCategory EnumType value로 구분자를 추가하여 등록 후 GraduationCategory에 해당하는 빈만 조회하여 반환하는 방식은 어떤가요?

  1. 모든 빈 List로 주입 후 support 여부로 체크 후 반환
    • 코드가 간결해짐
    • CalculateDetailGraduationUseCase 타입 빈들을 모두 체크해야 함 (어차피 몇개 없어서 큰 문제는 아닌거 같긴 합니다)
  2. Qualifier 어노테이션을 통해 빈 등록 시 GraduationCategory enum value로 구분 후 GraduationCategory에 해당하는 빈 조회
    • 필요한 빈만 조회 후 반환 가능
    • GraduationCategory 변경 시 Qualifier 어노테이션 value 수정 필요 -> 마찬가지로 변경의 유연성 떨어짐

어떤 방법이 더 괜찮을지 의견 부탁드립니다! @stophwan @Hoya324

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

나는 1번 방안이 더 나은거 같아. 수환 말대로 className 기발 조회가 변경 유연성이 떨어지고, 모든 빈을 주입하는게 큰 차이가 없다는 점에서!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[a863510] 반영완료했습니다!

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.plzgraduate.myongjigraduatebe.graduation.application.service;

import static com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory.COMMON_CULTURE;

import org.springframework.stereotype.Service;

import com.plzgraduate.myongjigraduatebe.graduation.application.usecase.CalculateCommonCultureGraduationUseCase;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.DetailGraduationResult;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationRequirement;
import com.plzgraduate.myongjigraduatebe.takenlecture.domain.model.TakenLectureInventory;
import com.plzgraduate.myongjigraduatebe.user.domain.model.User;

@Service
public class CalculateCommonCultureGraduationService implements CalculateCommonCultureGraduationUseCase {

@Override
public boolean supports(GraduationCategory graduationCategory) {
return graduationCategory == COMMON_CULTURE;
}

@Override
public DetailGraduationResult calculateDetailGraduation(User user, TakenLectureInventory takenLectureInventory,
GraduationRequirement graduationRequirement) {
return null;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.plzgraduate.myongjigraduatebe.graduation.application.service;

import static com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory.*;

import org.springframework.stereotype.Service;

import com.plzgraduate.myongjigraduatebe.graduation.application.usecase.CalculateCoreCultureGraduationUseCase;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.DetailGraduationResult;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationRequirement;
import com.plzgraduate.myongjigraduatebe.takenlecture.domain.model.TakenLectureInventory;
import com.plzgraduate.myongjigraduatebe.user.domain.model.User;

@Service
public class CalculateCoreCultureGraduationService
implements CalculateCoreCultureGraduationUseCase {

@Override
public boolean supports(GraduationCategory graduationCategory) {
return graduationCategory == CORE_CULTURE;
}

@Override
public DetailGraduationResult calculateDetailGraduation(User user, TakenLectureInventory takenLectureInventory,
GraduationRequirement graduationRequirement) {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.plzgraduate.myongjigraduatebe.graduation.application.service;

import static com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory.DUAL_BASIC_ACADEMICAL_CULTURE;

import org.springframework.stereotype.Service;

import com.plzgraduate.myongjigraduatebe.graduation.application.usecase.CalculateDualBasicAcademicalCultureDetailGraduationUseCase;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.DetailGraduationResult;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationRequirement;
import com.plzgraduate.myongjigraduatebe.takenlecture.domain.model.TakenLectureInventory;
import com.plzgraduate.myongjigraduatebe.user.domain.model.User;

@Service
public class CalculateDualBasicAcademicalCultureDetailGraduationUseService implements
CalculateDualBasicAcademicalCultureDetailGraduationUseCase {
@Override
public boolean supports(GraduationCategory graduationCategory) {
return graduationCategory == DUAL_BASIC_ACADEMICAL_CULTURE;
}

@Override
public DetailGraduationResult calculateDetailGraduation(User user, TakenLectureInventory takenLectureInventory,
GraduationRequirement graduationRequirement) {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.plzgraduate.myongjigraduatebe.graduation.application.service;

import static com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory.DUAL_MAJOR;

import org.springframework.stereotype.Service;

import com.plzgraduate.myongjigraduatebe.graduation.application.usecase.CalculateDualMajorDetailGraduationUseCase;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.DetailGraduationResult;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationRequirement;
import com.plzgraduate.myongjigraduatebe.takenlecture.domain.model.TakenLectureInventory;
import com.plzgraduate.myongjigraduatebe.user.domain.model.User;

@Service
public class CalculateDualMajorDetailGraduationService implements CalculateDualMajorDetailGraduationUseCase {
@Override
public boolean supports(GraduationCategory graduationCategory) {
return graduationCategory == DUAL_MAJOR;
}

@Override
public DetailGraduationResult calculateDetailGraduation(User user, TakenLectureInventory takenLectureInventory,
GraduationRequirement graduationRequirement) {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.plzgraduate.myongjigraduatebe.graduation.application.service;

import static com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory.PRIMARY_BASIC_ACADEMICAL_CULTURE;

import org.springframework.stereotype.Service;

import com.plzgraduate.myongjigraduatebe.graduation.application.usecase.CalculateDetailGraduationUseCase;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.DetailGraduationResult;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationRequirement;
import com.plzgraduate.myongjigraduatebe.takenlecture.domain.model.TakenLectureInventory;
import com.plzgraduate.myongjigraduatebe.user.domain.model.User;

@Service
public class CalculatePrimaryBasicAcademicalCultureDetailGraduationService
implements CalculateDetailGraduationUseCase {
@Override
public boolean supports(GraduationCategory graduationCategory) {
return graduationCategory == PRIMARY_BASIC_ACADEMICAL_CULTURE;
}

@Override
public DetailGraduationResult calculateDetailGraduation(User user, TakenLectureInventory takenLectureInventory,
GraduationRequirement graduationRequirement) {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.plzgraduate.myongjigraduatebe.graduation.application.service;

import static com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory.PRIMARY_MAJOR;

import org.springframework.stereotype.Service;

import com.plzgraduate.myongjigraduatebe.graduation.application.usecase.CalculatePrimaryMajorDetailGraduationUseCase;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.DetailGraduationResult;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationRequirement;
import com.plzgraduate.myongjigraduatebe.takenlecture.domain.model.TakenLectureInventory;
import com.plzgraduate.myongjigraduatebe.user.domain.model.User;

@Service
public class CalculatePrimaryMajorDetailGraduationService implements CalculatePrimaryMajorDetailGraduationUseCase {
@Override
public boolean supports(GraduationCategory graduationCategory) {
return graduationCategory == PRIMARY_MAJOR;
}

@Override
public DetailGraduationResult calculateDetailGraduation(User user, TakenLectureInventory takenLectureInventory,
GraduationRequirement graduationRequirement) {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.plzgraduate.myongjigraduatebe.graduation.application.service;

import static com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory.*;

import org.springframework.stereotype.Service;

import com.plzgraduate.myongjigraduatebe.graduation.application.usecase.CalculateSubMajorDetailGraduationUseCase;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.DetailGraduationResult;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationRequirement;
import com.plzgraduate.myongjigraduatebe.takenlecture.domain.model.TakenLectureInventory;
import com.plzgraduate.myongjigraduatebe.user.domain.model.User;

@Service
public class CalculateSubMajorDetailGraduationService implements CalculateSubMajorDetailGraduationUseCase {
@Override
public boolean supports(GraduationCategory graduationCategory) {
return graduationCategory == SUB_MAJOR;
}

@Override
public DetailGraduationResult calculateDetailGraduation(User user, TakenLectureInventory takenLectureInventory,
GraduationRequirement graduationRequirement) {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.plzgraduate.myongjigraduatebe.graduation.application.usecase;

public interface CalculateCommonCultureGraduationUseCase extends CalculateDetailGraduationUseCase{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.plzgraduate.myongjigraduatebe.graduation.application.usecase;

public interface CalculateCoreCultureGraduationUseCase extends CalculateDetailGraduationUseCase {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.plzgraduate.myongjigraduatebe.graduation.application.usecase;

import com.plzgraduate.myongjigraduatebe.graduation.domain.model.DetailGraduationResult;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationRequirement;
import com.plzgraduate.myongjigraduatebe.takenlecture.domain.model.TakenLectureInventory;
import com.plzgraduate.myongjigraduatebe.user.domain.model.User;

public interface CalculateDetailGraduationUseCase {

boolean supports(GraduationCategory graduationCategory);

DetailGraduationResult calculateDetailGraduation(User user, TakenLectureInventory takenLectureInventory,
GraduationRequirement graduationRequirement);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.plzgraduate.myongjigraduatebe.graduation.application.usecase;

public interface CalculateDualBasicAcademicalCultureDetailGraduationUseCase extends CalculateDetailGraduationUseCase {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.plzgraduate.myongjigraduatebe.graduation.application.usecase;

public interface CalculateDualMajorDetailGraduationUseCase extends CalculateDetailGraduationUseCase {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.plzgraduate.myongjigraduatebe.graduation.application.usecase;

public interface CalculatePrimaryBasicAcademicalCultureDetailGraduationUseCase
extends CalculateDetailGraduationUseCase {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.plzgraduate.myongjigraduatebe.graduation.application.usecase;

public interface CalculatePrimaryMajorDetailGraduationUseCase extends CalculateDetailGraduationUseCase {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.plzgraduate.myongjigraduatebe.graduation.application.usecase;

public interface CalculateSubMajorDetailGraduationUseCase extends CalculateDetailGraduationUseCase {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.plzgraduate.myongjigraduatebe.graduation.api;

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;

import com.plzgraduate.myongjigraduatebe.graduation.application.usecase.CalculateDetailGraduationUseCase;
import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory;

@SpringBootTest
@ActiveProfiles("test")
class SingleCalculateDetailGraduationUseCaseResolverTest {

@Autowired
private SingleCalculateDetailGraduationUseCaseResolver singleCalculateDetailGraduationUseCaseResolver;

@DisplayName("졸업 카테고리를 계산할 수 있는 CalculateDetailGraduationUseCaseResolver 반환한다.")
@ValueSource(strings =
{"COMMON_CULTURE", "CORE_CULTURE", "PRIMARY_MAJOR", "DUAL_MAJOR", "SUB_MAJOR",
"PRIMARY_BASIC_ACADEMICAL_CULTURE", "DUAL_BASIC_ACADEMICAL_CULTURE"
})
@ParameterizedTest
void resolveCalculateDetailGraduationUseCase(String graduationCategoryName) {
//given
GraduationCategory graduationCategory = GraduationCategory.valueOf(graduationCategoryName);

// when
CalculateDetailGraduationUseCase calculateDetailGraduationUseCase = singleCalculateDetailGraduationUseCaseResolver.resolveCalculateDetailGraduationUseCase(
graduationCategory);

//then
assertThat(calculateDetailGraduationUseCase.supports(graduationCategory)).isEqualTo(true);
}
}
Loading