JAVA

Factory Pattern을 적용한 리팩토링

잔망루피 2024. 9. 3. 18:37

 

두 가지 방법 중에서 고민하다가 첫 번째 방법으로 구현했다.
첫 번째 방법이 코드가 더 깔끔하다.

 

🧶 리팩토링 전

  • status 종류가 더 늘어날 경우 변경에 취약하다.
public Object getFundingList(String status) {
        Object result = null;

        switch (status) {
            case "progress":
                result = fundingRepository.getProgressRanking();
                break;
            case "request":
                result = fundingRepository.getRequestRanking();
                break;
        }
        return result;
}

 

✨ 클래스 다이어그램

 

✅ 첫 번째 방법

  • status로 객체를 찾은 후 메서드를 호출해서 객체를 생성한다.
public Object getFundingList(String status) {
        return factory.create(status).getFundingList(fundingRepository);
    }

 

public abstract class Factory {
    public abstract FundingList create(final String status);
}

 

@Component
public class FundingListFactory extends Factory {
    private final List<FundingList> fundingLists;

    public FundingListFactory(final List<FundingList> fundingLists) {
        this.fundingLists = fundingLists;
    }

    @Override
    public FundingList create(final String type) {
        return fundingLists.stream()
                .filter(status -> status.is(type))
                .findFirst()
                .orElseThrow(() -> NotFoundFundingListTypeException.EXCEPTION);
    }
}

 

public interface FundingList {
    Object getFundingList(FundingRepository fundingRepository);

    boolean is(String status);
}

 

public class ProgressRankingFundingList implements FundingList {
    private static final String STATUS = "progress";

    @Override
    public Object getFundingList(FundingRepository fundingRepository) {
        return fundingRepository.getProgressRanking();
    }

    @Override
    public boolean is(String status) {
        return STATUS.equals(status);
    }
}

 

public class RequestRankingFundingList implements FundingList {
    private final String STATUS = "request";

    @Override
    public Object getFundingList(FundingRepository fundingRepository) {
        return fundingRepository.getRequestRanking();
    }

    @Override
    public boolean is(String status) {
        return STATUS.equals(status);
    }
}

 


🌵 두 번째 방법

  • 유튜브에서 배운 방법대로 구현해봤다.
  • 첫 번째 방법과 차이점은 추상 클래스에서 객체 생성까지 한다.
public Object getFundingList(String status) {
        return factory.create(status);
}
public abstract class Factory {
    public FundingList create(final String status) {
        if (this.isCreatable(status)) {
            return this.createFundingList(status);
        }
        return null;
    }

    public abstract FundingList createFundingList(final String status);

    public abstract boolean isCreatable(String status);
}

 

@Component
public class FundingListFactory extends Factory {
    private final List<FundingList> fundingLists;

    public FundingListFactory(final List<FundingList> fundingLists) {
        this.fundingLists = fundingLists;
    }

    @Override
    public FundingList createFundingList(String status) {
        if (status.equals("progress")) {
            return new ProgressRankingFundingList();
        } else if (status.equals("request")) {
            return new RequestRankingFundingList();
        }
        return null;
    }

    @Override
    public boolean isCreatable(String type) {
        return fundingLists.stream().anyMatch(fundingList -> fundingList.is(type));
    }
}

 

public interface FundingList {
    boolean is(String status);
}

 

public class ProgressRankingFundingList implements FundingList {
    private static final String STATUS = "progress";

    @Override
    public boolean is(String status) {
        return STATUS.equals(status);
    }
}

 

public class RequestRankingFundingList implements FundingList {
    private final String STATUS = "request";

    @Override
    public boolean is(String status) {
        return STATUS.equals(status);
    }
}
반응형