2009-12-10 29 views
0

因此,对象模型相当复杂且层次分明。 祖父接受是由祖父工厂创建的,在其构造函数中接受祖父库。在现有代码库中实现模拟仓库

一切都很好。

现在,当爷爷需要加载它的儿童它是如何做到这一点?

它如何知道ChildFactory和ChildRepository?它不应该纠正?

但是它是如何加载它们的?我不认为你将一个ChildFactory传递给祖父构造函数,就好像你有孙辈(这个应用程序所做的那样),你也需要传递一个孙子工厂!

你实例某种EverythingFactory的有各种不同类型的工厂的它的内部并传递到每一个构造函数,他们利用他们所关心的一个吗?

还是有一些简单的解决方案,我只是没有看到?

目前所有对象调用web服务来加载自己的数据,我试图拉了这一点,并作出库接口,可模拟来测试的目的。

编辑: 忽略工厂,我不需要他们,我想我只是过分复杂的东西。

目前的对象由散布在对象的web服务调用的方式加载其数据和子数据。

大多数对象的构造函数被标记为私有,并且他们有静态方法,如“LoadByID(INT)”,以从数据库中检索它们。

然后当它包含它的子方法的属性被引用,如果它是私有的“子榜”变量是空的,它调用Child.GetAllChildrenFor(本);这是Child的静态方法,“this”是Parent类。它调用webservice,创建所有Childs,并返回它们的列表,每个列表都有一个对其父项的引用。

我知道这是不正确的...但我不知道我出了什么问题,或者如何纠正它能够删除Web服务调用,并放入一个Repository接口,可以是真实还是模拟......以及我在哪些代码中设置了哪个使用!

EDIT2: 代码是东西沿着这些路线目前

public interface IEntity 
{ 
    int ID { get; set; } 
} 

public class Parent : IEntity 
{ 
    public int ID { get; set; } 

    private Children children; 
    public Children Children 
    { 
     get 
     { 
      if (this.children == default(Children)) 
      { 
       this.children = Children.GetChildrenFor(this); 
      } 
      return this.children; 
     } 
    } 
} 

public class Children : List<Child> 
{ 
    private Children() { } 

    public static Children GetChildrenFor(Parent parent) 
    { 
     Children children = new Children(); 

     DataSet childrenDataSet = new DataSet(); 
     using (webservice) 
     { 
      childrenDataSet = webservice.Retrieve(parent.ID) 
     } 

     if (childrenDataSet.HasRows()) 
     { 
      foreach (DataRow dr in childrenDataSet.Tables[0].Rows) 
      { 
       Child rr = Child.LoadByDataRow(dr); 
       rr.Parent = parent; 
       children.Add(rr); 
      } 
     } 

     return children; 
    } 
} 

public class Child : IEntity 
{ 
    public Parent Parent { get; set; } 
    public int ID { get; set; } 

    internal static Child LoadByDataRow(DataRow dr) 
    { 
     Child child = new Child(); 

     child.ID = dr.Field<int>("ID"); 
     child.GrandChild = GrandChildren.GetGrandChildrenFor(this); 

     return child; 
    } 
} 
+0

你应该添加一些代码来更好地说明你在这里做什么。 – 2009-12-11 07:30:29

回答

1

一种方法是创建一个IRepository接口,定义为将提供您的实体类的合同。

public interface IRepository { 
    Parent GetParent(int parentId); 
    List<Child> GetChildrenByParent(int parentId); 
    // ... 
} 

其次,改变你的实体需要在它们的构造函数的IRepository

public class Parent: IEntity { 
    private IRepository repository; 
    public Parent(IRepository repository) { 
     this.repository = repository; 
    } 
    // ... 
} 

的具体IRepository实现将包含的代码来调用Web服务和地图的结果,以每个实体的;它必须自己传递时,它构造实体,像这样:像这样的构造

public class ConcreteRepository: IRepository { 
    public Parent GetParent(int parentId) { 
     Parent parent = new Parent(this); 
     // Call web service, perform mapping, etc. 
    } 
} 

实体可以使用存储库根据需要 - 例如,在Parent.Children get访问。您的应用程序将使用真实的存储库,而单元测试可以提供模拟或存根。

+0

所以我的错误是试图为每个实体创建一个存储库,而不是一个包含所有这些方法的存储库? – CaffGeek 2009-12-11 18:10:45

+0

这不是一个错误,只是一个设计决定 - 事实上,您仍然可以在封面下实施单独的实体存储库。我只提出一个单一的存储库(基本上是一个抽象工厂,只要存储库是专门的工厂)来简化API。 – 2009-12-11 18:51:13

+0

现在就开始工作,我看到了如何使用一个存储库(后来可能成为几个门面)使这项工作变得更加简单。我只是用一堆静态方法创建一个类并将任何调用拖放到Web服务中来开始它。从那里我应该能够重构它来实现一个接口并创建一个模拟对象......小步骤。希望下周我会有可以编写测试的代码... – CaffGeek 2009-12-11 20:02:30

0

创建工厂的层次结构。 ChildFactory继承了继承GrandfatherFactory的FatherFactory。也许工厂可以模板化,或者你可以使用抽象工厂设计模式。到这个因素码出的静态方法,使其模拟能够