正确的客户端-服务器框架架构方法(不同的服务器版本)
Correct client-server framework architecture approach (different server versions)
我正在尝试设计和实现一个与服务器通信的框架(这是一个用 Swift 编写的 iOS 框架)。我面临的挑战是架构——有两种与服务器通信的方式,我必须实现这两种方式(不同版本)。我真的很想实现拥有一个无状态客户端,方法如下:Client.authenticate()
或 Client.downloadFile()
。问题是当有两个实现时,我最终会在我的客户端 class 中使用这样的方法:
public class func authenticate(state: state) {
if (state.type == 1) {
Client1.authenticate(state)
} else {
Client2.authenticate(state)
}
}
对每个方法重复...
我最初想保持这样的客户端 - 无状态和静态并且只有状态对象保存实际状态,因为可能有许多连接到具有各种状态的服务器。通过这种方式,我想避免将客户端作为一个对象,同时保持状态并执行对服务器的调用。问题是这种方法只是……我猜很脏。什么是更 DRY、可读和可持续的方式来做到这一点?
如果没有更多代码示例,我无法完全理解您的意图,但我将向您展示的模式肯定会为您解决问题。
如果您的客户端 class 总是使用 Client1
或 Client2
(或者更具体地说,如果您的每个客户端对象 state
变量在其实例中不发生变化lifetime) 你应该使用 Dependency Injection.
您创建了一个 procol
(让我们用 authenticate
方法(以及服务器客户端应实现的所有其他方法)将其称为 RemoteClient
并使 Client1
和 Client2
遵守该协议。
现在让您的客户端 class 在其构造函数中接受 RemoteClient
。
现在无论创建 Client 对象,它都可以决定将什么 注入 到构造函数中:Client1
具体 class 对象,或 Client2
.
关于Dependency Injection
的文章很多,所以我不会详细介绍。
您还可以使用策略设计模式,它非常相似但意图有点不同:
Difference between DI and Strategy
编辑
在您在下面的评论中阐明您想要做什么之后:
在这种情况下,您可以使用 reflection/metadata 并使用 dictionary/map 来调用您想要的客户端。
(伪代码)
enum ServerType
{
client1,
client2
}
Dictionary* serversDictionary; // key = ServerType , value = object of protocol type RemoteLocation
static init
{
serversDictionary[client1] = Client1.self; // using swift class metadata
serversDictionary[client2] = Client2.self; // using swift class metadata
}
static authenticate(ServerType type) {
let locationToSendAuthTo = serversDictionary[type];
locationToSendAuthTo.authenticate(type);
}
我不确定 Swift 是否这样工作,因为我才刚刚开始使用它。我不确定您是否可以在 class 类型上调用静态方法。文档对此非常薄弱。
更多信息在这里:
Swift class introspection & generics
我正在尝试设计和实现一个与服务器通信的框架(这是一个用 Swift 编写的 iOS 框架)。我面临的挑战是架构——有两种与服务器通信的方式,我必须实现这两种方式(不同版本)。我真的很想实现拥有一个无状态客户端,方法如下:Client.authenticate()
或 Client.downloadFile()
。问题是当有两个实现时,我最终会在我的客户端 class 中使用这样的方法:
public class func authenticate(state: state) {
if (state.type == 1) {
Client1.authenticate(state)
} else {
Client2.authenticate(state)
}
}
对每个方法重复...
我最初想保持这样的客户端 - 无状态和静态并且只有状态对象保存实际状态,因为可能有许多连接到具有各种状态的服务器。通过这种方式,我想避免将客户端作为一个对象,同时保持状态并执行对服务器的调用。问题是这种方法只是……我猜很脏。什么是更 DRY、可读和可持续的方式来做到这一点?
如果没有更多代码示例,我无法完全理解您的意图,但我将向您展示的模式肯定会为您解决问题。
如果您的客户端 class 总是使用 Client1
或 Client2
(或者更具体地说,如果您的每个客户端对象 state
变量在其实例中不发生变化lifetime) 你应该使用 Dependency Injection.
您创建了一个 procol
(让我们用 authenticate
方法(以及服务器客户端应实现的所有其他方法)将其称为 RemoteClient
并使 Client1
和 Client2
遵守该协议。
现在让您的客户端 class 在其构造函数中接受 RemoteClient
。
现在无论创建 Client 对象,它都可以决定将什么 注入 到构造函数中:Client1
具体 class 对象,或 Client2
.
关于Dependency Injection
的文章很多,所以我不会详细介绍。
您还可以使用策略设计模式,它非常相似但意图有点不同:
Difference between DI and Strategy
编辑
在您在下面的评论中阐明您想要做什么之后:
在这种情况下,您可以使用 reflection/metadata 并使用 dictionary/map 来调用您想要的客户端。
(伪代码)
enum ServerType
{
client1,
client2
}
Dictionary* serversDictionary; // key = ServerType , value = object of protocol type RemoteLocation
static init
{
serversDictionary[client1] = Client1.self; // using swift class metadata
serversDictionary[client2] = Client2.self; // using swift class metadata
}
static authenticate(ServerType type) {
let locationToSendAuthTo = serversDictionary[type];
locationToSendAuthTo.authenticate(type);
}
我不确定 Swift 是否这样工作,因为我才刚刚开始使用它。我不确定您是否可以在 class 类型上调用静态方法。文档对此非常薄弱。
更多信息在这里: Swift class introspection & generics