回答你的第一个问题。以下是一些你可能想考虑的想法
首先,构造子类,使它们都使用相同的初始化参数。此外,您还可以将其他一些启动代码(例如您的编码体和服务器访问器)放在那里。我的意思是:
class SOChatSubClass
attr_accessor :encoded_body, :server, :from, :to, :body
def initialize(event, room, server)
@encoded_body = event['content']
@server = server
SOChatEvent.events.push event
xmpp_message = event['message']
@from = xmpp_message.from
@to = xmpp_message.to
@body = xmpp_message.body
end
end
注意,在我的示例中,子类中仍然有重复的代码。理想情况下,您可以通过将副本放在适当的父类中来消除它。
如果在创建启动参数的公共列表时遇到问题,请更改类以接受参数列表作为哈希值{:event=>event,:room=>room,:server=>server,etc},而不是传入参数列表(event、room、server)。
不管怎样,一旦有了用于初始化类的公共参数结构,就可以更动态地初始化它们,从而不需要case语句。
class SOChatEvent
class << self; attr_accessor :events; end
@events = []
@@event_parser = {
0 => SOChatSubClass,
1 => SOChatMessage,
2 => SOChatMessageEdit,
}
def self.create_from_evt( json_event_data, room=nil, server=nil)
event_type = json_event_data["event_type"]
event_class = @@event_parser[event_type]
event_obj = event_class.new(json_event_data, room, server)
end
end
@@event_parser
包含事件类型与实现该事件类型的类之间的映射。您只需将适当的类分配给一个变量,并像对待实际的类一样对待它。
如下代码将创建适当类的对象:
event_obj = SOChatEvent.create_from_evt( json_event_data,
"some room",
"some server")
注意:有进一步的优化可以做什么,我提供了更干净和更简洁,但希望这有助于你克服驼峰的情况说明。
编辑:我忘了提到类实例变量
SOChatEvent.events
使用此创建:
class << self; attr_accessor :events; end
@events = []
您将事件推到事件堆栈上,但我不清楚您希望栈存在于哪里,它是否是全局事件列表,或者特定于特定的类。我所做的是全局的,所以如果您希望将事件堆栈约束到某些类或实例,可以随意更改它。