서문:
이번 글에서는 무작위로 추천되는 레슨을 가져오는 코드를 리팩토링하는 과정을 소개하려 합니다. 주어진 코드는 중복이 많았고 가독성이 떨어져 유지보수가 어려웠습니다. 이를 개선하여 효율적이고 유연한 코드로 변경해보겠습니다.
코드 리팩토링 전:
// 원래 코드
public List<RecommendLesson> getRecommendLessons(LessonCategory category, Integer lessonId){
List<Lesson> filteredLessons = lessonRepository.findByCategoryNotCurrent(category, lessonId);
// 무작위로 선택할 레슨의 개수
int numRandomLessons = Math.min(3, filteredLessons.size());
List<Lesson> randomLessons = new ArrayList<>();
Random random = new Random();
while (randomLessons.size() < numRandomLessons) {
int randomIndex = random.nextInt(filteredLessons.size());
Lesson randomLesson = filteredLessons.get(randomIndex);
// 중복된 레슨을 선택하지 않도록 필터링
if (!randomLessons.contains(randomLesson)) {
randomLessons.add(randomLesson);
}
}
return randomLessons.stream()
.map(RecommendLesson::new)
.toList();
}
public List<RecommendLesson> getRandomLessons(){
List<Lesson> filteredLessons = lessonRepository.findAll();
// 무작위로 선택할 레슨의 개수
int numRandomLessons = Math.min(5, filteredLessons.size());
List<Lesson> randomLessons = new ArrayList<>();
Random random = new Random();
while (randomLessons.size() < numRandomLessons) {
int randomIndex = random.nextInt(filteredLessons.size());
Lesson randomLesson = filteredLessons.get(randomIndex);
// 중복된 레슨을 선택하지 않도록 필터링
if (!randomLessons.contains(randomLesson)) {
randomLessons.add(randomLesson);
}
}
return randomLessons.stream()
.map(RecommendLesson::new)
.toList();
}
문제점:
getRandomLessons
와 getRecommendLessons
에 중복된 로직이 존재하며, 가독성이 떨어짐.코드 리팩토링 후:
public List<RecommendLesson> getRandomLessons(int numRandomLessons, LessonCategory category, Integer lessonId) {
List<Lesson> filteredLessons;
if (category != null && lessonId != null) {
filteredLessons = lessonRepository.findByCategoryNotCurrent(category, lessonId);
} else {
filteredLessons = lessonRepository.findAll();
}
return getRandomRecommendLessons(filteredLessons, numRandomLessons);
}
private List<RecommendLesson> getRandomRecommendLessons(List<Lesson> lessons, int numRandomLessons) {
int totalLessons = lessons.size();
int actualRandomLessons = Math.min(numRandomLessons, totalLessons);
List<Lesson> randomLessons = new ArrayList<>();
Random random = new Random();
while (randomLessons.size() < actualRandomLessons) {
int randomIndex = random.nextInt(totalLessons);
Lesson randomLesson = lessons.get(randomIndex);
if (!randomLessons.contains(randomLesson)) {
randomLessons.add(randomLesson);
}
}
return randomLessons.stream()
.map(RecommendLesson::new)
.toList();
}
개선 사항:
getRandomLessons
와 getRecommendLessons
의 중복 로직을 getRandomRecommendLessons
로 추출하여 중복 제거.결론:
이번 코드 리팩토링을 통해 중복을 제거하고 가독성을 높이며, 유지보수성을 향상시켰습니다. 변경된 코드는 더욱 유연하며 향후 추가적인 기능이나 조건 변경에 대응하기에 용이해졌습니다.
위의 리팩토링은 코드의 가독성과 유지보수성을 높이고 중복을 제거하여 코드를 더 효율적으로 만들기 위해 진행되었습니다.
중복 코드 제거: getRandomLessons
와 getRecommendLessons
는 기본적으로 비슷한 로직을 가지고 있었습니다. 이 두 메서드에서 중복되는 부분을 getRandomRecommendLessons
로 추출하여 중복을 제거했습니다.
재사용성 향상: getRandomRecommendLessons
로 추출된 메서드를 getRandomLessons
에서 활용하여, 여러 곳에서 무작위 레슨을 가져오는 로직을 재사용할 수 있게 되었습니다.
인자 활용하여 유연성 증대: getRandomRecommendLessons
에 List<Lesson>
와 numRandomLessons
를 인자로 전달함으로써, 다양한 리스트와 다른 개수의 무작위 레슨을 추출할 수 있게 되었습니다. 또한, getRandomLessons
에서는 필요에 따라 카테고리와 레슨 ID를 전달하여 특정 조건에 맞는 추천 레슨을 가져올 수 있도록 설계되었습니다.
가독성 향상: 메서드를 분리하고 이름을 명확하게 지어서 각 메서드의 역할을 명확히 드러내었습니다. 코드가 무엇을 하는지 쉽게 이해할 수 있게 되었습니다.
이렇게 하여 코드의 중복을 줄이고, 유연성을 높이며, 가독성을 개선함으로써 향후 유지보수를 용이하게 만들었습니다. 코드 리팩토링은 기능의 변경 없이 코드를 개선하여 더 나은 구조와 가독성을 확보하는 데 도움을 줍니다.
개발 철학: 코드는 함축적이고 유연해야 한다
이 개발 철학은 코드 작성과 유지보수의 핵심 가치를 내포하고 있습니다. 코드는 읽기 쉬워야 하며, 명확하고 간결한 표현을 선호합니다. 코드는 기능을 제공하는 것뿐만 아니라 읽기 쉽고 이해하기 쉬워야 합니다.
가독성 우선:
유지보수성과 확장성:
중복 제거와 모듈화:
진화하는 코드:
테스트와 안정성:
이러한 개발 철학은 코드 작성 방법뿐만 아니라, 소프트웨어 개발 방법론과도 연관이 있습니다. Agile, DevOps 등의 방법론은 이러한 가치들을 중요시하며, 코드의 가독성과 유연성을 강조합니다.
개발자는 기술적인 부분뿐만 아니라, 이러한 가치와 철학을 가지고 코드를 작성하고 프로젝트를 이끌어가는 것이 중요합니다. 이러한 원칙을 중심으로 소프트웨어 개발에 접근하는 것이 항상 효과적인 결과를 가져다줄 수 있습니다.