Skip to content

Commit b344297

Browse files
committed
feat : application file factory 구현
1 parent 06d3b86 commit b344297

File tree

11 files changed

+470
-10
lines changed

11 files changed

+470
-10
lines changed

codeit-bootcamp-spring/1-sprint-mission/.gitignore

+3-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ bin/
4040

4141
### Mac OS ###
4242
.DS_Store
43-
/build/reports/
43+
44+
45+
/build
4446
/build/test-results/
4547
/build/reports/
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,40 @@
11
package com.sprint.mission.discodeit;
22

3-
import com.sprint.mission.discodeit.repository.file.user.FileUserRepository;
3+
import com.sprint.mission.discodeit.config.factory.ApplicationFileFactory;
4+
import com.sprint.mission.discodeit.entity.channel.dto.ChannelResponse;
5+
import com.sprint.mission.discodeit.entity.channel.dto.CreateNewChannelRequest;
6+
import com.sprint.mission.discodeit.entity.message.dto.DirectMessageInfoResponse;
7+
import com.sprint.mission.discodeit.entity.message.dto.SendDirectMessageRequest;
8+
import com.sprint.mission.discodeit.entity.user.dto.RegisterUserRequest;
9+
import com.sprint.mission.discodeit.entity.user.dto.UserInfoResponse;
410
import java.io.IOException;
11+
import java.util.UUID;
512

