我不确定这个问题是否属于这里,因为它是“有争议的”,但让我们试一试。
在阅读了很多关于它的例子和问题(比如 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所以它是一个不同的故事),所以添加新功能应该是添加一个案例和一个方法,而不是那很难。该项目不会增长太多,但我希望它能够轻松扩展。
我应该坚持使用OOP设计并为每个到达的消息创建一个对象并应用多态?自服务器处理聊天消息以来,似乎有点压倒性。
答案 0 :(得分:1)
一方面,在一天结束时,这对您有用,并且相对容易维护。完全的OOP可能只是纯粹和/或自我的练习。
如果您将OOP方法提升到下一级别,如果是我,我将创建一个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);
}
...
}
我不太确定我要把这一切都放在哪里。我的主要观点是,您可以使其更加面向对象,这将使其更具灵活性和可扩展性,但这也会带来更多可维护性方面的困难。这真的是一个偏好和项目范围的问题(即它是一个由很多人维护的大型项目,还是你在业余时间玩的业余爱好剧本?)