4

我的例子是我希望我的用户打电话

findCustomers(...)

现在我的问题是关于这种方法的论点。我有一个

Customer.java

对象,我希望用户能够使用该库按客户名称和客户 ID 进行搜索。

现在我不想创建多个方法

findCustomerById(String id)
findCustomerByName(String name)
findAllCustomers()

相反,我想做的是一个通用的 findCustomer

/** if you pass only custoer.name and rest of fields are null will search by name,
if you pass a null custoer object will return all customers, if you pass both custoer id and his name will search by both fields). **/
findCustomer(Customer customer)

现在我有一个通用的 api 方法,但我不喜欢在对象中传递空值,我不喜欢空值。

有人对这样的 api 有明确的最佳实践吗?

谢谢

4

3 回答 3

8

用于查询的流体 api 之类的东西怎么样:

List<Customer> matches = find(new CustomerQuery().withName("john(.*)").withId(42));
于 2012-12-15T11:54:39.267 回答
3

您尝试构建的内容称为Query By Example。没关系,但它有局限性:您的Customer类被重新用作查询参数,使其某些代码无用或适得其反。例如,如果您添加一个要求名称仅包含字母的验证,您将无法使用通配符查询名称。

解决此问题的一种方法是提供专门设计用于处理查询参数的查询构建器类。查询对象本身可以包装Map<String,Object>用户传递的参数绑定,让您的查询 API 将其拆开,并将相应的数据传递给底层数据存储的查询。

QueryObject<Customer> qObj = new QueryObject(Customer.class);
qObj.setParameter("FirstName", "Joe");
qObj.setParameter("LastName", "S*");
qObj.setParameter("ID", 123);
List<Customer> cust = findCustomers(qObj);
于 2012-12-15T11:59:41.353 回答
1

而不是传递一个我认为有许多其他方法的客户对象,你可以有

findCustomer(String id, String name); // id or name can be null.

或 CustomerSearch 对象,该对象可以具有这些或可能具有多个 id 和名称。

于 2012-12-15T11:52:25.973 回答