613
public class JavaApplication {
14+
private static final ApplicationFileFactory app = ApplicationFileFactory.getInstance();
15+
716
public static void main(String[] args) throws IOException {
8-
try (FileUserRepository repo = (FileUserRepository) FileUserRepository.getInstance()) {
9-
System.out.println("======================");
10-
repo.findAll().forEach(System.out::println);
11-
System.out.println("======================");
12-
}
17+
UserInfoResponse user = registerUser();
18+
ChannelResponse channelResponse = registerChannel(user.uuid(), "스프링부트_1기");
19+
UserInfoResponse receiveMessageUserTemp = registerUser();
20+
DirectMessageInfoResponse sendDirectMessage = sendDirectMessage(user.uuid(), receiveMessageUserTemp.uuid(), "안녕하세요");
21+
}
22+
23+
private static UserInfoResponse registerUser() {
24+
var userService = app.getUserService();
25+
var registerRequest = new RegisterUserRequest("홍길동");
26+
return userService.register(registerRequest);
27+
}
28+
29+
private static ChannelResponse registerChannel(UUID userId, String channelName) {
30+
var channelService = app.getChannelService();
31+
var channelCreateRequest = new CreateNewChannelRequest(userId, channelName);
32+
return channelService.createChannelOrThrow(channelCreateRequest);
33+
}
34+
35+
private static DirectMessageInfoResponse sendDirectMessage(UUID sendUserId, UUID receiveUserId, String message) {
36+
var directMessageService = app.getDirectMessageService();
37+
var sendDirectMessageRequest = new SendDirectMessageRequest(sendUserId, receiveUserId, message);
38+
return directMessageService.sendMessage(sendDirectMessageRequest);
1339
}
1440
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package com.sprint.mission.discodeit.config.factory;
2+
3+
import com.sprint.mission.discodeit.repository.file.channel.FileChannelRepository;
4+
import com.sprint.mission.discodeit.repository.file.message.FileChannelMessageRepository;
5+
import com.sprint.mission.discodeit.repository.file.message.FileDirectMessageRepository;
6+
import com.sprint.mission.discodeit.repository.file.user.FileUserRepository;
7+
import com.sprint.mission.discodeit.repository.jcf.channel.ChannelRepository;
8+
import com.sprint.mission.discodeit.repository.jcf.message.ChannelMessage.ChannelMessageRepository;
9+
import com.sprint.mission.discodeit.repository.jcf.message.directMessage.DirectMessageRepository;
10+
import com.sprint.mission.discodeit.repository.jcf.user.UserRepository;
11+
import com.sprint.mission.discodeit.service.channel.ChannelService;
12+
import com.sprint.mission.discodeit.service.jcf.JCFChannelMessageService;
13+
import com.sprint.mission.discodeit.service.jcf.JCFChannelService;
14+
import com.sprint.mission.discodeit.service.jcf.JCFDirectMessageService;
15+
import com.sprint.mission.discodeit.service.jcf.JCFUserService;
16+
import com.sprint.mission.discodeit.service.message.channelMessage.ChannelMessageService;
17+
import com.sprint.mission.discodeit.service.message.directMessage.DirectMessageService;
18+
import com.sprint.mission.discodeit.service.user.UserService;
19+
20+
public class ApplicationFileFactory implements AppFactory {
21+
22+
private static ApplicationFileFactory INSTANCE;
23+
24+
25+
private final UserRepository userRepository;
26+
private final UserService userService;
27+
28+
private final ChannelRepository channelRepository;
29+
private final ChannelService channelService;
30+
31+
private final DirectMessageService directMessageService;
32+
private final DirectMessageRepository directMessageRepository;
33+
34+
private final ChannelMessageService channelMessageService;
35+
private final ChannelMessageRepository channelMessageRepository;
36+
37+
private static class SingleInstanceHolder {
38+
private static final ApplicationFileFactory INSTANCE =
39+
new ApplicationFileFactory();
40+
}
41+
42+
public static synchronized ApplicationFileFactory getInstance() {
43+
return SingleInstanceHolder.INSTANCE;
44+
}
45+
46+
47+
private ApplicationFileFactory() {
48+
this.userRepository = FileUserRepository.getInstance();
49+
this.channelRepository = FileChannelRepository.getInstance();
50+
this.directMessageRepository = FileDirectMessageRepository.getInstance();
51+
this.channelMessageRepository = FileChannelMessageRepository.getInstance();
52+
53+
this.userService = JCFUserService.getInstance(userRepository);
54+
this.channelService = JCFChannelService.getInstance(userRepository, channelRepository);
55+
this.directMessageService = JCFDirectMessageService.getInstance(directMessageRepository, userRepository);
56+
this.channelMessageService = JCFChannelMessageService.getInstance(userRepository, channelRepository,
57+
channelMessageRepository);
58+
}
59+
60+
61+
@Override
62+
public UserService getUserService() {
63+
return userService;
64+
}
65+
66+
@Override
67+
public UserRepository getUserRepository() {
68+
return userRepository;
69+
}
70+
71+
@Override
72+
public ChannelRepository getChannelRepository() {
73+
return channelRepository;
74+
}
75+
76+
@Override
77+
public ChannelService getChannelService() {
78+
return channelService;
79+
}
80+
81+
@Override
82+
public DirectMessageService getDirectMessageService() {
83+
return directMessageService;
84+
}
85+
86+
@Override
87+
public DirectMessageRepository getDirectMessageRepository() {
88+
return directMessageRepository;
89+
}
90+
91+
@Override
92+
public ChannelMessageRepository getChannelMessageRepository() {
93+
return channelMessageRepository;
94+
}
95+
96+
@Override
97+
public ChannelMessageService getChannelMessageService() {
98+
return channelMessageService;
99+
}
100+
}

codeit-bootcamp-spring/1-sprint-mission/src/main/java/com/sprint/mission/discodeit/entity/message/DirectMessage.java

-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ public static DirectMessage ofMessageAndSenderReceiver(String message, User mess
2828
receiver1.getName(),
2929
message
3030
);
31-
System.out.println(format);
3231
};
3332

3433
return new DirectMessage(sender, message, messageSender, messageReceiver);

codeit-bootcamp-spring/1-sprint-mission/src/main/java/com/sprint/mission/discodeit/repository/file/channel/FileChannelRepository.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ protected FileChannelRepository() {
1414
store.putAll(loadFile());
1515
}
1616

