1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
| // Mediator 패턴의 우아함
// 1. Mediator 인터페이스
interface ChatMediator {
void sendMessage(Message message, User sender);
void addUser(User user);
void removeUser(User user);
void createGroup(String groupName, List<User> members);
void sendGroupMessage(String groupName, Message message, User sender);
}
// 2. Message 클래스
class Message {
private final String content;
private final MessageType type;
private final LocalDateTime timestamp;
private final String messageId;
public Message(String content, MessageType type) {
this.content = content;
this.type = type;
this.timestamp = LocalDateTime.now();
this.messageId = UUID.randomUUID().toString();
}
// getters
public String getContent() { return content; }
public MessageType getType() { return type; }
public LocalDateTime getTimestamp() { return timestamp; }
public String getMessageId() { return messageId; }
}
enum MessageType {
TEXT, IMAGE, FILE, SYSTEM_NOTIFICATION
}
// 3. 구체적인 Mediator 구현
class AdvancedChatRoom implements ChatMediator {
private final List<User> users;
private final Map<String, List<User>> groups;
private final List<MessageFilter> filters;
private final MessageLogger logger;
public AdvancedChatRoom() {
this.users = new ArrayList<>();
this.groups = new HashMap<>();
this.filters = new ArrayList<>();
this.logger = new MessageLogger();
}
@Override
public void addUser(User user) {
users.add(user);
user.setMediator(this);
// 시스템 알림
Message welcomeMessage = new Message(
user.getName() + " joined the chat",
MessageType.SYSTEM_NOTIFICATION
);
broadcastSystemMessage(welcomeMessage, user);
System.out.println("👋 " + user.getName() + " joined the chat room");
}
@Override
public void removeUser(User user) {
users.remove(user);
// 모든 그룹에서 제거
groups.values().forEach(group -> group.remove(user));
Message leaveMessage = new Message(
user.getName() + " left the chat",
MessageType.SYSTEM_NOTIFICATION
);
broadcastSystemMessage(leaveMessage, user);
System.out.println("👋 " + user.getName() + " left the chat room");
}
@Override
public void sendMessage(Message message, User sender) {
// 메시지 필터링
if (!applyFilters(message, sender)) {
System.out.println("🚫 Message blocked by filter");
return;
}
// 로깅
logger.logMessage(message, sender, users);
// 모든 사용자에게 전송 (발신자 제외)
for (User user : users) {
if (user != sender) {
user.receive(message, sender.getName());
}
}
}
@Override
public void createGroup(String groupName, List<User> members) {
// 유효한 사용자들만 필터링
List<User> validMembers = members.stream()
.filter(users::contains)
.collect(Collectors.toList());
groups.put(groupName, new ArrayList<>(validMembers));
Message groupCreatedMessage = new Message(
"Group '" + groupName + "' created with " + validMembers.size() + " members",
MessageType.SYSTEM_NOTIFICATION
);
// 그룹 멤버들에게만 알림
for (User member : validMembers) {
member.receive(groupCreatedMessage, "System");
}
System.out.println("👥 Group '" + groupName + "' created");
}
@Override
public void sendGroupMessage(String groupName, Message message, User sender) {
List<User> groupMembers = groups.get(groupName);
if (groupMembers == null) {
sender.receive(
new Message("Group '" + groupName + "' not found", MessageType.SYSTEM_NOTIFICATION),
"System"
);
return;
}
if (!groupMembers.contains(sender)) {
sender.receive(
new Message("You are not a member of group '" + groupName + "'", MessageType.SYSTEM_NOTIFICATION),
"System"
);
return;
}
// 메시지 필터링
if (!applyFilters(message, sender)) {
return;
}
// 로깅
logger.logGroupMessage(message, sender, groupName, groupMembers);
// 그룹 멤버들에게 전송 (발신자 제외)
for (User member : groupMembers) {
if (member != sender) {
member.receiveGroupMessage(message, sender.getName(), groupName);
}
}
}
public void addMessageFilter(MessageFilter filter) {
filters.add(filter);
}
private boolean applyFilters(Message message, User sender) {
for (MessageFilter filter : filters) {
if (!filter.isAllowed(message, sender)) {
return false;
}
}
return true;
}
private void broadcastSystemMessage(Message message, User excludeUser) {
for (User user : users) {
if (user != excludeUser) {
user.receive(message, "System");
}
}
}
public void printStatistics() {
System.out.println("=== Chat Room Statistics ===");
System.out.println("Total users: " + users.size());
System.out.println("Total groups: " + groups.size());
System.out.println("Total messages: " + logger.getTotalMessages());
}
}
// 4. User 추상 클래스
abstract class User {
protected ChatMediator mediator;
protected final String name;
protected final UserType userType;
public User(String name, UserType userType) {
this.name = name;
this.userType = userType;
}
public void setMediator(ChatMediator mediator) {
this.mediator = mediator;
}
public abstract void send(String messageContent);
public abstract void receive(Message message, String senderName);
public abstract void receiveGroupMessage(Message message, String senderName, String groupName);
public String getName() { return name; }
public UserType getUserType() { return userType; }
}
enum UserType {
REGULAR, MODERATOR, ADMIN
}
// 5. 구체적인 User 구현
class RegularUser extends User {
public RegularUser(String name) {
super(name, UserType.REGULAR);
}
@Override
public void send(String messageContent) {
if (mediator != null) {
Message message = new Message(messageContent, MessageType.TEXT);
mediator.sendMessage(message, this);
}
}
public void sendToGroup(String groupName, String messageContent) {
if (mediator != null) {
Message message = new Message(messageContent, MessageType.TEXT);
mediator.sendGroupMessage(groupName, message, this);
}
}
@Override
public void receive(Message message, String senderName) {
System.out.printf("📱 [%s] %s: %s\n",
name, senderName, message.getContent());
}
@Override
public void receiveGroupMessage(Message message, String senderName, String groupName) {
System.out.printf("👥 [%s] %s@%s: %s\n",
name, senderName, groupName, message.getContent());
}
}
class ModeratorUser extends RegularUser {
public ModeratorUser(String name) {
super(name);
}
public void kickUser(User user) {
if (mediator != null) {
mediator.removeUser(user);
System.out.println("🔨 " + name + " kicked " + user.getName());
}
}
@Override
public void receive(Message message, String senderName) {
System.out.printf("🛡️ [%s] %s: %s\n",
name, senderName, message.getContent());
}
}
// 6. 메시지 필터
interface MessageFilter {
boolean isAllowed(Message message, User sender);
}
class ProfanityFilter implements MessageFilter {
private final Set<String> bannedWords = Set.of("spam", "bad", "inappropriate");
@Override
public boolean isAllowed(Message message, User sender) {
String content = message.getContent().toLowerCase();
for (String bannedWord : bannedWords) {
if (content.contains(bannedWord)) {
System.out.println("🚫 Message from " + sender.getName() + " blocked: contains '" + bannedWord + "'");
return false;
}
}
return true;
}
}
class RateLimitFilter implements MessageFilter {
private final Map<User, List<LocalDateTime>> userMessageTimes = new HashMap<>();
private final int maxMessagesPerMinute = 10;
@Override
public boolean isAllowed(Message message, User sender) {
LocalDateTime now = LocalDateTime.now();
List<LocalDateTime> messageTimes = userMessageTimes.computeIfAbsent(sender, k -> new ArrayList<>());
// 1분 이전 메시지들 제거
messageTimes.removeIf(time -> time.isBefore(now.minusMinutes(1)));
if (messageTimes.size() >= maxMessagesPerMinute) {
System.out.println("🚫 Rate limit exceeded for " + sender.getName());
return false;
}
messageTimes.add(now);
return true;
}
}
// 7. 메시지 로거
class MessageLogger {
private int totalMessages = 0;
private final Map<String, Integer> userMessageCounts = new HashMap<>();
public void logMessage(Message message, User sender, List<User> recipients) {
totalMessages++;
userMessageCounts.merge(sender.getName(), 1, Integer::sum);
System.out.printf("📝 LOG: %s sent message to %d users at %s\n",
sender.getName(), recipients.size() - 1, message.getTimestamp());
}
public void logGroupMessage(Message message, User sender, String groupName, List<User> members) {
totalMessages++;
userMessageCounts.merge(sender.getName(), 1, Integer::sum);
System.out.printf("📝 LOG: %s sent group message to %s (%d members) at %s\n",
sender.getName(), groupName, members.size() - 1, message.getTimestamp());
}
public int getTotalMessages() {
return totalMessages;
}
public Map<String, Integer> getUserMessageCounts() {
return new HashMap<>(userMessageCounts);
}
}
// 사용 예시
class MediatorPatternDemo {
public static void main(String[] args) {
// 채팅방 생성
AdvancedChatRoom chatRoom = new AdvancedChatRoom();
// 필터 추가
chatRoom.addMessageFilter(new ProfanityFilter());
chatRoom.addMessageFilter(new RateLimitFilter());
// 사용자 생성 및 추가
User alice = new RegularUser("Alice");
User bob = new RegularUser("Bob");
User charlie = new RegularUser("Charlie");
User moderator = new ModeratorUser("ModeratorDave");
chatRoom.addUser(alice);
chatRoom.addUser(bob);
chatRoom.addUser(charlie);
chatRoom.addUser(moderator);
System.out.println("\n=== General Chat ===");
// 일반 채팅
alice.send("Hello everyone!");
bob.send("Hi Alice!");
charlie.send("Good morning!");
System.out.println("\n=== Group Creation ===");
// 그룹 생성
chatRoom.createGroup("developers", Arrays.asList(alice, bob, charlie));
System.out.println("\n=== Group Chat ===");
// 그룹 채팅
((RegularUser) alice).sendToGroup("developers", "Let's discuss the new project");
((RegularUser) bob).sendToGroup("developers", "Great idea!");
System.out.println("\n=== Filter Testing ===");
// 필터 테스트
alice.send("This message contains spam keyword");
System.out.println("\n=== Statistics ===");
// 통계 출력
chatRoom.printStatistics();
}
}
|