Skip to content

[김찬호] Sprint1 #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: 김찬호
Choose a base branch
from

Conversation

cheis11
Copy link
Collaborator

@cheis11 cheis11 commented Jun 2, 2025

요구사항

기본 요구사항

프로젝트 초기화

  • IntelliJ를 통해 다음의 조건으로 Java 프로젝트를 생성합니다.
      • IntelliJ에서 제공하는 프로젝트 템플릿 중 Java를 선택합니다.
      • 프로젝트의 경로는 스프린트 미션 리포지토리의 경로와 같게 설정합니다.
      • 예를 들어 스프린트 미션 리포지토리의 경로가 /some/path/1-sprint-mission 이라면:
        • Name은 1-sprint-mission
        • Location은 /some/path
          으로 설정합니다.
      • Create Git Repository 옵션은 체크하지 않습니다.
      • Build system은 Gradle을 사용합니다. Gradle DSL은 Groovy를 사용합니다.
      • JDK 17을 선택합니다.
      • GroupId는 com.sprint.mission로 설정합니다.
      • ArtifactId는 수정하지 않습니다.
      • .gitignore에 IntelliJ와 관련된 파일이 형상관리 되지 않도록 .idea디렉토리를 추가합니다.
        ... .idea ...

도메인 모델링

  • 디스코드 서비스를 활용해보면서 각 도메인 모델에 필요한 정보를 도출하고, Java Class로 구현하세요.
      • 패키지명: com.sprint.mission.discodeit.entity
      • 도메인 모델 정의
        • 공통
          • id: 객체를 식별하기 위한 id로 UUID 타입으로 선언합니다.
          • createdAt, updatedAt: 각각 객체의 생성, 수정 시간을 유닉스 타임스탬프로 나타내기 위한 필드로 Long 타입으로 선언합니다.
        • User
        • Channel
        • Message
      • 생성자
        • id는 생성자에서 초기화하세요.
        • createdAt는 생성자에서 초기화하세요.
        • id, createdAt, updatedAt을 제외한 필드는 생성자의 파라미터를 통해 초기화하세요.
      • 메소드
        • 각 필드를 반환하는 Getter 함수를 정의하세요.
        • 필드를 수정하는 update 함수를 정의하세요.

서비스 설계 및 구현

  • 도메인 모델 별 CRUD(생성, 읽기, 모두 읽기, 수정, 삭제) 기능을 인터페이스로 선언하세요.
      • 인터페이스 패키지명: com.sprint.mission.discodeit.service
      • 인터페이스 네이밍 규칙: [도메인 모델 이름]Service
    • 다음의 조건을 만족하는 서비스 인터페이스의 구현체를 작성하세요.
      • 클래스 패키지명: com.sprint.mission.discodeit.service.jcf
      • 클래스 네이밍 규칙: JCF[인터페이스 이름]
      • Java Collections Framework를 활용하여 데이터를 저장할 수 있는 필드(data)를 final로 선언하고 생성자에서 초기화하세요.
      • data 필드를 활용해 생성, 조회, 수정, 삭제하는 메소드를 구현하세요.

메인 클래스 구현

  • 메인 메소드가 선언된 JavaApplication 클래스를 선언하고, 도메인 별 서비스 구현체를 테스트해보세요.
      • 등록
      • 조회(단건, 다건)
      • 수정
      • 수정된 데이터 조회
      • 삭제
      • 조회를 통해 삭제되었는지 확인

기본 요구사항 커밋 태그

  • 여기까지 진행 후 반드시 커밋해주세요. 그리고 sprint1-basic 태그를 생성해주세요.

심화

서비스 간 의존성 주입

  • 도메인 모델 간 관계를 고려해서 검증하는 로직을 추가하고, 테스트해보세요.
    • 힌트: Message를 생성할 때 연관된 도메인 모델 데이터 확인하기

주요 변경사항

    • 양방향 연결
      • User, Message, Channel끼리의 관계를 양방향으로 연결
    • 클래스 상속
      • User, Message, Channel에서 중복된 멤버를 BaseEntity에 추가하여 각 클래스에 상속
    • 클래스 상태 추가
      • User, Message, Channel 각각의 상태를 열거형으로 [도메인 모델 이름]State로 구현
        • 삭제된 User, Message, Channel은 출력이나 수정이 불가능
    • 팩토리 패턴 구현
      • 구현체를 메인에서 선언하는 것이 아닌 ServiceFactory라는 클래스를 만들어 팩토리 패턴을 구현

스크린샷

image

멘토에게

  • 셀프 코드 리뷰를 통해 질문 이어가겠습니다.

@cheis11 cheis11 changed the base branch from main to 김찬호 June 10, 2025 02:46

