简体   繁体   中英

How to make my Filter Pattern more generic

I've written some code which uses the filter design pattern like so:

public class SingleLengthCriteria implements XsamCriteria {

private final FilterLength filterLength;

public SingleLengthCriteria(FilterLength filterLength)  {
  this.filterLength = filterLength;
}

@Override
public List<XsamRecord> meetRecordCriteria(List<XsamRecord> records) {
  List<XsamRecord> spanLengthRecords = new ArrayList<>();

  for(XsamRecord record : records){
    if(record.getXs() >= filterLength.getMin() && record.getXs() <= filterLength.getMax()){
    spanLengthRecords.add(record);
    }
  }

  return spanLengthRecords;
}

The FilterLength is just a pojo with a min and max cooordinate.

The XsamRecord is the object which is being filtered. In this example, i'm filtering on the XsamRecords getXs method which simple returns an integer.

This all works well, but I'm also looking to create the same thing for other getx... methods (they also return integers). For example, I have getxL , getxR . Writing the same thing over and over for a different getter isn't exactly keeping things DRY.

Is there any way to pass the get.. method into the constructor so that it knows which one to call in the for loop below?

Thanks in advance!

Yes there is a way, using method references. The syntax would be, for example, XsamRecord::getXs .

The type for the associated parameter would be Function<XsamRecord, Integer> .

public class SingleLengthCriteria implements XsamCriteria {

private final FilterLength filterLength;
private final Function<XsamRecord, Interger> propertyValueGetter;

public SingleLengthCriteria(FilterLength filterLength, Function<XsamRecord, Interger> propertyValueGetter)  {
  this.filterLength = filterLength;
  this.propertyValueGetter = propertyValueGetter;
}

@Override
public List<XsamRecord> meetRecordCriteria(List<XsamRecord> records) {
  List<XsamRecord> spanLengthRecords = new ArrayList<>();

  for(XsamRecord record : records){
    final Integer value = propertyValueGetter.apply(record);
    if(value >= filterLength.getMin() && value <= filterLength.getMax()){
    spanLengthRecords.add(record);
    }
  }

  return spanLengthRecords;
}

Used as:

new SingleLengthCriteria(..., XsamRecord::getXs);
new SingleLengthCriteria(..., XsamRecord::getOtherProperty);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM