【问题标题】:Access control for a services (design decision)服务的访问控制(设计决策)
【发布时间】:2009-12-09 05:50:54
【问题描述】:

假设我们有一个接口“IA”,我们有一个实现“A”。 在我们的应用程序域中,如果没有容器对象“X”,对象“A”永远不会存在。所以'A'永远不会被直接操作。 'A' 在 'X' 中聚合。

我们不想将“A”暴露给外界。为此,我们采取了方法,没有公共接口“IA”,而是直接在“X”中使用实现“A”。不知何故,我觉得这不是正确的方法。可能是我遗漏了一些基本的 OO 概念。

请发表意见。

PS:不提供“IA”的原因是:人们可能会为 A 想出自己的随机实现并玩弄系统。


好的。让我把实际问题放在这里。 我正在开发一个 Web 应用程序。我们有几个层次——Dao、Doamin、Service、Web。 服务层通过 DAO 为 Domain 对象提供各种服务。 我们有域对象——Wire 和 WireRequest。一个 WireRequest 可以有任意数量的 Wire。对应于这些领域对象,我们有两个服务——WireService 和 WireRequestService。 WireService 是使用 spring 注入到 WireRequestService 中的。

当我们将 service.jar 暴露给客户端时,他们可能会独立使用 WireService 并在没有 WireRequest 对象的情况下创建 Wire 对象。我们想防止这种情况。基本上我们想要控制对某些服务的访问。 (我们可以通过授权 spring 方面做到这一点,但想使用一些 OO 方式)

-奈恩

【问题讨论】:

  • 是否有特定的语言将在其中实现?

标签: java spring interface


【解决方案1】:

做最简单的事情。

除非我遗漏了什么,否则隐藏聚合对象的实现细节或你的类的任何其他属性本质上是“非 OO”的。

正如 Kenaniah 所说,将 A 类标记为 internal(或您的语言中的任何等效项),外部世界将看不到它。然后,您班级上的集合属性可以是 protected(或其他),并且在该班级之外将不可见。

某些语言,例如.NET,还提供“内部类”:

public class X
{
    internal class A
    {
    }

    protected IEnumerable<A> ACollection { get; set; }
}

在这里,A 在 X 之外根本不可见。

【讨论】:

  • 您的建议的基本概念是合理的。不幸的是,您的示例仅限制对集合的访问,而不是类型,这使得它可以通过 new X.A(); 访问,这与 OP 的目标背道而驰。他想阻止实例化。如果您将 A 声明为 internal class A {...} 并将访问器声明为 internal ,那么您将拥有 OP 想要的类的库级别隔离.
  • @JeremyMcGee:我从你的回答中得到了春季级别的想法。
【解决方案2】:

为什么不保护 A 的所有方法和属性?

【讨论】:

    【解决方案3】:

    让我看看我是否理解正确;重新表述这个问题,你有容器 X,它包含从 IA 派生的 A 的实例 - 但是为了使 X 只有 A 的实例,你将它限制为只包含 A 的类型而不是 IA。我说对了吗?

    对我来说,这实际上很好。您正在定义一个可以在编译时加强的约束。将接口 IA 仅用于其他目的仍然有效——您可能需要另一个具有 IA 定义的行为的对象列表;通过接口 IA 传递对象引用以实现多态性等仍然很有用。

    唯一的缺陷是系统是封闭的——列表只能取类型 A。如果下次你需要将 A 和 B 都保存在同一个列表中,而不是 C 怎么办? (假设所有都来自 IA)。在这种情况下,最好添加对数据/状态的正确验证,而不是仅限于一种类型。

    【讨论】:

      【解决方案4】:

      根据 A 的复杂性和 X 的相对复杂性(或简单性),听起来您所描述的可能是 Facade Pattern 或 Wrapper/Adapter Pattern

      两者都适用于给定的一组场景,并且通常有助于保持跨域/子域边界的清晰。

      编辑:鉴于 OPs 最近添加...听起来像“使用弹簧和代码注入时如何控制对 WireService 和 Wire 的访问...”

      我不熟悉 spring 以及它如何注入东西。
      但是,如果它遵守任何合理的库创建规则,它应该只要求您希望消费者必须公开的那些东西......所以您应该能够将 WireServiceRequester 作为唯一的公共对象。给其他所有东西一个他们实现的公共接口,并从任何具体实现类之前删除 public

      如果 spring 不像我假设的那样健全,那么使用 spring 中内置的访问控制机制可能是最安全的...

      【讨论】:

      • 我更新了问题。请看一下是否有意义。
      • 这仍然不是问题。这是对您的具体情况的澄清。尝试提出几个问题来跟进上下文。如:我做的合适吗?是否有涵盖这些场景的设计模式?有没有其他方法可以解决这个问题?....等等。 我们可以推断出哪些信息可能对您最重要,但是,我们只是猜测。提出具体问题可以让社区更容易地提供相关和有意义的反馈。这最终会帮助你。
      • 嗯。我很感激。我认为您正确理解了我的问题。我有一个非常简单的解决方案来解决这个问题。 Spring 通过实际的对象创建来处理依赖注入。我可以将“wireService”bean 定义为“wireRequestService”bean 的内部 bean。由于内部 bean 不能在容器 bean 之外使用,因此不能独立创建。它与内部类的概念相同。我想这符合我的目的。非常感谢你们。
      【解决方案5】:

      公共 service.jar 应该只包含接口类,并且应该通过某种 IoC 获得实现

      在这种情况下,使用spring动态绑定实现

      因此 service.jar 应该包含

      仅限 WireRequestServiceInterface

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-04
        相关资源
        最近更新 更多