基于多个参数返回结果的模式

时间:2015-12-22 19:42:06

标签: java design-patterns

我正在处理遗留代码,其中一个方法应该根据多个参数返回结果。代码中使用的模式有效,但我想是否可以进一步改进。我举一个例子

我们假设我有一个具有各种属性的JobPosting类

class JobPosting {
    int jobPostingId;
    String description;
    Dept dept; // A posting ca belong to 1 department at a time
    Location loc; // A job posting can belong to 1 location at a time
    String created By;
    int headcount; // number of people required to fill the job posting
    List<User> assignedUsers; // number  of people who have applied for the posting already
    List<User> reservedUsers; // users who are eligible to apply for the posting, if this is empty, then anyone can apply to posting
    DateTime visibleDate; // date from when posting is visible to users
    Date endDate; // posting's deadline
    ...
}

发布的这些详细信息存储在一个表中的数据库中

现在我有各种用例来获取帖子:

- Get job postings for a loc & dept- I only care about description and headcount.
- Get job posintgs for a loc & dept with users who have filled the postings
- Get job postings for a loc & dept with users who have filled and users who are eligible for the postings
- Get job postings for a loc & dept which are visibleToUsers (visibleDate < curdate)

等等,我可以根据场景获得发布的各种可能性。

目前的实施是我们有参数的构建模式

class postingsParams {
    boolean excludeFilledPostings;
    boolean excludeNonVisiblePostings;
    boolean returnAssignedUsers;
    boolean returnEligibleUsers;
}

和一种方法,它接收参数并确定要填充的JobPostings中的哪些字段以及要排除的帖子

getPostingsByLocDept(loc, dept, postingsParamas) { ...// code calls dynamic SQL queries to return results and if conditions to filter }

这似乎工作正常,但我不喜欢的是

- Each caller must be aware of all the possible crtireia to search
- If in future I want to add another criteria like excludePostingsWithPassedDeadline, I need to make changes to this method and need to test all the places where it is called to make sure nothing breaks

一种方法是为用例创建特定的get方法,但是使用这种方法我们最终可能会得到多个get方法,这可能是不可取的。

有没有办法改进这种设计,或者目前的方法是处理这种情况的最佳方法?

1 个答案:

答案 0 :(得分:0)

我建议使用JPA,使用spring实现(例如使用依赖org.springframework.data:spring-data-jpa:1.7.2.RELEASE)。

然后你只需定义扩展CrudRepository的接口,如:

public interface MyEntityRepo extends CrudRepository<MyEntity, Long>
{
    public Collection<MyEntity> findByAccountIdAndProductId( 
                                                       Long aAccountId, 
                                                       Long aProductId );

    MyEntity findByDeviceHwIdAndLicenseLicenseLicenseeName( String aHwId, String aLicenseeName );

    etc.

其中MyEntity是带注释的POJO bean,如:

@Entity
@Table( name = "my_entity" )
public class MyEntity implements java.io.Serializable
{
    private static final long serialVersionUID = 0L;

    @Id
    @GeneratedValue( strategy = IDENTITY )
    @Column( name = "id", unique = true, nullable = false )
    private Long Id;

    @Column( name = "account_id", nullable = false )
    private long accountId;

    @Column( name = "product_id", nullable = false )
    private long productId;

    @ManyToOne( fetch = FetchType.LAZY )
    @JoinColumn( name = "license_id", nullable = false )
    private License license;

etc.

其中,License是具有String成员licenseeName的连接实体。

JPA框架自动神奇地解析了这种接口方法,无需手动定义查询。