Chat Application
A messaging app that treats a one-to-one conversation and a group conversation as the same class, and treats "who's online" as a question separate from "who said what."
Requirements
Functional
- Two users can start a direct chat and exchange text messages.
- A group of users can share a chat room where every member sees every message.
- A user's messages show up in order within a room, to everyone in it.
- Other users can see whether a given user is currently online.
Non-functional
- Adding a group chat feature must not require a separate code path from direct chat - a direct chat is just a room with two members.
- Presence updates (online/offline) must reach members without those members polling for it on every message send.
Design
ChatRoom doesn't distinguish direct from group - it's a set of Users and an ordered
list of Messages either way. A ChatService creates rooms and routes sends; a
PresenceTracker owns online/offline state and notifies interested rooms, so a message
send never has to ask "is this person online" itself.
- 1The sender only knows a room id - never whether the room is direct or group.
- 2The service looks up the room and appends the message; the room enforces membership.
- 3Every room keeps one ordered message list, regardless of member count.
- 4Presence is updated independently of any message being sent.
- 5The tracker calls back into every registered room; each room ignores the update unless the user is actually one of its members.
The only thing that varies between "direct" and "group" is how the room got created - two users versus a roster - never how a message flows through it once it exists.
Class diagram
implementsuses
Code
Design decisions
- No
DirectChatRoom/GroupChatRoomsubclasses. A direct chat is aChatRoomwith exactly two members; nothing about sending, ordering, or reading a message differs by member count, so a subclass hierarchy would exist only to enforce "exactly two," which a factory method (ChatService.createDirectChat) can do just as well without the extra types. - Presence is a separate tracker, not a field the room polls. If
ChatRoomasked each member "are you online" on every send, presence and messaging would be coupled for no reason.PresenceTrackerinstead pushes status changes outward as events, so a room only reacts when something actually changes. Messageis immutable once created. A sent message never mutates - edits or deletes in a real system would be new events referencing the original message's id, not a change to the message object, which keeps message ordering and delivery guarantees simple to reason about.- What's missing for a real system: this models everything in-memory and synchronously; a production version would persist messages before acknowledging the sender, page a room's history instead of loading it whole, and give the client a way to know it's missed messages while offline (a per-user last-read cursor per room).