@@ -0,0 +1,86 @@
+package nextstep.subway.application;
+
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import nextstep.subway.domain.Line;
+import nextstep.subway.domain.LineRepository;
+import nextstep.subway.domain.Station;
+import nextstep.subway.domain.StationRepository;
+import nextstep.subway.dto.LineCreateRequest;
+import nextstep.subway.dto.LineResponse;
+import nextstep.subway.dto.LineUpdateRequest;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+@Transactional(readOnly = true)
+public class LineService {
+    private final LineRepository lineRepository;
+
+    private final StationRepository stationRepository;
+
+    public LineService(LineRepository lineRepository, StationRepository stationRepository) {
+        this.lineRepository = lineRepository;
+        this.stationRepository = stationRepository;
+    }
+
+    @Transactional
+    public LineResponse saveLine(LineCreateRequest lineCreateRequest) {
+        Line persistLine = lineRepository.save(lineCreateRequest.toLine());
+        addStations(persistLine, lineCreateRequest);
+        return LineResponse.of(persistLine);
+    }
+
+    public LineResponse findLine(Long id) {
+        Optional<Line> line = lineRepository.findById(id);
+        return LineResponse.of(line.get());
+    }
+
+    public List<LineResponse> findAllLines() {
+        return lineRepository.findAll().stream()
+                .map(LineResponse::of)
+                .collect(Collectors.toList());
+    }
+
+    @Transactional
+    public LineResponse updateLine(Long id, LineUpdateRequest lineUpdateRequest) {
+        Line line = lineRepository.findById(id).get();
+        line.updateLine(lineUpdateRequest);
+        return LineResponse.of(line);
+    }
+
+    @Transactional
+    public void deleteLineById(Long id) {
+        Optional<Line> line = lineRepository.findById(id);
+        if (line.isPresent()) {
+            line.get().clearRelatedLines();
+            lineRepository.delete(line.get());
+        }
+    }
+
+    private void addStations(Line persistLine, LineCreateRequest lineCreateRequest) {
+        addUpLine(persistLine, lineCreateRequest);
+        addDownLine(persistLine, lineCreateRequest);
+    }
+
+    private void addUpLine(Line line, LineCreateRequest lineCreateRequest) {
+        if (lineCreateRequest.hasUpStationsId()) {
+            Station station = getStation(lineCreateRequest.getUpStationId());
+            line.addStation(station);
+        }
+    }
+
+    private void addDownLine(Line line, LineCreateRequest lineCreateRequest) {
+        if (lineCreateRequest.hasDownStationsId()) {
+            Station station = getStation(lineCreateRequest.getDownStationId());
+            line.addStation(station);
+        }
+    }
+
+    private Station getStation(Long stationId) {
+        return stationRepository.findById(stationId)
+                .orElseThrow(() -> new NoSuchElementException("id(" + stationId + ")에 해당하는 역이 없습니다."));
+    }
+}

리뷰: id로 라인을 찾아 연관관계를 제거하는 로직을 넣고자 했는데요,
라인이 있을 경우에만 처리하려다 보니 방어코드 차원으로 넣었습니다.

이 경우에는 deleteById 보다는 delete 메소드가 더 적합해 보이네요. 감사합니다!