哪种类结构更理想?

时间:2009-04-08 13:43:34

标签: design-patterns architecture oop

我不确定这两种“模式”中哪一种最好。目前我使用选项A(与提供程序一起实现持久性),但我现在正在向B做错,特别是考虑到单元测试能够使用“依赖注入”模型。

选项A:

class ClassA
{
   ClassA() { }
   Save();
   static List<ClassA> GetClassAs();   
}    

选项B:

class ClassA
{
   ClassA() { }
   Save();
}

class ClassARepository
{
    ClassARepository() { }
    List<ClassA> GetClassAs();    
}

我认为我要问的是,一个类暴露返回自身实例集合的静态方法是不错的做法?

修改

似乎普遍认为选项B是更好的选择。看起来我前面有很多重构:S

6 个答案:

答案 0 :(得分:4)

选项B看起来有点像ActiveRecord模式(我假设ClassA中的Save方法将使用ClassARepository?),这在某些情况下很好,但是,如果你有相当复杂的域模型,我不会使用'ActiveREcord'模式。

相反,我会使用这样的模型:

public class ClassA
{
   public int Id {get; private set;}
   public string Name {get; set;}
}

public class ClassARepository
{
    public ClassA Get( int id );

    public void Save( ClassA item );
}

这意味着所有与持久性相关的逻辑都放在ClassARepository类中,而ClassA也没有直接访问存储库。

答案 1 :(得分:2)

您可以将对象的完全持久性与数据和逻辑分开,也可以将所有对象保留在一个类中。将“保存”移至“ClassARepository”或将“GetClassAs”保留在“ClassA”中。

答案 2 :(得分:1)

选项B看起来更好,因为A混合了两种想法,两种功能。有A类的实际功能和管理A的集合的单独功能。

随着应用程序的增长,您可能还需要在存储库中使用其他功能 - findById,检索子集等等。把它变成A级会变得混乱。

而且,正如您所指出的,选项B更容易测试。

答案 3 :(得分:0)

不,我不认为这种不良做法是一项严格的规则,尽管我假设这是针对某种实例跟踪或资源监控的吗?如果是这样,请记住,幕后必须有逻辑,以确保原本超出范围的对象不会仅仅停留在静态集合中。我不确定您使用的是哪种语言,但如果是C#,您可以考虑将其作为List<WeakReference>内部存储。

答案 4 :(得分:0)

选项B更灵活。

  • 它允许有多个存储库的可能性。
  • 它允许将存储库类子类化。
  • 它允许您将存储库作为参数传递给另一个类或函数,而不是将该类或函数显式耦合到全局静态变量。

答案 5 :(得分:0)

  

我认为我要问的是,一个类暴露返回自身实例集合的静态方法是不错的做法?

一般情况下没有 - 这样的收藏品通常是单身人士,如果是(如你的例子)那么单身人士的常见原因被认为是antipattern,以及static is considered harmful的原因。 / p>