如何简化两个相似方法的代码?
How to simplify the code of two similar methods?
我想重构这两种方法,除了“maxResult ()”外,它们几乎相同,这两种方法指的是两种不同的获取方式,一种是 returns 我是单个用户,另一种是 returns returns 改为列表。我怎样才能简化这两种方法(总是在有意义的情况下)
这些是 2 种方法:
第一种方法:
public List findFirstByTransactionId(String transactionId) {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<User> criteria = builder.createQuery(User.class);
Root<User> root = criteria.from(User.class);
criteria.select(root).where(builder.equal(root.get(User_.transactionId), transactionId));
criteria.orderBy(builder.asc(root.get(User_.date)));
TypedQuery<User> query = em.createQuery(criteria).setMaxResults(1);
return query.getSingleResult();
第二种方法:
public List<User> findAllByTransactionId(String transactionId) {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<User> criteria = builder.createQuery(User.class);
Root<User> root = criteria.from(User.class);
criteria.select(root).where(builder.equal(root.get(User_.transactionId), transactionId));
criteria.orderBy(builder.asc(root.get(User_.date)));
TypedQuery<User> query = em.createQuery(criteria);
return query.getResultList();
您在 query
上调用的方法与任何其他方法一样工作,因此您可以将一些调用放在 if
块中,如下所示:
public List<User> findByTransactionId(String transactionId, boolean onlyFirst) {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<User> criteria = builder.createQuery(User.class);
Root<User> root = criteria.from(User.class);
criteria.select(root).where(builder.equal(root.get(User_.transactionId), transactionId));
criteria.orderBy(builder.asc(root.get(User_.date)));
TypedQuery<User> query = em.createQuery(criteria);
if (onlyFirst) {
query=query.setMaxResults(1);
}
return query.getResultList();
}
嗯,最简单的选择通常是尝试将相同的代码移动到它自己的方法中。在这里,您有多种选择,其中之一可能是这样的:
- 写一个新的(私有)方法:
private List<User> findFirstByTransactionId(String transactionId, boolean onlyOneResult) {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<User> criteria = builder.createQuery(User.class);
Root<User> root = criteria.from(User.class);
criteria.select(root).where(builder.equal(root.get(User_.transactionId), transactionId));
criteria.orderBy(builder.asc(root.get(User_.date)));
TypedQuery<User> query = em.createQuery(criteria);
if (onlyOneResult) {
query = query.setMaxResults(1);
}
return query.getResultList();
}
然后像这样重构现有的方法:
public List<User> findFirstByTransactionId(String transactionId) {
return findFirstByTransactionId(transactionId, false);
}
public List<User> findFirstByTransactionId(String transactionId) {
return findFirstByTransactionId(transactionId, true);
}
现在您消除了 8 行重复代码:)
更多的是附录。
建议添加布尔参数的其他答案是有效的,但是:干净的编码建议始终争取最少的参数数量。尤其不鼓励使用此类布尔参数。当然,这样做还是有意义的,可以避免代码重复。
但我会怎么做:
- 是的,内部有一个
private List<User> findFirstByTransactionId()
采用布尔参数
- 但是在您的 public 界面上,只需提供两种不同的方法,例如
public List<User> findFirstUserByTransactionId()
和 `public List findUsersByTransactionId()``
这两个public方法可以调用内部方法并传递true
/false
。使用布尔值来做出该决定是一个实现细节,您应该避免在事物的 public 方面使其可见。
我想重构这两种方法,除了“maxResult ()”外,它们几乎相同,这两种方法指的是两种不同的获取方式,一种是 returns 我是单个用户,另一种是 returns returns 改为列表。我怎样才能简化这两种方法(总是在有意义的情况下) 这些是 2 种方法:
第一种方法:
public List findFirstByTransactionId(String transactionId) {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<User> criteria = builder.createQuery(User.class);
Root<User> root = criteria.from(User.class);
criteria.select(root).where(builder.equal(root.get(User_.transactionId), transactionId));
criteria.orderBy(builder.asc(root.get(User_.date)));
TypedQuery<User> query = em.createQuery(criteria).setMaxResults(1);
return query.getSingleResult();
第二种方法:
public List<User> findAllByTransactionId(String transactionId) {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<User> criteria = builder.createQuery(User.class);
Root<User> root = criteria.from(User.class);
criteria.select(root).where(builder.equal(root.get(User_.transactionId), transactionId));
criteria.orderBy(builder.asc(root.get(User_.date)));
TypedQuery<User> query = em.createQuery(criteria);
return query.getResultList();
您在 query
上调用的方法与任何其他方法一样工作,因此您可以将一些调用放在 if
块中,如下所示:
public List<User> findByTransactionId(String transactionId, boolean onlyFirst) {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<User> criteria = builder.createQuery(User.class);
Root<User> root = criteria.from(User.class);
criteria.select(root).where(builder.equal(root.get(User_.transactionId), transactionId));
criteria.orderBy(builder.asc(root.get(User_.date)));
TypedQuery<User> query = em.createQuery(criteria);
if (onlyFirst) {
query=query.setMaxResults(1);
}
return query.getResultList();
}
嗯,最简单的选择通常是尝试将相同的代码移动到它自己的方法中。在这里,您有多种选择,其中之一可能是这样的:
- 写一个新的(私有)方法:
private List<User> findFirstByTransactionId(String transactionId, boolean onlyOneResult) {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<User> criteria = builder.createQuery(User.class);
Root<User> root = criteria.from(User.class);
criteria.select(root).where(builder.equal(root.get(User_.transactionId), transactionId));
criteria.orderBy(builder.asc(root.get(User_.date)));
TypedQuery<User> query = em.createQuery(criteria);
if (onlyOneResult) {
query = query.setMaxResults(1);
}
return query.getResultList();
}
然后像这样重构现有的方法:
public List<User> findFirstByTransactionId(String transactionId) {
return findFirstByTransactionId(transactionId, false);
}
public List<User> findFirstByTransactionId(String transactionId) {
return findFirstByTransactionId(transactionId, true);
}
现在您消除了 8 行重复代码:)
更多的是附录。
建议添加布尔参数的其他答案是有效的,但是:干净的编码建议始终争取最少的参数数量。尤其不鼓励使用此类布尔参数。当然,这样做还是有意义的,可以避免代码重复。
但我会怎么做:
- 是的,内部有一个
private List<User> findFirstByTransactionId()
采用布尔参数 - 但是在您的 public 界面上,只需提供两种不同的方法,例如
public List<User> findFirstUserByTransactionId()
和 `public List findUsersByTransactionId()``
这两个public方法可以调用内部方法并传递true
/false
。使用布尔值来做出该决定是一个实现细节,您应该避免在事物的 public 方面使其可见。