test {
useJUnitPlatform()
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

EOL 해결해주세요.
나중에 git에서 무의미한 diff 가 찍힐 수 있습니다.

@@ -0,0 +1 @@
rootProject.name = '1-sprint-mission'
Copy link
Collaborator

Choose a reason for hiding this comment

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

EOL 해결해주세요.

Comment on lines +4 to +5
protected final Long createdAt;
protected Long updatedAt;
Copy link
Collaborator

Choose a reason for hiding this comment

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

멤버 변수는 private 으로 선언하시는게 좋습니다. 캡슐화를 위해서요.

Comment on lines +12 to +13
private List<User> users;
private List<Message> messages;
Copy link
Collaborator

Choose a reason for hiding this comment

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

리스트는 선언과 동시에 초기화 해주시는게 좋습니다.

Comment on lines +44 to +68
public void addUser(User user) {
if(!users.contains(user)) {
users.add(user);
user.addChannel(this);
}
}
public void removeUser(User user) {
if(users.contains(user)) {
users.remove(user);
user.removeChannel(this);
}
}

public void addMessage(Message message) {
if(!messages.contains(message)) {
messages.add(message);
message.addChannel(this);
}
}
public void removeMessage(Message message) {
if(messages.contains(message)) {
messages.remove(message);
message.removeChannel(this);
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

if 문에서는 예외를 처리하고, 그 밖에서 비지니스 로직이 처리되도록 구성해보세요.

private ChannelState(String state) {
this.state = state;
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

EOL 해결해주세요.

DEACTIVATED("비활성화"),
DELETED("삭제");

private String state;
Copy link
Collaborator

Choose a reason for hiding this comment

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

description이라고 명명해도 괜찮을것 같습니다.

private Channel channel;
private String contents;
private MessageState state;

Copy link
Collaborator

Choose a reason for hiding this comment

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

이런 의미 없는 공백은 제거해주시는게 좋습니다.
spotless 같은 코드 포맷팅 툴 설치해서 돌려주시면 이런 문제는 해결할 수 있습니다.

Comment on lines +17 to +19
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
String created = sdf.format(new Date(createdAt));
String updated = sdf.format(new Date(updatedAt));
Copy link
Collaborator

Choose a reason for hiding this comment

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

이런 코드가 중복되네요. 이런 경우는 Util 클래스로 빼는것도 괜찮습니다.

Comment on lines +40 to +65
public void addChannel(Channel channel) {
if(this.channel == null) {
this.channel = channel;
channel.addMessage(this);
}
}

public void removeChannel(Channel channel) {
if(this.channel != channel) {
this.channel = null;
channel.removeMessage(this);
}
}

public void addUser(User user) {
if(this.user == null) {
this.user = user;
user.addMessage(this);
}
}
public void removeUser(User user) {
if(this.user != user) {
this.user = null;
user.removeMessage(this);
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

if 안에서 조건만족할때만 비지니스로직이 돌면 나중에 실 운영에서 이슈가 있습니다.
if 안에서는 조건 만족하지 않을 경우에 대한 예외처리를 하고 바깥에서 비지니스 로직을 처리해보시기 바랍니다.

package com.sprint.mission.discodeit.entity;

public enum MessageState {
VISIBLE(""),
Copy link
Collaborator

Choose a reason for hiding this comment

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

"" 로 두지마시고 이것도 설명 달아주시면 좋을것 같습니다.

INVISIBLE("숨김"),
DELETED("삭제");

private String state;
Copy link
Collaborator

Choose a reason for hiding this comment

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

description 정도면 적당할듯합니다.

Comment on lines +44 to +68
public void addChannel(Channel channel) {
if(!channels.contains(channel)) {
channels.add(channel);
channel.addUser(this);
}
}
public void removeChannel(Channel channel) {
if(channels.contains(channel)) {
channels.remove(channel);
channel.removeUser(this);
}
}

public void addMessage(Message message) {
if(!messages.contains(message)) {
messages.add(message);
message.addUser(this);
}
}
public void removeMessage(Message message) {
if(messages.contains(message)) {
messages.remove(message);
message.removeUser(this);
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

이것도 위의 코멘트 보시면서 수정해보세요!

public String getState() {
return state;
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

EOL 해결해주세요.

public void leaveUser(Channel channel, User user);//채널에서 유저 추방
public void deleteChannel(Channel channel);//채널 삭제

}
Copy link
Collaborator

Choose a reason for hiding this comment

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

eol 해결해주세요.


public interface ChannelService {
public Channel createChannel(Channel channel);//채널 생성
public List<Channel> getChannels();//모든 채널 출력
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
public List<Channel> getChannels();//모든 채널 출력
public List<Channel> getAllChannels();//모든 채널 출력


public interface MessageService {
public Message addMessage(Message message);//메세지 입력
public List<Message> getMessages();//모든 메세지 출력
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
public List<Message> getMessages();//모든 메세지 출력
public List<Message> getAllMessages();//모든 메세지 출력


public interface UserService {
public User addUser(User user);//유저 가입
public List<User> getUsers();//모든 유저 출력
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
public List<User> getUsers();//모든 유저 출력
public List<User> getAllUsers();//모든 유저 출력

public void updateUser(UUID userId, String updatedText);//유저 이름 수정
public void deleteUser(User user);//유저 탈퇴
public List<Message> findMessagesByUser(User user);//유저가 쓴 메세지 출력
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

EOL 해결해주세요.

Comment on lines +30 to +35
public Optional<Channel> findChannelById(UUID channelId) {
return data.stream()
.filter(channel -> channel.getChannelId().equals(channelId))
.filter(channel -> channel.getState() != ChannelState.DELETED)
.findFirst();
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

만약 결과가 empty인 경우 예외처리를 하고 Channel을 리턴하도록 바꿔보세요.

}

@Override
public Optional<User> findUserById(UUID UserId) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

만약 결과가 empty인 경우 예외처리를 하고 User를 리턴하도록 바꿔보세요.

}

@Override
public Optional<Message> findMessageById(UUID messageId) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

만약 결과가 empty인 경우 예외처리를 하고 Message를 리턴하도록 바꿔보세요.

joongwonAn added a commit to joongwonAn/4-sprint-mission that referenced this pull request Jun 15, 2025
jinho-yoo-jack pushed a commit that referenced this pull request Jun 16, 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