본문 바로가기

개발/java

중복 맞이 중복코드 최소화

서론

높은 퀄리티의 코드를 위해 리펙터링을 할 때,

코드 중복을 줄이는 것이 중요한 요소입니다.

오늘 24년 7월 25일, 중복을 맞아

코드 중복 최소화에 방법에 대해 알아봅시다!

1. 공통 로직을 추상 클래스나 인터페이스로 분리:

  • 추상 클래스 사용:
  • public abstract class BaseService { protected void commonMethod() { // 공통 로직 } } public class UserService extends BaseService { // UserService 특정 로직 }
  • 인터페이스와 디폴트 메서드 활용:
  • public interface CommonOperations { default void commonMethod() { // 공통 로직 } } public class UserService implements CommonOperations { // UserService 특정 로직 }

2. 유틸리티 클래스 활용:

   public class StringUtils {
       public static String capitalize(String str) {
           if (str == null || str.isEmpty()) {
               return str;
           }
           return Character.toUpperCase(str.charAt(0)) + str.substring(1);
       }
   }

3. 상속과 컴포지션 적절히 사용:

  • 상속 예시:
  • public class Vehicle { protected void startEngine() { // 엔진 시작 로직 } } public class Car extends Vehicle { public void drive() { startEngine(); // 운전 로직 } }
  • 컴포지션 예시:
  • public class Engine { public void start() { // 엔진 시작 로직 } } public class Car { private Engine engine; public Car(Engine engine) { this.engine = engine; } public void drive() { engine.start(); // 운전 로직 } }

4. 스프링의 AOP(Aspect-Oriented Programming) 활용:

   @Aspect
   @Component
   public class LoggingAspect {
       @Around("execution(* com.example.service.*.*(..))")
       public Object logMethodExecution(ProceedingJoinPoint joinPoint) throws Throwable {
           // 메서드 실행 전 로깅
           Object result = joinPoint.proceed();
           // 메서드 실행 후 로깅
           return result;
       }
   }

5. 제네릭 사용:

   public interface CrudRepository<T, ID> {
       T findById(ID id);
       void save(T entity);
       void delete(T entity);
   }

   public class UserRepository implements CrudRepository<User, Long> {
       // User 특정 구현
   }

6. 템플릿 메서드 패턴:

   public abstract class DataProcessor {
       public final void process() {
           readData();
           processData();
           saveData();
       }

       protected abstract void readData();
       protected abstract void processData();
       protected abstract void saveData();
   }

   public class CsvDataProcessor extends DataProcessor {
       @Override
       protected void readData() {
           // CSV 파일 읽기
       }

       @Override
       protected void processData() {
           // CSV 데이터 처리
       }

       @Override
       protected void saveData() {
           // 처리된 데이터 저장
       }
   }

7. 빌더 패턴:

   public class User {
       private final String name;
       private final int age;

       private User(UserBuilder builder) {
           this.name = builder.name;
           this.age = builder.age;
       }

       public static class UserBuilder {
           private String name;
           private int age;

           public UserBuilder name(String name) {
               this.name = name;
               return this;
           }

           public UserBuilder age(int age) {
               this.age = age;
               return this;
           }

           public User build() {
               return new User(this);
           }
       }
   }

8. 스프링의 컴포넌트 스캔과 의존성 주입:

   @Service
   public class EmailService {
       public void sendEmail(String to, String subject, String body) {
           // 이메일 전송 로직
       }
   }

   @Service
   public class UserService {
       private final EmailService emailService;

       @Autowired
       public UserService(EmailService emailService) {
           this.emailService = emailService;
       }

       public void registerUser(User user) {
           // 사용자 등록 로직
           emailService.sendEmail(user.getEmail(), "Welcome", "Welcome to our service!");
       }
   }

이러한 기법들을 적절히 조합하여 사용하면 중복 코드를 크게 줄일 수 있습니다.

또한, 코드의 재사용성과 유지보수성이 향상되며,

새로운 기능을 추가하거나 기존 코드를 수정할 때 더 효율적으로 작업할 수 있기 때문에,

향후 서비스 운영할 때 큰 도움이 될 것입니다.

결론

중복 맞아 치킨드시고 모두 몸보신 하세요!

 

반응형