我是一个老的VB6开发人员,我正在尝试学习一些OOP方法。我正在开发一个Winforms应用程序,该应用程序具有多个在应用程序生命周期内存在的对象,例如与其他计算机上运行的应用程序的日志记录,音频和套接字连接。某些事情(如按下按钮或接收到的消息)可以触发与一个或多个这些对象相关的操作。例如,当用户单击“登录”按钮时,我可能希望将其记录到文件,打开套接字连接,向用户播放音频以及启动麦克风。看起来Command模式可能会做我想要的,但是当有这么多时,我如何干净地传递依赖关系呢?所以它可能看起来像:
Public Interface ICommand
Sub Execute()
End Interface
Public Class LoginCommand
Implements ICommand
Protected _Receiver As LoginCommandReceiver
Public Sub New(Receiver As LoginCommandReceiver)
_Receiver = Receiver
End Sub
Public Sub Execute() Implements ICommand.Execute
_Receiver.Login()
End Sub
End Class
Public Class LoginCommandReceiver
Protected _Logger As LogManager
Protected _Gateway As IGatewayConnection
Protected _Audio As IAudioPlayer
Protected _VR As IVREngine
Public Sub New(Logger As LogManager, Gateway As IGatewayConnection, Audio As IAudioPlayer, VR As IVREngine)
_Logger = Logger
_Audio = Audio
_Gateway = Gateway
_VR = VR
End Sub
Public Sub Login()
_Logger.LogEvent("Starting login")
_Audio.PlayRingtone()
_Gateway.Connect()
_VR.Start()
_Logger.LogEvent("Login complete")
End Sub
End Class
现在,即使在这个简单的例子中,LoginCommandReceiver的构造函数也变得混乱了。我想过将所需的依赖项放入容器类中。然后构造函数可以如下所示:
Public Sub New(Container As ApplicationContainer)
With Container
_Logger = .Logger
_Audio = .Audio
_Gateway = .Gateway
_VR = .VR
End With
End Sub
我实际上已经构建了这个容器类(没有Command模式)但是容器类变得非常大(差不多30个对象),并且将这个巨大的东西传递给只需要一个的类是不对的。它包含的部分。服务定位器模式似乎是合适的,但我正在阅读,应该避免。
我还考虑过将每个步骤作为自己的命令,如LogCommand,PlayRingtoneCommand,GatewayConnectCommand和VRStartCommand。然后每个子命令只需要知道一个应用程序级对象。例如,播放铃声只需要知道音频对象:
Public Class PlayRingtoneCommand
Implements ICommand
Protected _Receiver As PlayRingtoneCommandReceiver
Public Sub New(Receiver As PlayRingtoneCommandReceiver)
_Receiver = Receiver
End Sub
Public Sub Execute() Implements ICommand.Execute
_Receiver.PlayRingtone()
End Sub
End Class
Public Class PlayRingtoneCommandReceiver
Protected _Audio As IAudioPlayer
Public Sub New(Audio As IAudioPlayer)
_Audio = Audio
End Sub
Public Sub PlayRingtone()
_Audio.PlayRingtone()
End Sub
End Class
现在每个命令在其构造函数中都有一个对象,它更干净。但在某个地方,有人仍然必须知道所有对象才能创建命令列表。在制作这个巨型容器之外,我将所有对象实例放在一起的另一个时间是在程序启动时我将所有连接在一起。我是否需要在此时创建所有命令类型的实例?可能会有很多。或者是否有其他设计可以使这个更干净?