【问题标题】:Pattern for returning results based on multiple parameters基于多个参数返回结果的模式
【发布时间】:2015-12-22 19:42:05
【问题描述】:

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

假设我有一个具有各种属性的类 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 方法,这可能是不可取的。

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

【问题讨论】:

标签: java design-patterns


【解决方案1】:

我建议使用 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 是具有字符串成员 licenseeName 的联合实体。

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

【讨论】:

    猜你喜欢
    • 2016-07-05
    • 1970-01-01
    • 2021-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多