The Finder Pattern

 

Posted by   fabriziogiudici  on January 15, 2010 at 3:24 AM PST

原文地址:http://weblogs.java.net/blog/fabriziogiudici/archive/2010/01/15/finder-pattern

 

In many previous code examples in this blog I've used the “Finder pattern”, that I've elected as one of my best practices (it's standard in all my new APIs and will be retrofitted to the old ones). Before moving on with more examples, I think it's high time I shortly introduced it formally.

As the name suggests, it helps whenever you need to provide a search of some type. For instance, in the Hierarchy API the interfaces HView and HItem (name shortened from Hierarchical*** in my previous post) implement a Composite pattern, so a HItem has got children:

public interface HView
  {   
    @Nonnull
    public Finder<HItem> findChildren();
     
    @Nonnull
    public Builder<HItem> createChild();
     
    @Nonnull 
    public Builder<HItem> findOrCreateChild();
  }

public interface HItem extends HView
  {
    @Nonnull
    public HView getView();

    @Nonnull
    public HItem getParent()
      throws NotFoundException;
  }

There are many ways to search for children; for instance, you could search for a specific child with an id, or if you recall that any object in the Hierarchical API is logically bound to another object, you could explicitly search for children with a specific binding. Thus, one might need to have methods such as findChildren(), findChildById(), findChildrenBoundTo() etc. This is not a scalable approach in the perspective of flexibility, as any extension of the search facility would need the introduction of a new method. Instead, all of the above can be done with the single findChildren()returning a Finder:

HItem parent = ...;
List<? extends HItem> allChildren = parent.findChildren().results();
specificChild = parent.findChilren().withId("xyz").result();
List<? extends HItem> childrenBoundToAPhoto = parent.findChildren().boundTo(Photo.class).results();

Ok, you're probably saying that now new methods must be added to the Finder - right, I'll give more details about how to extend a Finder in another post, but in the meantime the problem has been restricted to extending a single class, instead of the many that support queries; moreover, the fact that the search responsibility is given to a specific class makes it possible to add common features without duplicating code. 

For instance, if you want to retrieve only a subset of the results (usefulr for instance with the paginated views), you can specify it:

HItem parent = ...;
List<? extends HItem> someChildren = parent.findChildren().from(10).max(20).results();
HItem the7thChildren = parent.findChildren().from(7).firstResult();
List<? extends HItem> childrenBoundToAPhoto = parent.findChildren().boundTo(Photo.class).from(10).max(30)..results();

It is possible to use a Finder just to know the number of the items that would be produced by the query:

HItem parent = ...;
int howManyChildren = parent.findChildren().count();
int howManyChildrenBoundToAPhoto = parent.findChildren().boundTo(Photo.class).count();

Depending of the implementation, asking for a count of items could generate an optimized query (e.g. a thing such as select count(*) where available). Right, because the fact that the responsibility of searching stuff is delegated to a specific class (or set of classes, as Finder acts often as a Façade pattern) makes it possible to decouple the implementation - which in a component scenario might even be pluggable, that is capable of extending functionalities by adding plugins to the system.

The fact that a Finder represents all the needed information for performing a query, but not the results of the query itself, makes it possible also to serialize it for a later retrieval (and execution), a useful feature for saved queries and such.

So, basically the Finder is a class implementing the Fluent interface pattern for specifying all the information needed to create a query (in fact you find basically the same pattern e.g. in the JPA API for creating JPAQL queries).

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值