2015-12-18 3 views
2

Я не уверен, что этот вопрос принадлежит здесь, так как он «спорный», но давайте попробуем.Удаление инструкции коммутатора Запах с сервера Websocket

После прочтения много примеров и вопросов об этом (как this one, который кажется очень похож), я до сих пор не могу понять, если я должен выбрать для полиморфизма, чтобы заменить выключатель.

Это все о сервере Ratchet WebSocket, который принимает сообщения в формате JSON и выполняет подпрограмму в зависимости от сообщения type:

public function onMessage(ConnectionInterface $from, $msg) { 
    /*! 
    Triggers everytime a message is received by the application. 
    Depending on @p $msg type, the application will broadcast @p $msg accordingly. 

    @param ConnectionInterface $from 
    This is the socket (client) who sent @p $msg. 
    @param string $msg 
    A JSON string sent by the client. 
    */ 
    $usermsg = json_decode($msg, true); 
    if (isset($usermsg["message"])) { 
     $actual_msg = $this->removeHTML($usermsg["message"]); 
    } 

    switch ($usermsg["type"]) { 

     case 'text': 
      $this->text($from, $actual_msg, "text"); 
      break; 

     case 'token': 
      $this->token($from, $usermsg["im"]); 
      break; 

     case "ready": 
      $this->ready($from); 
      break; 

     case "action": 
      $this->text($from, $actual_msg, "action"); 
      break; 

     case "users": 
      $this->whoIsOnline($from); 
      break; 

     case "listen": 
      $this->listen($from); 
      break; 

     case "end": 
      $this->finish($from, $actual_msg); 
      break; 

     case 'statInit': 
      $this->statInit($from); 
      break; 
    } 
} 

вещи, $msg является строкой, так как это JSON, ни один объект не конкретизируется для любого сообщения который приходит на всех. Вот почему нет иерархии классов, потому что сообщения не являются объектами. На самом деле, нет другого класса, кроме реального сервера.

В любом случае, это единственный коммутатор, который существует на стороне сервера (в клиенте есть еще один, но это jQuery, так что это совсем другая история), поэтому добавление новых функций должно заключаться в добавлении case AND метода, не так сложно. Проект не будет много расти, но я бы хотел, чтобы его легко масштабировали.

Должен ли я придерживаться дизайна ООП и создавать объект для каждого сообщения, которое приходит и применяет полиморфизм? Кажется немного подавляющим, так как сервер обрабатывает сообщения чата.

ответ

1

С одной стороны, в конце дня это работает для вас и относительно легко обслуживается. Выполнение полного ООП может быть просто упражнением в чистоте и/или эго.

Если бы вы приняли подход ООП на следующий уровень, если бы это был я, я бы создал класс SocketMessage, который принимает строку сообщения JSON в конструкторе. Я бы также создал класс SocketHandler с отдельными классами обработчиков для каждого типа сообщения, который его расширяет. Некоторый грубый код, как ваш метод будет выглядеть после этого является:

public function onMessage(ConnectionInterface $from, $json) 
{ 
    $message = new SocketMessage($json); 
    return $message->dispatch(); 
} 

dispatch() вызова будет частью SocketMessage класса и будет определять, какой обработчик, чтобы направить его в зависимости от типа сообщения. Он знал бы, какие обработчики были доступны, потому что вы сначала зарегистрировали их с базовым классом SocketHandler.

// Somewhere that you initialize code 
SocketHandler::register('text', Handlers\TextHandler::class); 
SocketHandler::register('token', Handlers\TokenHandler::class); 
SocketHandler::register('ready', Handlers\ReadyHandler::class); 

Регистрация обработчика будет просто помещать их в статический массив в класс, к которому будет обращаться позже. Внутри функции SocketMessage::dispatch(), вы, вероятно, сделать что-то вроде этого:

class SocketMessage 
{ 
    ... 
    public function __construct($json) 
    { 
     // Parse raw message data 
     $this->message = @json_decode($json, true); 
     if (empty($this->message)) { 
      throw new Exception('SocketMessage expects a valid JSON string.'); 
     } 
    } 
    ... 
    public function dispatch() 
    { 
     $type = $this->message['type']; 
     $handler = SocketHandler::get($type); 

     return $handler->handle($this->message); 
    } 
    ... 
} 

Я не совсем уверен, где я буду со всем этим. Главное, что вы можете сделать его более объектно ориентированным, что приведет к его большей гибкости и расширяемости, но это также может привести к большим трудностям с ремонтопригодностью. Это действительно вопрос предпочтений и объема проекта (т. Е. Это будет большой проект, поддерживаемый множеством людей, или это сценарий хобби, с которым вы играете в свое свободное время?)

+0

Это дает мне хорошую перспективу на чем работать дальше. Поскольку этот проект похож на сценарий «хобби», я должен оставить его на странице. Спасибо за ваше понимание. –

Смежные вопросы