https://toongri.tistory.com/13
https://mangkyu.tistory.com/151
GitHub - kyukong/atdd-subway-path at step2
우아한테크코스 미션 중 지하철 경로 조회 미션에서 외부 라이브러리를 사용한 객체를 스프링 빈으로 생성하였다.
지하철 경로를 조회하는 알고리즘을 다익스트라 알고리즘을 사용하였으나 다른 라이브러리 또는 다른 알고리즘을 사용할 수 있기 때문에 사용하는 전략을 쉽게 바꾸기 위해서 다형성을 이용하였다. 변경이 쉽도록 인터페이스로 분리하였으므로 코드 내에서 해당 객체를 선언하는 것이 아닌 외부에서 입력받아오도록 스프링 빈 객체로 선언하였다.
***src/main/java/wooteco/subway/domain/path/PathDecisionStrategy.java***
package wooteco.subway.domain.path;
import wooteco.subway.domain.Section;
import java.util.List;
public interface PathDecisionStrategy {
PathDecision decidePath(final List<Section> sections, final Path path);
}
***src/main/java/wooteco/subway/domain/path/PathDijkstraDecisionStrategy.java***
package wooteco.subway.domain.path;
import org.jgrapht.GraphPath;
import org.jgrapht.alg.shortestpath.DijkstraShortestPath;
import org.jgrapht.graph.DefaultWeightedEdge;
import org.jgrapht.graph.WeightedMultigraph;
import wooteco.subway.domain.Section;
import java.util.List;
public class PathDijkstraDecisionStrategy implements PathDecisionStrategy {
private DijkstraShortestPath<Long, DefaultWeightedEdge> dijkstraShortestPath;
@Override
public PathDecision decidePath(final List<Section> sections, final Path path) {
createDijkstraGraph(sections);
GraphPath<Long, DefaultWeightedEdge> graph = dijkstraShortestPath.getPath(path.getSource(), path.getTarget());
return new PathDecision(graph.getVertexList(), graph.getWeight());
}
private void createDijkstraGraph(final List<Section> sections) {
final WeightedMultigraph<Long, DefaultWeightedEdge> graph = new WeightedMultigraph<>(DefaultWeightedEdge.class);
for (Section section : sections) {
addSectionInGraph(graph, section);
}
dijkstraShortestPath = new DijkstraShortestPath<>(graph);
}
private void addSectionInGraph(final WeightedMultigraph<Long, DefaultWeightedEdge> graph, final Section section) {
final Long upStationId = section.getUpStationId();
final Long downStationId = section.getDownStationId();
graph.addVertex(upStationId);
graph.addVertex(downStationId);
graph.setEdgeWeight(graph.addEdge(upStationId, downStationId), section.getDistance());
graph.setEdgeWeight(graph.addEdge(downStationId, upStationId), section.getDistance());
}
}
***src/main/java/wooteco/subway/config/PathConfiguration.java***
package wooteco.subway.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import wooteco.subway.domain.path.PathDecisionStrategy;
import wooteco.subway.domain.path.PathDijkstraDecisionStrategy;
@Configuration
public class PathConfiguration {
@Bean
public PathDecisionStrategy addPathDecisionStrategyBean() {
return new PathDijkstraDecisionStrategy();
}
}
설정 객체인 PathConfiguration
에서 지하철 경로를 조회하는 여러 전략 중 하나를 선택하도록 설정하였다.