채팅 프로그램(feat. Command Pattern)
#Java/adv2/Network
- /채팅 프로그램 설계 - 클라이언트
- 기존 클라이언트는 콘솔에서 입력받는 부분에서 블로킹되기 때문에, 메시지가 도착해도 콘솔에 바로 출력할 수 없다.
- 콘솔 입력과 서버로부터 메시지를 받는 부분을 별도의 스레드로 분리
- /채팅 프로그램 설계 - 서버
- 서버에서 모든 세션을 관리해야, 하나의 클라이언트가 보낸 메시지를 서버가 받아서 모든 클라이언트에게 메시지를 전송할 수 있다. 이전 챕터의 세션 매니저를 잘 활용하자.
ReadHandler
,WriteHandler
: 두 작업을 별도의 스레드로 분리- 필드에 Client 참조를 추가하여, 서버와 연결 종료 시 finally에서
client.close()
를 호출하도록 함. - 중복 종료를 막기 위해 동기화 코드와
closed
플래그 사용 WriteHandler
의close()
close()
를 호출하면System.in.close()
를 통해 사용자의 콘솔 입력을 닫는다. 이렇게 하면Scanner
를 통한 콘솔 입력인scanner.nextLine()
코드에서 대기하는 스레드에NoSuchElementException
이 발생하면서 대기 상태에서 빠져 나온다.
- 필드에 Client 참조를 추가하여, 서버와 연결 종료 시 finally에서
- 이전 챕터의 session 코드에
CommandManager
를 추가한다. 명령어를 처리하는 기능을 제공하는 클래스이다.- 전송 받은 메시지를
commandManager.execute()
를 사용해서 실행한다.
- 전송 받은 메시지를
Session
의 생성 시점에sessionManager
에Session
을 등록한다.username
을 통해 클라이언트의 이름을 등록할 수 있다.- 예외가 발생하면 세션 매니저에서 세션을 제거하고, 나머지 클라이언트에게 퇴장 소식을 알린다. 그리고 자원을 정리한다
- if문으로 커맨드를 식별하여 로직 처리
- 문제점: 각각의 개별 기능을
CommandManager
안에 if문으로 덕지덕지 추가하는 것이 깔끔하지 않다.
- 각각의 명령어를 하나의
Command
(명령)로 보고 인터페이스와 구현체로 구분해보자.JoinCommand
,ExitCommand
, …
- 명령어를 관리하고 찾아서 실행하는
CommandManagerV3
를 만들자.private final Map<String, Command> commands = new HashMap<>();
로 커맨드 정보 등록
- 이전 예제에서
command
가 없는 경우에null
을 체크하고 처리해야 하는 부분이 좀 지저분하다. null
인 상황을 처리할 객체를 만든다.(DefaultCommand
)Map
에는getOrDefault(key, defaultObject)
라는 메서드가 존재한다.- 만약 key를 사용해서 객체를 찾을 수 있다면 찾고, 찾을 수 없다면 옆에 있는
defaultObject
를 반환한다. - 이 기능을 사용하면
null
을 받지 않고 항상Command
객체를 받아서 처리할 수 있다. - 이와 같이
null
을 객체(Object)처럼 처리하는 방법을 Null Object Pattern 이라 한다.
- 커맨드 패턴은 디자인 패턴 중 하나로, 요청을 독립적인 객체로 변환해서 처리한다.
- 분리: 작업을 호출하는 객체와 작업을 수행하는 객체를 분리한다.
- 확장성: 기존 코드를 변경하지 않고 새로운 명령을 추가할 수 있다.
- 장점
- 새로운 커맨드를 Command 구현체를 만듬으로써 쉽게 추가할 수 있다.
- if문에서 모든 작업 케이스를 관리할 필요가 없다.
- 각각의 기능이 명확하게 분리됨
- 단점
- 복잡성 증가: 간단한 작업을 수행하는 경우에도
Command
인터페이스와 구현체들, 호출, 관리 클래스 등 여러 클래스를 만들어야 하여 코드 복잡성이 증가할 수 있다.- if문 1~2개로 케이스가 나뉘는데, 커맨드 패턴을 사용하는 건 좋은 설계가 아닐 수 있다.
- 복잡성 증가: 간단한 작업을 수행하는 경우에도
- 기능이 어느 정도 있고, 각각의 기능이 명확하게 나누어질 수 있고, 향후 기능의 확장까지 고려해야 한다면 커맨드 패턴은 좋은 대안이 될 수 있다.
'Java > IO, Network' 카테고리의 다른 글
[Java] 53. HTTP 서버 만들기 (0) | 2025.07.01 |
---|---|
[Java] 51. 네트워크 - 프로그램(2) (0) | 2025.07.01 |
[Java] 50. 네트워크 - 프로그램(1) (0) | 2025.07.01 |
[Java] 49. File, Files (0) | 2025.07.01 |
[Java] 48. 자바 I/O 활용 (0) | 2025.07.01 |