서론
높은 퀄리티의 코드를 위해 리펙터링을 할 때,
코드 중복을 줄이는 것이 중요한 요소입니다.
오늘 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!");
}
}
이러한 기법들을 적절히 조합하여 사용하면 중복 코드를 크게 줄일 수 있습니다.
또한, 코드의 재사용성과 유지보수성이 향상되며,
새로운 기능을 추가하거나 기존 코드를 수정할 때 더 효율적으로 작업할 수 있기 때문에,
향후 서비스 운영할 때 큰 도움이 될 것입니다.
결론
중복 맞아 치킨드시고 모두 몸보신 하세요!
반응형
'개발 > java' 카테고리의 다른 글
Spring Batch 5 JdbcBatchItemWriter itemPreparedStatementSetter is null 에러 (1) | 2024.11.29 |
---|---|
Spring Batch + MSSQL 실행과정 FLOW 파헤치기, meta db 접근순서 (3) | 2024.04.29 |
build.gradle, settings.gradle, properties 차이? 역할? 알아보기 (0) | 2024.04.16 |
Spring Actuator 로 Custom Endpoint 등록 및 변수 전달 (0) | 2024.03.19 |
포장을 못하면 개발을 못해요 (API 유지보수성 극대화) (0) | 2021.06.10 |