Skip to content

Conversation

lkim0402
Copy link
Collaborator

@lkim0402 lkim0402 commented Jun 12, 2025

기본 요구사항

기본요구사항

File IO를 통한 데이터 영속화

  • 다음의 조건을 만족하는 서비스 인터페이스의 구현체를 작성하세요.
    • 클래스 패키지명: com.sprint.mission.discodeit.service.file
    • 클래스 네이밍 규칙: File[인터페이스 이름]
    • JCF 대신 FileIO와 객체 직렬화를 활용해 메소드를 구현하세요.
  • Application에서 서비스 구현체를 File*Service로 바꾸어 테스트해보세요.

서비스 구현체 분석

  • JCFService 구현체와 FileService 구현체를 비교하여 공통점과 차이점을 발견해보세요.
    • "비즈니스 로직"과 관련된 코드를 식별해보세요.
    • "저장 로직"과 관련된 코드를 식별해보세요.

레포지토리 설계 및 구현

  • "저장 로직"과 관련된 기능을 도메인 모델 별 인터페이스로 선언하세요.
    • 인터페이스 패키지명: com.sprint.mission.discodeit.repository
    • 인터페이스 네이밍 규칙: [도메인 모델 이름]Repository
  • 다음의 조건을 만족하는 레포지토리 인터페이스의 구현체를 작성하세요.
    • 클래스 패키지명: com.sprint.mission.discodeit.repository.jcf
    • 클래스 네이밍 규칙: JCF[인터페이스 이름]
    • 기존에 구현한 JCF*Service 구현체의 "저장 로직"과 관련된 코드를 참고하여 구현하세요.
  • 다음의 조건을 만족하는 레포지토리 인터페이스의 구현체를 작성하세요.
    • 클래스 패키지명: com.sprint.mission.discodeit.repository.file
    • 클래스 네이밍 규칙: File[인터페이스 이름]
    • 기존에 구현한 File*Service 구현체의 "저장 로직"과 관련된 코드를 참고하여 구현하세요.

심화 요구 사항

관심사 분리를 통한 레이어 간 의존성 주입

  • 다음의 조건을 만족하는 서비스 인터페이스의 구현체를 작성하세요.
    • 클래스 패키지명: com.sprint.mission.discodeit.service.basic
    • 클래스 네이밍 규칙: Basic[인터페이스 이름]
    • 기존에 구현한 서비스 구현체의 "비즈니스 로직"과 관련된 코드를 참고하여 구현하세요.
    • 필요한 Repository 인터페이스를 필드로 선언하고 생성자를 통해 초기화하세요.
    • "저장 로직"은 Repository 인터페이스 필드를 활용하세요. (직접 구현하지 마세요.)
  • Basic*Service 구현체를 활용하여 테스트해보세요.
  • JCF*Repository 구현체를 활용하여 테스트해보세요.
    • File*Repository 구현체를 활용하여 테스트해보세요.
    • 이전에 작성했던 코드(JCFService 또는 FileService)와 비교해 어떤 차이가 있는지 정리해보세요.

변경사항

  • 기본/심화 요구사항에 맞춰서 ServiceFactory 코드와 JavaApplication의 테스트 코드 변경

멘토에게

  • 시간의 문제로 JCF*Service에는 List만 코드를 변경했습니다.

@lkim0402 lkim0402 changed the title Leejun/sprint2 [김이준] Sprint2 Jun 12, 2025
import java.util.UUID;

public class FileUserRepository implements UserRepository {
private static final String FILE_PATH = "data/users.ser";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

data 디렉토리와 user.ser 파일에 대한 초기화는 필수 입니다.
존재여부 확인하고, 존재하지 않는다면, 새롭게 생성할 수 있도록 구현해야 합니다.


@Override
public void saveAll(List<User> users) {
try {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이런식으로 try-catch문을 사용 했다면,
필수적으로 finally문을 선언하고 FileIO와 관련된 리소스를 반환해주셔야 합니다.
fos.close
oos.close; 와 같은 코드의 형태로 말이죠.
그렇지 않다면, 리소스 부족으로 강제로 Applicaiton이 종료 될 수 있습니다.

boolean updated = false;

for (int i = 0; i < users.size(); i++) {
if (users.get(i).getId().equals(user.getId())) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

users.stream.filter 방식으로 구현했다면, 코드의 가독성을 더 극대화 시킬 수 있습니다.
참고하셔서 다시 한번 고쳐보시기를 권고 드립니다.

FileInputStream fis = new FileInputStream(FILE_PATH);
ObjectInputStream ois = new ObjectInputStream(fis);
messages = (List<Message>) ois.readObject();
} catch (IOException | ClassNotFoundException e) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RuntimeException으로 던지기 보다는 예외 처리가 발생한 Exception으로 던져주는 것이 더 많은 정보를 전달 할 수 있습니다.
그래서 아래와 같은 코드의 형태로 오류 처리하는 것을 추천드립니다.

catch (IOException e){
    trow new IOException();
} catch (ClassNotFoundException e) {
    trow new ClassNotFoundException();
}

}

@Override
public void updateUser(UUID id, User partialUser) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 코드는 아래와 같이 람다를 사용하면 좀 더 깔끔한 코드로 변경될 수 있습니다.

private <T> void applyIfNotNull(T value, Consumer<T> setter) {
    if (value != null) setter.accept(value);
}

@Override
public void updateUser(UUID id, User partialUser) {
    User user = findVerifiedUser(id);

    applyIfNotNull(partialUser.getUserName(), user::setUserName);
    applyIfNotNull(partialUser.getEmail(), user::setEmail);
    applyIfNotNull(partialUser.getPassword(), user::setPassword);
    applyIfNotNull(partialUser.getUserStatus(), user::setUserStatus);

    user.updateTimeStamp();
    userRepository.save(user);
}

@jinho-yoo-jack jinho-yoo-jack merged commit 51d00b1 into codeit-bootcamp-spring:김이준 Jun 16, 2025
lkim0402 pushed a commit to lkim0402/4-sprint-mission that referenced this pull request Jul 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants