이용내역 조회 시 특정 타입에 따라 조건에 따라 다른 표시를 해줘야 하는 경우가 발생했다.
실제 사례가 아니라 좀 맞지 않는 부분이 많지만 아래처럼 예시 코드를 들어 얘기하는 게 더 나을 것 같다.
class Object {
private String type; // A, B, C 타입이 존재
private String gender; // F, M, U 타입이 존재
private int age;
private String info;
}
if ("A".equals(type) && "F".equals(gender)) {
return info;
}
if ("B".equals(type) && "M".equals(gendeer) && age > 20) {
return info + " " + age;
}
if ("C".equals(type) && ("F".equals(gender) || "U".equals(gender))) {
return info + " " + gender;
}
return null;
뭐 대략 이런 느낌의 비즈니스 로직이라고 생각해주면 된다.
Object 값이 주어졌을 때 내부 데이터의 조건에 따라 표시해줘야 하는 값이 달라지는 것이다.
if문으로 처리할 수 있지만 조건이 복잡하다보니 코드가 너무 길어지고 가독성도 좋지 않아서 다른 방법이 무엇이 있을까 생각을 계속 했었다.
이걸 처리하기 위해 Enum 으로 함수형 인터페이스를 활용하여 정리해보고자 했다.
enum ObjectType {
TYPE1((object) -> "A".equals(type) && "F".equals(gender),
(object) -> info),
TYPE2((object) -> "B".equals(type) && "M".equals(gendeer) && age > 20,
(object) -> info + " " + age),
TYPE3((object) -> "C".equals(type) && ("F".equals(gender) || "U".equals(gender)),
(object) -> info + " " + gender);
private Function<Object, Boolean> objectTypePredicate;
private Function<Object, String> objectInfoResolver;
public ObjectType(Function<Object, Boolean> objectTypePredicate, Function<Object, String> objectInfo) {
this.objectTypePredicate = objectTypePredicate;
this.objectInfo = objectInfo;
}
public static Optional<ObjectType> getObjectType(Object object) {
return Arrays.stream(values())
.filter(ObjectTypePredicate::apply)
.findFirst();
}
public String getObjectInfo(Object object) {
return objectInfoResolver.apply(object);
}
}
Object object = new Object("B", "M", 30, "happy");
ObjectType objectType = ObjectType.getObjectType(object);
System.out.println(objectType.getObjectInfo(object));
출력값: happy 30
Object 값에 따라 어떤 경우인지 판단하기 위해 Function<Object, Boolean> Object 값이 주어졌을 때 Boolean 값을 리턴하는 판단 함수 인터페이스를 추가한다.
그리고 static 메서드를 통해서 enum으로 선언한 경우 중 어떤 경우인지 판단한 후 enum 값을 가져오도록 한다.
해당 enum 값에서 특정 경우마다 표시해줘야 할 String 값도 달라지므로 Function<Object, String> Object 값이 주어졌을 때 내부 정보 조합해서 String 값으로 반환하는 함수 인터페이스를 추가한다.
static 메서드를 통해서 어떤 경우인지 판단 후 찾은 enum 타입 내부에 선언한 변환 메서드를 통해 표시할 String 값을 찾아와준다.
예시를 대충 들었더니 의미가 좀 더 명확해졌을지언정 이게 더 복잡하지 않나..? 싶은 생각도 들지만, 실제 사례에서는 1) 6 ~ 7개가 되는 케이스가 발생했고, 2) 1차 조건 이후 ObjectInfo 표시할 때 조건문이 추가로 있었고, 3) 경우에 따라 다르게 표시해줘야 하는 값도 2개라서 더욱 복잡했기 때문에 이 편이 훨씬 깔끔하게 코드 정리를 할 수 있었다.