【问题标题】:Correct client-server framework architecture approach (different server versions)正确的客户端-服务器框架架构方法(不同的服务器版本)
【发布时间】:2015-04-28 15:49:24
【问题描述】:

我正在尝试设计和实现一个与服务器通信的框架(它是一个用 Swift 编写的 iOS 框架)。我面临的挑战是架构 - 有两种与服务器通信的方式,我必须同时实现这两种方式(不同的版本)。我真的很想实现拥有一个无状态客户端,方法如下:Client.authenticate()Client.downloadFile()。问题是当有两个实现时,我最终会在我的 Client 类中使用如下方法:

public class func authenticate(state: state) {
    if (state.type == 1) {
        Client1.authenticate(state)
    } else {
        Client2.authenticate(state)
    }
}

对每一种方法都重复...

我希望最初保持客户端像这样 - 无状态和静态,并且只有状态对象保存实际状态,因为可能有许多连接到具有各种状态的服务器。通过这种方式,我想避免将客户端作为一个对象,同时保持状态并执行对服务器的调用。问题是这种方法只是......我猜很脏。什么是更干、更易读和更可持续的方式?

【问题讨论】:

    标签: ios swift architecture frameworks


    【解决方案1】:

    如果没有更多的代码示例,我无法完全理解您的意图,但是我将向您展示的模式肯定会为您解决问题。

    如果您的 Client 类总是使用 Client1Client2(或者更具体地说,如果您的每个客户端对象 state 变量在其实例生命周期内没有改变),您应该使用 依赖注入强>.

    您创建一个procol(我们称它为RemoteClientauthenticate 方法(以及服务器客户端应实现的所有其他方法)并使Client1Client2 符合该协议。

    现在您让您的 Client 类在其构造函数中接受 RemoteClient

    现在无论创建什么客户端对象,它都可以决定将什么注入到构造函数中:Client1 具体类对象或Client2

    关于Dependency Injection的文章很多,我就不详细介绍了。

    Example article

    您也可以使用策略设计模式,它非常相似,但意图不同:

    Strategy design pattern

    Difference between DI and Strategy

    编辑

    在你明确了你想在下面的 cmets 中做什么之后:

    在这种情况下,您可以使用反射/元数据并使用字典/映射来调用您想要的客户端。

    (伪代码)

    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 是否可以这样工作,因为我刚刚开始使用它。我不确定您是否可以在类类型上调用静态方法。文档对此非常薄弱。

    更多: Swift class introspection & generics

    【讨论】:

    • 感谢您的回答!我放弃了最初的想法,实际上按照您的建议进行操作。我可以看到我未能阐明我想要实现的核心目标 - 客户端是一个静态类(不是初始化的对象)。就像我会在 Alamofire 中调用 POST(不初始化客户端)我想在静态客户端上调用方法(每次都注入状态)。挑战是当我需要两个实现时如何做到这一点客户端 - 我必须有一个“路由器”才能调用 Client.performSth(),而 SDK 的“用户”不必指定哪个(客户端 1 或客户端 2)。
    • 那么如何确定使用哪个客户端的方法将是通过状态对象。但这会产生我在我的问题中发布的那种方法 - 对于我想要公开的每个方法 - 与 switch 一样,调用正确的实现......
    猜你喜欢
    • 1970-01-01
    • 2012-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多