Design patterns 为什么选择查询对象设计模式

Design patterns 为什么选择查询对象设计模式,design-patterns,Design Patterns,我试图理解“查询对象设计模式”。我找不到好的简单的例子。有人能帮我了解一下这个设计模式的用途以及我们可以在什么问题上实现它吗?查询设计模式通常与存储库设计模式结合使用 让我们举一个例子,然后我将给出一篇很好的文章来阅读。假设我们有一个数据库,在那里我们存储有关客户及其订单等的信息 然后我们创建一个初始存储库,如下所示: class CustomerRepository() { Customer GetById(int id) { // implementation } void

我试图理解“查询对象设计模式”。我找不到好的简单的例子。有人能帮我了解一下这个设计模式的用途以及我们可以在什么问题上实现它吗?

查询设计模式通常与存储库设计模式结合使用

让我们举一个例子,然后我将给出一篇很好的文章来阅读。假设我们有一个数据库,在那里我们存储有关客户及其订单等的信息

然后我们创建一个初始存储库,如下所示:

class CustomerRepository() {
    Customer GetById(int id) { // implementation }
    void DeleteCustomer(int id) { // impl }
    Customer GetCustomerWithOrder(int orderId);
    Customer[] GetCustomersWithOrdersMoreThan(int numberOfOrders);
}
class CustomerRepository() {
    Customer[] Get(Query query) { // implementation }
    void DeleteCustomer(int id) { // impl }
}
正如您所看到的,对于每个查询,我们都在存储库中创建了一个方法,该方法非常适合有限数量的查询,但当我们有很多查询时,它们开始因许多组合而变得复杂(例如,让我的客户购买超过1000件商品,住在纽约,他们的信用限额低于3000)然后,我们将得到一长串方法,甚至更糟糕的是,在存储库中以查询的形式泄漏一些我们不希望发生的业务逻辑

因此,为了进行重构,我们将存储库更改为以下内容:

class CustomerRepository() {
    Customer GetById(int id) { // implementation }
    void DeleteCustomer(int id) { // impl }
    Customer GetCustomerWithOrder(int orderId);
    Customer[] GetCustomersWithOrdersMoreThan(int numberOfOrders);
}
class CustomerRepository() {
    Customer[] Get(Query query) { // implementation }
    void DeleteCustomer(int id) { // impl }
}
正如您所看到的,我们正在传递一个查询对象,该对象以对象的形式表示我们的查询,存储库有一个也是唯一一个存储库来执行该查询并返回结果


现在,如何实现该查询对象以及如何构建它将需要大量的代码,所以在这里,我将引导您了解这一点。它是用C语言编写的,但是你会发现它非常有用,你也可以看看NHibernate使用的(Java)来查看不同但类似的实现。

查询对象表示用域语言编写的查询,是查询对象模式的实现。Fowler所描述的查询对象模式是“表示数据库查询的对象”。如果没有某种查询机制,存储库将充斥着无数的检索方法,如下面的代码片段所示:

public interface ICustomerRepository     
{         
    IEnumerable<Customer> FindAll();
    IEnumerable<Customer> FindAllVIPCustomers();
    IEnumerable<Customer> FindByOrder(Guid ID);
    IEnumerable<Customer> FindAllCustomersThatHaveOutstandingOrders();
    …    
}
公共接口ICCustomerRepository
{         
IEnumerable FindAll();
IEnumerable FindAllVIPCustomers();
IEnumerable FindByOrder(Guid ID);
i有未结清订单的可数FindAllCustomer();
…    
}
相反,查询对象允许构造任何查询,然后将其发送到存储库以得到满足。查询对象模式的主要好处是,它完全抽象了底层数据库查询语言,从而将数据持久性和检索的基础架构问题排除在业务层之外。然而,在某些时候,需要创建数据库的原始查询语言;这是通过使用特定于数据库的QueryTranslator实现的,QueryTranslator接受查询对象并将其转换为数据库的语言

来自Pro ASP.NET设计模式手册


看看我为NHibernate编写的查询对象模式库:

好的,我现在了解了查询对象设计模式的确切用法。很好的例子和很好的解释。非常感谢。现在我有另一个与此相关的问题。CriteriaAPI提供了查询对象设计模式,我们可以简单地使用它。但对于如何通过编程实现这一点有点困惑。在上面提到的示例中,您正在注入查询对象。但是,如果我想在我的应用程序中实现这一点,它会是什么样子?@santu你在使用什么语言?你看过我告诉你的C#中的文章了吗?我在使用Java。我查了C。但是我想到了如何在DAO调用中使用这种模式,DAO调用执行不同的CRUD操作。@santu对于简单的CRUD操作,如添加、更新、删除和读取,您不需要这种模式。如果我们需要从两个不同的表中提取数据,该怎么办?客户存储库仅从客户表中提取数据在现实场景中如何有用?