Java

[Java] 함수를 매개변수로 전달하기

@developer.kye 2021. 4. 8. 13:50

중복되는 형태의 코드가 있을 때 모듈화를 하고 싶은 마음이 생긴다.

하필 모듈화를 해야할 부분에서 내부 클래스의 내부 함수를 사용하는 경우에, 

어떻게 따로 모듈화를 할지 어렵게 느껴질 수 있다.

 

이런 경우 java.lang.reflect.Method 를 이용해서 사용할 함수를 다른 함수의 파라미터로 전달해 해결할 수 있다.

 

다음은 ID를 생성해 DB에 저장하기 전에 중복을 방지하는 코드이다.

//ID 생성 
String id = String.valueOf(UUID.randomUUID());
while (true) { // 혹시나 있을 중복 아이디 제거
  if (getById(id) != null)
  	id = String.valueOf(UUID.randomUUID());
  else
  	break;
}

 

기존코드

다음처럼 UserService에서 유저를 디비에 저장되기 전에 해당 ID의 기존 유저가 있는지 확인하고 저장하고, ProductService에서 역시 프로덕트를 디비에 저장하기 전에 ID로 기존 프로덕트가 있는지 확인 한 후 저장하는 코드가 있다고 하자.

@Service("my.service.UserService")
public class UserServiceImpl implements UserService {
	@Resource(name="my.dao.UserDao")
    private UserDao userDao;
    
    @Override
    public User create(User user){
    
    	//ID 생성 
        String id = String.valueOf(UUID.randomUUID());
    	while (true) { // 혹시나 있을 중복 아이디 제거
            if (getById(id) != null)
                id = String.valueOf(UUID.randomUUID());
            else
                break;
        }
        
        user.setId(id)
    	return userDao.create(user)
    }
    
    @Override
    public User getById(String id){
    	return userDao.getById(id)
    }
}
@Service("my.service.ProductService")
public class ProductServiceImpl implements ProductService {
	@Resource(name="my.dao.ProductDao")
    private ProductDao productDao;
    
    @Override
    public Product create(Product product){
    
    	//ID 생성 
        String id = String.valueOf(UUID.randomUUID());
    	while (true) { // 혹시나 있을 중복 아이디 제거
            if (getById(id) != null)
                id = String.valueOf(UUID.randomUUID());
            else
                break;
        }
        
        user.setId(id)
    	return productDao.create(product)
    }
    
    @Override
    public Product getById(String id){
    	return productDao.getById(id)
    }
}

 

개선된 코드

다음처럼 함수를 매개변수로 전달해 중복방지코드를 모듈화 할 수 있다.

public class StringUtil {
    public static String generateUniqueUUID(Object classObject, String methodName) throws Exception {
        Method method = classObject.getClass().getMethod(methodName, String.class);

        String id = String.valueOf(UUID.randomUUID());
        Object[] parameters = new Object[1];

        while (true) { // 혹시나 있을 중복 아이디 제거
            parameters[0] = id;
            if (method.invoke(classObject, parameters) != null)
                id = String.valueOf(UUID.randomUUID());
            else
                break;
        }

        return id;
    }
}
@Service("my.service.UserService")
public class UserServiceImpl implements UserService {
	@Resource(name="my.dao.UserDao")
    private UserDao userDao;
    
    @Override
    public User create(User user){
        String id = StringUtil.generateUniqueUUID(this, "getById");
        user.setId(id)
    	return userDao.create(user)
    }
    
    @Override
    public User getById(String id){
    	return userDao.getById(id)
    }
}
@Service("my.service.ProductService")
public class ProductServiceImpl implements ProductService {
	@Resource(name="my.dao.ProductDao")
    private ProductDao productDao;
    
    @Override
    public Product create(Product product){
        String id = StringUtil.generateUniqueUUID(this, "getById");
        user.setId(id)
    	return productDao.create(product)
    }
    
    @Override
    public Product getById(String id){
    	return productDao.getById(id)
    }
}

불필요한 중복부분을 모듈화 하여 코드를 클린하게 유지할 수 있게된다.