【问题标题】:Dependency injection vs singleton, Initialization依赖注入 vs 单例,初始化
【发布时间】:2014-07-16 15:40:09
【问题描述】:

我现在正在处理一个大项目,该应用正在利用许多不同的服务,例如: 评论、点赞、发帖、购买等..

每个服务都有一个类。

现在,我想限制注册用户的某些操作,例如发帖、评论等。

到目前为止,每个类都只有类方法,如下所示:

 @interface UpdateOrderServies : NSObject

+(void)deleteOrder: (STOrder *)order
         andReturn: (void(^)(NSError *error))errorBlock;

+(void)updateOrder: (STOrder *)order
         andReturn: (void(^)(NSError *error))errorBlock;

但是现在,我想先检查用户是否已注册,如果没有,则不返回值。 所以我想出的最好方法是将课程更改为单音,并在每次调用课程时询问用户是否像这样注册:

+(id) getInstance {

    static UpdateOrderServies *__sharedDataModel = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        __sharedDataModel = [[UpdateOrderServies alloc]init];

    });

    if (![__sharedDataModel userIsRegisterd]) {
        return nil;
    }

    return __sharedDataModel;

}

它有效,但是,正如您所见,它不是一个很好的答案.. 我想要更通用的东西。 我正在考虑使用 Typhoon 依赖注入,但如果用户已注册,我没有地方可以检查每个调用...... 有更好的方法来处理这个问题吗?更有活力...

【问题讨论】:

  • 为什么不识别用户,当他们第一次“登录”或以其他方式识别自己时,使用封装所有授权等的“能力”对象。使用它而不是简单的用户 ID 来识别用户,并查询该对象以测试用户的能力。
  • @HotLicks "为什么在用户登录时不识别用户" . .这一步就是认证。接下来是定义调用给定服务所需的权限——这部分称为授权。我们可以将授权作为每个服务调用的一部分,但这会破坏单一责任原则 - 因此推荐 AOP。
  • @JasperBlues - 您将“责任”放在用户的能力对象中。必须提供执行授权操作的能力。对我来说,这似乎是一个“单一责任”计划。
  • @HotLicks 能力对象是,但是如何执行授权 - 即评估能力对象?由于这是一个“横切”要求,因此必须重复应用。事实上,在解释 AOP 时,安全性是一个常见的例子。 (我相信其他人可以比我更好地解释它)。 . en.wikipedia.org/wiki/Aspect-oriented_programming
  • AOP一直是寻找问题的解决方案,我不明白这是怎么回事。能力对象封装了保留授权信息或在调用时访问它所需的任何内容。它是具有单一职责的单一控制点。

标签: objective-c typhoon


【解决方案1】:

根据您上面的问题,我认为您不是在寻找依赖注入,而是在寻找面向方面的编程。

Aspect Orientes Programming (AOP) 旨在解决您上面描述的那种问题——那些跨越系统中许多模块的问题。示例:

  • 每次用户与服务交互时,都应该检查安全性。
  • 所有交易都应该有审计追踪
  • 每一次店铺互动都应该得到一个天才的推荐

如果我们对这些横切需求使用普通的面向对象编程,我们就打破了单一职责原则,一个应该几乎是关于一个主题的类现在承担了更多的角色混乱、重复和混乱。

AOP 将这些横切关注点模块化,然后使用方法拦截标识所有应该应用这些的地方。 (在 AOP 中我们称之为切入点表达式)。

在 Objective-c 中,您可以使用 ISA-swizzling、消息转发或使用 NSProxy 进行手动 AOP——这些都是在运行时实现方法拦截的所有方法。或者,您可以使用由 Pete Steinberger 和团队开发的名为“Aspects”的库和一个此类库。这个库还没有切入点表达式语言,但肯定比直接使用 ObjC 运行时拦截方法要简单得多。

授权方面如何工作的总结:

  • 在登录时,我们使用用户名/密码质询、oauth 令牌或类似方式对用户进行身份验证。对用户进行身份验证后,我们现在可以授权服务调用。
  • 确定需要授权的每个服务,以及所需的权限(您可以选择任何您喜欢的角色、功能等方案)。
  • 良好的面向对象原则说每个类都应该有一个单一的职责。所以你的服务客户端应该是关于调用远程服务的。我们可以编辑服务客户端来评估登录用户的权限并决定是否继续。但这将是混乱和重复的。相反,我们将使用第 2 步中的信息(每个服务所需的权限)并将对该评估的评估委托给我们的授权模块。
  • 现在是 AOP 步骤: 对于每个服务调用,我们将告诉我们的 AOP lib 拦截服务客户端方法并首先调用授权模块。

这样您的横切要求(授权客户端调用)不会重复。现在,为了简单起见,您可以决定让每个服务调用调用一个授权模块,但它仍然有助于了解 AOP 和横切关注点背后的理论。

依赖注入/台风

依赖注入与您的问题并没有直接关系,尽管它肯定有助于避免单例客户端的陷阱:

  • 在您的类之间创建一个清晰的契约 - 增加代码的凝聚力。
  • 确定应用程序中的关键“参与者”,并描述将它们组合成一个整体的方式。可以将一个演员换成另一个履行相同合同的演员。
  • 使用模拟和存根简化单元测试。
  • 简化了集成测试 - 能够将一个参与者换成另一个参与者,从而将系统置于所需的状态。例如,只修补一个授权模块。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-15
    • 1970-01-01
    • 2011-04-19
    • 2013-07-27
    • 2019-05-06
    • 1970-01-01
    • 2021-05-15
    • 1970-01-01
    相关资源
    最近更新 更多