Мой Чат.

Всем привет!
Хочу поделиться своим небольшим проектом:
Взял одну из больших задач (Чат) и изменил, обновил, добавил много нового и вот что из этого вышло:



Что изменено/добавлено по сравнению с оригинальной задачей:

— Конфигурацию читает из файла properties при помощи класса ResourceManager
— Добавлены чат румы и возможность клиенту создавать свои чаты
— Добавлены приватные сообщения
— Полностью новый swing интерфейс клиента
— Добавлены горячие клавиши для отправления сообщений и команд клиента
— Добавлено окно настроек
— Добавлены смайлики
— Сделаны вкладки для отображения сообщений из разных чат румов и приватных чатов
— Добавлен счетчик непрочитанных сообщений
— Сделано дерево пользователей для отображения пользователей в чатах и вызова приватных сообщений
— Бот научился отвечать смайликом на смайлик
— Добавил логгер log4j
— Добавил добавил тесты jUnit
— Завернул все это в мавен и разбил на модули

ссылка на гит хаб: github.com/DevCorvette/chat

Кому интересно, заходите, смотрите, комментируйте, буду рад :)
Конструктивной критике тоже буду рад.

P.S.: Тот кто еще не решал задачу — не ищите у меня готовых решений, там практически все переписано ;)

10 комментариев

Rushmore
Хорошая идея создать пользователей и комнаты в юморнофэнтезийной стилистике Семи королевств, а ля вк, но Jon пишется как John :)
KarmaHacker
Уууупс, опечаточка закралась :)
fatfaggy
  • fatfaggy
  • +1
  • Комментарий отредактирован 2017-11-01 21:24:28 пользователем fatfaggy
а почему сервер весь на статиках? :) чтоб было невозможно запустить два чата одновременно?

и тогда сразу еще вопрос: почему бы класс Client не сделать интерфейсом и вынести туда все необходимые методы для любой реализации интерфейса. чтоб если я например захочу написать свою реализацию клиента (например веб-клиент) — у меня не были бы связаны руки наследованием класса Client, а я смог бы наследоваться от любого другого класса, и просто реализовать недостающие методы. в том числе и те, которые выводят сообщения об ошибках (потому что сейчас они просто сыпятся в консоль, как я понял, а с веб-клиентом никто ту консоль не увидит. ну кроме сисадмина, который потом будет читать логи веб-сервера) :)
lichMax
ага, mvc или подобная архитектура — рулит!
KarmaHacker
В оригинальной задаче клиент был организован через MVC, но я был вынужден отказаться от данного подхода, потому что классы Swing содержат реализацию MVC внутри (например JTabbedPane и JTree) и разделить их на модель и отрображение не получается. Поэтому я не стал пытаться впихнуть невпихуемое.
В моей реализации класс Client — это контроллер, а модуль guiclient это отображение и модель вместе.
lichMax
Да ну, вы просто не умеете её готовить. Спокойно всё разделяется. Сам использовал такие комоненты свинга (тот же jtree и jtable). B то, что в свинге многие компоненты используют MVC, не мешает свою программу делать на MVC.
В моей реализации класс Client — это контроллер, а модуль guiclient это отображение и модель вместе.
А это какой-то херов изврат и говнокод. Не советую так больше делать. И не советую двигаться в этом направлении. Лучше получше изучите MVC или какое-нибудь трёх-тировое приложение.
KarmaHacker
Ну да подразумевалось, что клиентов будет много, а сервер один на всех. Хотя я не претендую на правильность данного решения, такой подход был в оригинальной задаче и я оставил его.
fatfaggy
да, когда клиентов много, а сервер один — это норм. это ж клиент-серверная архитектура в принципе :)
я немножко о другом. допустим есть компания, которой очень понравился ваш чат :) они себе даже специально закупили сервачек именно под чат. и хотели бы сделать примерно так:
общий чат для всех, и клиентов и сотрудников (ну допустим)
общий чат сотрудников
и отдельный чат для руководства и всякой там ылиты))
вот не нравятся им комнаты, хотят реально чтоб разные приложения для этого были.
а на серваке на своем могут только один инстанс сервера поднять потому что он на статиках. ну это грубый пример, конечно, но я вот именно что-то такое имел ввиду :)
KarmaHacker
Клиент специально сделал абстрактным классом. Все важные методы для подключения и взаимодействия с сервером реализованы в нем. Такие как: подключение к серверу, «рукопожатие» и прием сообщений. Если потребуется сделать новое отображение, достаточно наследоваться от Client и реализовать методы отображения сообщений и отображения списка пользователей. Все остальное остается под капотом и трогать это не нужно.

Сообщения об ошибках о которых нужно знать пользователю выводятся через метод showErrorMessage, его можно переопределить. (В классе GUIClient он переопределен) Логи же выводятся в консоль и в файл адрес которого прописывается в файле log4j.properties (сейчас адрес файла C:\Temp\chat_log.log) на сколько я понимаю это правильный подход.
fatfaggy
достаточно наследоваться от Client и реализовать методы отображения сообщений и отображения списка пользователей
Сообщения об ошибках о которых нужно знать пользователю выводятся через метод showErrorMessage
вот их в интерфейс и вынести бы :)

Все важные методы для подключения и взаимодействия с сервером реализованы в нем. Такие как: подключение к серверу, «рукопожатие» и прием сообщений.
а вот их, раз уж они для всех клиентов одинаковые — в контроллер типа :) или даже просто в какой-нибудь отдельный класс статическими методами, если они уже полностью написаны и переопределять их нет необходимости.

Логи же выводятся в консоль и в файл адрес которого прописывается в файле log4j.properties (сейчас адрес файла C:\Temp\chat_log.log) на сколько я понимаю это правильный подход.
да, системные сообщения логично писать в лог, тут абсолютно согласен :) просто я не очень вникал в код. так, на гитхабе просто поклацал классы посмотрел :)

в общем, я примерно так представлял бы такую программу:
в качестве контроллера — то, что у вас в классе Client. он бы обрабатывал подключения клиентов ну и вся бизнес-логика, так сказать, была бы в нем. моделью бы выступали данные, которые он получает/отправляет с сервера. и еще один отдельный класс, который бы имплементировал какой-нибудь интерфейс (с теми несколькими методами, типа, отображать сообщения и список пользователей), и этот класс уже именно работал бы со всеми теми JTabbedPane и JTree и просто «рисовал» бы данные, которые он получил от контроллера.
в таком случае было бы намного проще расширять ваше приложение другим людям, которые например хотели бы написать свой внешний вид (ну там другой фон, другие смайлики, кнопочки, другое расположение панелей). тогда достаточно было бы переопределить те 3 метода типа showMessage(), showUsers(), showErrorMessage() и все. а все остальное пусть делают как хотят :) даже если кто-то захочет написать какой-нибудь CLI, хехе (линуксовые админы любят консоль больше, чем всякие красивые GUI) — ему не нужно будет за собой тянуть те JTabbedPane и JTree (что произойдет в случае наследования), ну или тот же веб-клиент, как я уже говорил. не, ну а че, у скайпа есть веб-клиент, почему бы и тут не запилить?)

еще раз. я не говорю что так надо было делать, или наоборот не надо было. я просто предложил вариант, который мне показался более простым в плане расширения функционала :)
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.