2014-01-14 28 views
1

在构建集成引擎时,我一直在寻找有关设计模式的一些提示。处理导入和导出(集成)的.NET服务

我有一个SQL Server,它包含我想要导出的所有数据(这也是我插入导入数据的位置)。我有一个服务可以根据时间间隔执行命令等等。尽管我真正努力的一件事情就是处理软件中数据处理的方式。

例如,在一个出口项目我做我有类似的这种

// Entity order 
public class Order { 
    int OrderID { get; set; } 
    string OrderNo { get; set; } 

    // One order can include loads of registrations 
    // A registration can only have a reference to one order 
    // Basically a mirror of the database 
    List<Registration> RegistrationList { get; set; } 
} 

// Entity registration 
public class Registration { 
    int RegistrationID { get; set; } 
    string Name { get; set; } 
    // Some more variables 
} 

// Controller(?) 
public class OrderController : IControlOrder 
{ 
    private IControlRegistrations _registrationController; 
    public OrderController() 
    { 
     this._registrationController = new RegistrationController(); 
    } 

    public List<Order> get() { 
     List<Order> orderList = new List<Order>(); 
     // Query database 
     foreach(...) { 
      // Short example 
      Order order = new Order(); 
      order.OrderNo = ... 
      order.OrderID = ... 
      order.RegistrationList = _registrationController.getRegistrationsBasedOnOrder(order); 
     } 
     // Iterate through every row 
     // Create a new Order-object per iterate 
     return orderList; 
    } 

    public void updateOrder(Order order) { 
     // Update the order in the database (set exported-flag) 
    } 
} 

public RegistrationController : IControlRegistrations 
{ 
    public List<Registration> getRegistrationsBasedOnOrder(Order order) 
    { 
     List<Registration> list = new List<Registration>(); 
     // Query DB based on OrderID 

     return list; 
    } 

    public void update(Registration registration) 
    { 
     // Update the registration in the database 
    } 
} 

// Output 
public class Output 
{ 
    private IControlOrder _controller; 
    public Output(IControlOrder controller) 
    { 
     this._controller = controller; 
    } 

    public void export() 
    { 
     // Build XML 
     // ... Example 
     // 
     //<Orders> 
     // <Order> 
     //  <OrderNo>KF322</OrderNo> 
     //  <RegistrationList> 
     //   <!-- All the registrations with a reference to this order --> 
     //  </RegistrationList> 
     // </Order> 
     // <Order> 
     //  <OrderNo>KF323</OrderNo> 
     //  <RegistrationList> 
     //   <!-- All the registrations with a reference to this order --> 
     //  </RegistrationList> 
     // </Order> 
     //</Orders> 


     foreach(Order order in _controller.get()) 
     { 
      // Create the order info in the XML, then create registrations 
      foreach(Registration reg in order.RegistrationList) 
      { 
       // Create the registration list in the XML 
      }  
     } 
     // Save the file to a network drive. 
    } 
} 

我敢肯定,我违反了设计模式的每一个规则有一个结构。最终,我的代码变得混乱,每层的责任(不知道我是否可以称之为图层)变得混乱起来。例如,如果一个订单也与描述和地址有一对多的关系,那么类会变得难以置信地混乱。在我的下一个项目中,我也将执行导入,并且我不会仅导出订单,而且还会导出其他主数据。所以我相信我必须在接口,帮助类等方面很聪明。在输出文件或将其插入数据库之前,我还必须验证从数据库和集成程序中检索的所有数据。

你们有没有人知道集成引擎的良好设计模式(只是一个理论)?这个问题可能并不具有建设性,但是当我们使用的小房子设计会比数十倍大的时候还不够。

任何帮助非常感谢:)谢谢!

回答

1

这看起来并不坏。有两种命名的问题,特别是你的控制器不控制器,但和你的输出类是服务(这样OutputService会是一个更好的名字)。

分层没问题。你有一个深层的领域模型。然后你在上层有仓库,在它上面有你的服务。如果你遵循简单的约定,其中仓储类名与RepositoryOrderRepository)结束服务是..Service,你把每一层在单独的程序,并允许上层装配仅供参考下层组件,那么你会收拾你的很多混乱。

我的想法是不要手动编写模型类和存储库。这没有多大意义,因为有很多陷阱。相反,反向工程模型进行使用实体框架逆向工程代码第一个选项,则数据库,而不是手工创建仓库使用实体框架来代替。手工创建的唯一层就是实现特定业务流程的服务层。

+0

这是很酷多少早点有意义的,因为你只需要改变的“小细节”像术语。 EF让我感到困惑,因为它就像一个魔术盒给我,可能是因为我自己没用过,只是看到了一些使用它的产品代码。我想到的另一件事是验证我插入到模型中的模型数据。但是我相信我会在某些时候解决这个问题:)这个设计模型是否指定了具体的东西?感谢您的帮助,只是术语的变化使其可以理解! – Alex07

+0

我很抱歉再次打扰您,我决定按照您提出的命名约定来采用这种模式。如果我以上述为例,我想创建两个输出,前面提到的XML和一个Web服务连接,以及一个报告(我真正输出了什么)。 IOutputService应该是一个具有定义的报告方法和抽象的Export-method的抽象类?你为这个特定目的建议了什么设计? :) – Alex07

+0

@ Alex07:听起来像一个很好的,自包含的代码审查问题http://codereview.stackexchange.com –

2

你可能想看看Command-Query Segregation。基本上这归结为几个概念:

  • 写作,阅读查询命令。导入是通过命令,通过查询导出的。
  • 与/只有一个类型的导入导出

所以从用户,您将获得文件数据/数据保存在控制器和传递到与这种类型的交易命令一个命令/查询交易数据。为了导出,您可以在控制器中执行查询,查询将从数据库提取数据并适当格式化。

有时,如果您将数据提取到XLS或其他格式,则可能需要引入单独的渲染器。这样您的关注就会分开 - 查询只提取数据,渲染器将该数据转换为所需的格式。通过这种方式,您只需添加新的渲染器即可将数据提取到不同的格式。

命令也一样 - 命令的一部分可以是一个解析器,用于将传入数据解析为类实例,然后命令将其保存到数据库中。

您可以检查出的例子,更CQRS详情点击这里:

+1

明天我会检查出来!听起来像是一种定义责任的好方法,它也可能使代码更易于理解!非常感谢:) – Alex07

+0

没问题。我们已经使用了服务和全面的功能类,但是当你跨越30个控制器的时候,事情就变得混乱了。搬到CQRS之后 - 一切都很清楚:班级只做一件事和一件事。您可以查看我的小应用程序,我使用CQRS https://github.com/trailmax/Amv.Reporting,但对于DB,我使用Raven DB,而不是EF – trailmax