我正在用 Haxe 编写代码。不过,这与问题无关,只要您记住它是一种高级语言并且可以与 Java、ActionScript、JavaScript、C# 等进行比较(我在这里使用伪代码)。
我要从事一个大项目,现在正忙着准备。对于这个问题,我将创建一个小场景:一个简单的应用程序,它有一个 Main 类(这个在应用程序启动时执行)和一个 LoginScreen 类(这基本上是一个加载登录屏幕的类,以便用户可以登录)。
通常我猜这看起来像下面这样:
Main constructor:
loginScreen = new LoginScreen()
loginScreen.load();
LoginScreen load():
niceBackground = loader.loadBitmap("somebg.png");
someButton = new gui.customButton();
someButton.onClick = buttonIsPressed;
LoginScreen buttonIsPressed():
socketConnection = new network.SocketConnection();
socketConnection.connect(host, ip);
socketConnection.write("login#auth#username#password");
socketConnection.onData = gotAuthConfirmation;
LoginScreen gotAuthConfirmation(response):
if response == "success" {
//login success.. continue
}
这个简单的场景为我们的类添加了以下依赖项和缺点:
- 没有 LoginScreen 将无法加载 Main
- 没有自定义加载器类,LoginScreen 将无法加载
- 如果没有我们的自定义按钮类,LoginScreen 将无法加载
- 如果没有我们的自定义 SocketConnection 类,LoginScreen 将无法加载
- 现在LoginScreen里面已经设置了SocketConnection(以后会被很多不同的类访问),除了LoginScreen第一次需要socket连接之外,其实和它没什么关系
为了解决这些问题,有人建议我做“事件驱动编程”,或者说松耦合。据我了解,这基本上意味着必须使类彼此独立,然后将它们绑定在单独的绑定器中。
那么问题1:我对此的看法是真的还是假的?一定要用粘合剂吗?
我听说面向方面的编程可以在这里提供帮助。不幸的是,Haxe 不支持这种配置。
但是,我确实可以访问一个事件库,该库基本上允许我创建一个信号器 (public var loginPressedSignaller = new Signaller())、触发一个信号器 (loginPressedSignaller.fire()) 并收听一个信号器 (someClass.loginPressedSignaller .bind(doSomethingWhenLoginPressed))。
因此,几乎没有进一步调查,我认为这会将我之前的设置更改为:
Main:
public var appLaunchedSignaller = new Signaller();
Main constructor:
appLaunchedSignaller.fire();
LoginScreen:
public var loginPressedSignaller = new Signaller();
LoginScreen load():
niceBackground = !!! Question 2: how do we use Event Driven Programming to load our background here, while not being dependent on the custom loader class !!!
someButton = !!! same as for niceBackground, but for the customButton class !!!
someButton.onClick = buttonIsPressed;
LoginScreen buttonIsPressed():
loginPressedSignaller.fire(username, pass);
LoginScreenAuthenticator:
public var loginSuccessSignaller = new Signaller();
public var loginFailSignaller = new Signaller();
LoginScreenAuthenticator auth(username, pass):
socketConnection = !!! how do we use a socket connection here, if we cannot call a custom socket connection class !!!
socketConnection.write("login#auth#username#password");
此代码尚未完成,例如。我仍然需要听服务器的响应,但你可能明白我卡在哪里了。
问题 2:这种新结构有意义吗?我应该如何解决上面提到的问题!!!分隔符?
然后我听说了活页夹。所以也许我需要为每个类创建一个活页夹,将所有东西连接在一起。像这样的东西:
MainBinder:
feature = new Main();
LoginScreenBinder:
feature = new LoginScreen();
MainBinder.feature.appLaunchedSignaller.bind(feature.load);
niceBackgroundLoader = loader.loadBitmap;
someButtonClass = gui.customButton();
等等......希望你明白我的意思。这篇文章有点长,所以我必须把它包起来。
问题3:这有意义吗?这不会使事情变得不必要的复杂吗?
此外,在上面的“Binders”中,我只需要使用实例化一次的类,例如。登录屏幕。如果一个类有多个实例怎么办,例如。国际象棋游戏中的玩家类。