这种单身设计模式是不是很糟糕?在这种情况下使用Singleton是错误的吗?

时间:2015-10-17 06:26:35

标签: design-patterns singleton factory-pattern anti-patterns cocoa-design-patterns

问题:

为简单起见,我将使用一个简单的例子。在示例应用程序中,A类读取一些数据。

然后,Class-A实例化Class-B,然后实例化Class-C。所以总共有一个3级层次的类A --> B --> C

B级创造&基于类A中的数据管理自定义对象。我只是以函数/方法参数的形式将数据从类A传递到类B。

然而,C类是不同的。它有2个函数/方法为它提供数据。

  1. firstMethod(arg) - 为其提供数据。 (在B级上调用)
  2. otherMethod(otherArg) - 并为其提供其他数据。
  3. 它是由Class-B实例化的,并且它需要从Class-B传递的数据将被传递给它由class-B通过firstMethod(arg1)传递给它。但是,还有另一个数据集,C类需要正常运行。这个其他参数与B类无关;因此,通过此类将此信息作为参数传递给class-C似乎是错误的。

    如何在不使用B类的情况下从A类到C类获取此信息? 我所做的是创建一个Singleton类-S。

    Class-S在其中定义了A类的方法/函数(而不是变量)。在设置之后,Class-C现在可以在Class-S上调用它的otherMethod(otherArg),它调用所需的函数并直接从A类返回所需的数据。

    A-->B-->C
    ^       |
    |___S___|
    

    问题:

    我已经列出了网络上看到的单身人士的一些问题。

    1. 来自this link,它们通常用作全局实例,为什么这么糟糕?因为您在代码中隐藏了应用程序的依赖关系,而不是通过接口公开它们。制作一些全局的东西以避免传递它是一种代码味道。 [我的编辑] - 当class-S 被用作全局实例时,Class-c明确定义了其依赖关系。它工作所需的方法/功能在其界面中定义。
    2. 来自this link,它们固有地导致代码紧密耦合。在许多情况下,这使得将它们伪装在测试中相当困难。 [我的编辑] 这个设置仍然紧密地将class-C与单例联系起来?如果要对C级进行单元测试,则不需要单例(至少我不这么认为)。由于函数是明确定义的,因此mock类可以伪造其数据。
    3. 它们在应用程序的生命周期中处于状态。测试的另一个打击因为你可能最终会遇到需要订购测试的情况,这对于单元测试来说是一个很大的问题。为什么?因为每个单元测试应该独立于另一个。 [我的编辑] 鉴于设置,我不确定这会是个问题吗?
    4. 任何关于此的指示都会有所帮助。请不要讨厌..我用谷歌搜索,但没有找到许多明确的答案。谢谢。有什么想法吗?

      [我的编辑] - >下面的评论询问了以下问题,我认为这个问题非常重要,可以在这里添加。

        

      为什么不想将其他数据传递给B?如果执行命令[in class-C]需要此数据,那么它应该是一个参数。无论B直接使用它还是传递它

      答案是这是一个简单的例子,使用A,B和& C.事实是应用程序要复杂得多。 B类是一个可重用的类,用于应用程序的许多其他部分。如果我让class-B接受附加数据作为参数传递给class-C,那么在应用程序中使用class-B的每个其他部分,我都必须为该参数传递nil。此外,如果在应用程序的更多位置使用了B类:B->C ... B->X ... B->Y ... B->Z ...等,那么可重复使用的B类现在必须携带C,X,Y和Z ..或更多的参数。 B类是一个可以实例化不同类型的类的类,但它不知道有关实例化/分配的类的信息。它的工作只是实例/分配一个类,通过参数为instanced-class提供所需的一般信息,最后进行一些额外的设置。但是B类不应该知道其实例类的其他特定数据。所以它不会知道C类需要去A级来获取它的信息。只有C级才知道从哪里获取其特定信息。

1 个答案:

答案 0 :(得分:1)

我对“产卵类”的概念感到有点失落。

你说C有成员(即它是服务类吗?),那么就说C被称为库克,它有一个名为

的成员
  Cake bakeACakeMethod(Flour,Chocolate)

巧克力就是你所说的B类。

由于您想要跳过B类并在C中直接使用A类(Pineapple),那么您可以将方法更改为

  Cake bakeACakeMethod(Flour,IYummy)

其中IYummy是一个接口,而一个B类实现了IYummy,所以该方法允许这两个类。

其他方法是使用重载