为什么查询对象设计模式

25 design-patterns

我试图理解"查询对象设计模式".我无法找到好的和简单的例子.有人可以帮助我理解这个设计模式是什么以及我们可以实现这个问题吗?

Ibr*_*jar 37

Query设计模式通常与Repository设计模式结合使用.

让我们举个例子,然后我会给你一篇很好的文章.假设我们有一个数据库,用于存储有关客户及其订单等的信息.

然后我们创建一个这样的初始存储库:

class CustomerRepository() {
    Customer GetById(int id) { // implementation }
    void DeleteCustomer(int id) { // impl }
    Customer GetCustomerWithOrder(int orderId);
    Customer[] GetCustomersWithOrdersMoreThan(int numberOfOrders);
}
Run Code Online (Sandbox Code Playgroud)

正如您在每个查询中看到的那样,我们在存储库中创建了一个非常精细且适用于有限数量查询的方法,但是当我们拥有大量的查询并且他们开始变得复杂时(例如让我的客户购买)超过1000并且居住在纽约并且他们的信用额度小于3000)那么我们最终会得到一长串方法,更糟糕的是,在我们不想要的存储库内以查询的形式泄露一些业务逻辑即将发生.

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

class CustomerRepository() {
    Customer[] Get(Query query) { // implementation }
    void DeleteCustomer(int id) { // impl }
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我们正在传递一个查询对象,它以对象的形式表示我们的查询,并且存储库有一个唯一的存储库来执行该查询并将结果返回给我们.

现在如何实现查询对象以及如何构建它将需要大量代码,所以在这一点上我将指导您阅读这篇好文章.它在C#中,但您会发现它非常有用,您也可以查看NHibernate使用的Criteria API(Java)来查看不同但相似的实现.


Bul*_*ise 7

查询对象表示用域语言编写的查询,并且是查询对象模式的实现.Fowler描述的查询对象模式是"表示数据库查询的对象."如果没有某种查询机制,存储库将充斥着无数的检索方法,例如可以在此代码片段中看到:

public interface ICustomerRepository     
{         
    IEnumerable<Customer> FindAll();
    IEnumerable<Customer> FindAllVIPCustomers();
    IEnumerable<Customer> FindByOrder(Guid ID);
    IEnumerable<Customer> FindAllCustomersThatHaveOutstandingOrders();
    …    
}
Run Code Online (Sandbox Code Playgroud)

相反,查询对象允许构造任何查询,然后将其发送到存储库以满足.查询对象模式的主要好处是它完全抽象出底层数据库查询语言,从而将数据持久性和检索的基础结构问题保留在业务层之外.但是,在某些时候,需要创建数据库的原始查询语言; 这是使用特定于数据库的QueryTranslator实现的,该QueryTranslator接受查询对象并将它们转换为数据库的语言.

来自Pro ASP.NET Design Patterns一书.