17-
public ChannelRepository getInstance() {
17+
public static ChannelRepository getInstance() {
1818
if (FILE_USER_REPOSITORY_INSTANCE == null) {
1919
FILE_USER_REPOSITORY_INSTANCE = new FileChannelRepository();
2020
}

codeit-bootcamp-spring/1-sprint-mission/src/main/java/com/sprint/mission/discodeit/repository/file/message/FileDirectMessageRepository.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ protected FileDirectMessageRepository() {
1515
store.putAll(loadFile());
1616
}
1717

18-
public DirectMessageRepository getInstance() {
18+
public static DirectMessageRepository getInstance() {
1919
if (FILE_DIRECT_REPOSITORY_INSTANCE == null) {
2020
FILE_DIRECT_REPOSITORY_INSTANCE = new FileDirectMessageRepository();
2121
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package com.sprint.mission.discodeit.service.basic;
2+
3+
import com.sprint.mission.discodeit.common.error.ErrorMessage;
4+
import com.sprint.mission.discodeit.common.error.channel.ChannelException;
5+
import com.sprint.mission.discodeit.common.error.user.UserException;
6+
import com.sprint.mission.discodeit.entity.channel.Channel;
7+
import com.sprint.mission.discodeit.entity.message.ChannelMessage;
8+
import com.sprint.mission.discodeit.entity.message.dto.ChannelMessageInfoResponse;
9+
import com.sprint.mission.discodeit.entity.message.dto.SendChannelMessageRequest;
10+
import com.sprint.mission.discodeit.entity.user.entity.User;
11+
import com.sprint.mission.discodeit.repository.jcf.channel.ChannelRepository;
12+
import com.sprint.mission.discodeit.repository.jcf.message.ChannelMessage.ChannelMessageRepository;
13+
import com.sprint.mission.discodeit.repository.jcf.user.UserRepository;
14+
import com.sprint.mission.discodeit.service.message.channelMessage.ChannelMessageService;
15+
import com.sprint.mission.discodeit.service.message.converter.ChannelMessageConverter;
16+
import java.util.UUID;
17+
18+
public class BasicChannelMessageService implements ChannelMessageService {
19+
20+
private final UserRepository userRepository;
21+
private final ChannelRepository channelRepository;
22+
private final ChannelMessageRepository channelMessageRepository;
23+
private final ChannelMessageConverter converter;
24+
25+
private BasicChannelMessageService(
26+
UserRepository userRepository,
27+
ChannelRepository channelRepository,
28+
ChannelMessageRepository channelMessageRepository,
29+
ChannelMessageConverter converter
30+
) {
31+
this.userRepository = userRepository;
32+
this.channelRepository = channelRepository;
33+
this.channelMessageRepository = channelMessageRepository;
34+
this.converter = converter;
35+
}
36+
37+
public static ChannelMessageService getInstance(
38+
UserRepository userRepository,
39+
ChannelRepository channelRepository,
40+
ChannelMessageRepository channelMessageRepository
41+
) {
42+
var converter = new ChannelMessageConverter();
43+
return new BasicChannelMessageService(userRepository, channelRepository, channelMessageRepository, converter);
44+
}
45+
46+
@Override
47+
public ChannelMessageInfoResponse sendMessage(SendChannelMessageRequest sendChannelMessageRequest) {
48+
// 유저 찾기
49+
var foundUser = findUserByIdOrThrow(sendChannelMessageRequest.sendUserId());
50+
// 채널 찾기
51+
var foundChannel = findChannelByIdOrThrow(sendChannelMessageRequest.receiveChannelId());
52+
// 메시지 생성
53+
var channelMessage = ChannelMessage.ofMessageAndSenderAndReceiverChannel(
54+
sendChannelMessageRequest.message(),
55+
foundUser,
56+
foundChannel
57+
);
58+
// 메시지 저장
59+
var savedMessage = channelMessageRepository.save(channelMessage);
60+
// 메시지 전송
61+
savedMessage.sendMessage();
62+
// 생성된 메시지 반환
63+
return converter.toDto(savedMessage);
64+
}
65+
66+
/**
67+
* ==> 코드리뷰 부탁드립니다. 유저 서비스에 다른 서비스에서 이용하기 위한 메서드를 넣는게 바람직한가요?
68+
* ==> 제 생각은, 유저 서비스에 같은 기능으로 호출하는 기능이 필요하다면 추가하지만, 없다면 안넣는게 낫다고 생각함. 넣는다면 userRepository
69+
* 그런데, 유저 서비스에서 id로만 찾는 유저를 찾는 기능이 있는가? 구현한 내용은 유저 서비스 레이어 안에서만 private 구현
70+
* 코드 중복이 너무 많이 발생함, 이를 해결하기 위해 userService, userRepository 둘 중 하나에 메서드를 만드는 방법 중 어디가 좋을까요?
71+
*
72+
* ==> 다른 서비스 레이어를 의존하도록 해서 호출해도 괜찮을까요 ?
73+
*/
74+
private User findUserByIdOrThrow(UUID userId) {
75+
var foundUser = userRepository.findById(userId)
76+
.filter(User::isNotUnregistered)
77+
.orElseThrow(() -> UserException.ofErrorMessageAndId(
78+
ErrorMessage.USER_NOT_FOUND, userId.toString()
79+
));
80+
81+
return foundUser;
82+
}
83+
84+
85+
private Channel findChannelByIdOrThrow(UUID channelId) {
86+
var foundChannel = channelRepository.findById(channelId)
87+
.orElseThrow(() -> ChannelException.ofErrorMessageAndNotExistChannelId(
88+
ErrorMessage.CHANNEL_NOT_FOUND,
89+
channelId
90+
));
91+
return foundChannel;
92+
}
93+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package com.sprint.mission.discodeit.service.basic;
2+
3+
import static com.sprint.mission.discodeit.common.error.ErrorMessage.CHANNEL_NOT_FOUND;
4+
import static com.sprint.mission.discodeit.common.error.ErrorMessage.USER_NOT_FOUND;
5+
6+
import com.sprint.mission.discodeit.common.error.channel.ChannelException;
7+
import com.sprint.mission.discodeit.common.error.user.UserException;
8+
import com.sprint.mission.discodeit.entity.channel.dto.ChangeChannelNameRequest;
9+
import com.sprint.mission.discodeit.entity.channel.dto.ChannelResponse;
10+
import com.sprint.mission.discodeit.entity.channel.dto.CreateNewChannelRequest;
11+
import com.sprint.mission.discodeit.entity.channel.dto.DeleteChannelRequest;
12+
import com.sprint.mission.discodeit.entity.user.entity.User;
13+
import com.sprint.mission.discodeit.repository.jcf.channel.ChannelRepository;
14+
import com.sprint.mission.discodeit.repository.jcf.user.UserRepository;
15+
import com.sprint.mission.discodeit.service.channel.ChannelConverter;
16+
import com.sprint.mission.discodeit.service.channel.ChannelService;
17+
import java.util.UUID;
18+
19+
public class BasicChannelService implements ChannelService {
20+
21+
private final ChannelRepository channelRepository;
22+
private final UserRepository userRepository;
23+
private final ChannelConverter channelConverter;
24+
25+
private BasicChannelService(
26+
ChannelRepository channelRepository,
27+
UserRepository userRepository,
28+
ChannelConverter channelConverter
29+
) {
30+
this.channelRepository = channelRepository;
31+
this.userRepository = userRepository;
32+
this.channelConverter = channelConverter;
33+
}
34+
35+
public static ChannelService getInstance(UserRepository userRepository, ChannelRepository channelRepository) {
36+
return new BasicChannelService(channelRepository, userRepository, new ChannelConverter());
37+
}
38+
39+
@Override
40+
public ChannelResponse createChannelOrThrow(CreateNewChannelRequest request) {
41+
/**
42+
* ==> 코드리뷰 : 메서드 내부에 다른 메서드를 호출하면서 throw가 발생가능하다는 것을 코드 블록의 메서드의 이름에 추가해야할까요?
43+
* createChannel VS createChannelOrThrow
44+
*/
45+
var findUser = findUserByIdOrThrow(request.userId());
46+
47+
var createdChannel = findUser.openNewChannel(request.channelName());
48+
49+
channelRepository.save(createdChannel);
50+
userRepository.save(findUser);
51+
52+
return channelConverter.toDto(createdChannel);
53+
}
54+
55+
@Override
56+
public void changeChannelNameOrThrow(ChangeChannelNameRequest request) {
57+
var foundUser = findUserByIdOrThrow(request.userId());
58+
59+
var changedChannel = foundUser.changeChannelName(request.channelId(), request.newChannelName());
60+
61+
channelRepository.save(changedChannel);
62+
userRepository.save(foundUser);
63+
}
64+
65+
@Override
66+
public void deleteChannelByChannelIdOrThrow(DeleteChannelRequest request) {
67+
var foundChannel = channelRepository.findById(request.channelId())
68+
.orElseThrow(
69+
() -> ChannelException.ofErrorMessageAndNotExistChannelId(
70+
CHANNEL_NOT_FOUND,
71+
request.channelId())
72+
);
73+
74+
var foundUser = findUserByIdOrThrow(request.userId());
75+
foundChannel.deleteChannel(foundUser);
76+
77+
channelRepository.save(foundChannel);
78+
}
79+
80+
private User findUserByIdOrThrow(UUID id) {
81+
var foundUser = userRepository.findById(id)
82+
.filter(User::isNotUnregistered)
83+
.orElseThrow(() -> UserException.of(USER_NOT_FOUND));
84+
85+
return foundUser;
86+
}
87+
}

0 commit comments

Comments
 (0)