Java Design Pattern - Filter Pattern

업데이트:

Design Pattern

  • 과거의 소프트웨어 개발 과정에서 발견된 설계의 노하우를 축적하여 이름을 붙여, 이후에 재이용하기 좋은 형태로 특정의 규약을 묶어서 정리한 것이다.
  • 디자인 패턴은 알고리즘이 아니라 상황에 따라 자주 쓰이는 설계 방법을 정리한 코딩 방법론일 뿐이며 모든 상황의 해결책이 아니다.

Structural Patterns, 구조 패턴

  • 클래스와 객체를 더 큰 결과물로 합칠 수 있는 구조로 설계하는 패턴이다.
  • 서로 다른 인터페이스를 지닌 여러 개의 객체를 조합하여 단일 인터페이스를 제공하거나, 객체들을 서로 묶어 새로운 기능을 제공하는 패턴이다.

Filter Pattern

  • 다양한 기준을 사용하여 객체 집합을 필터링하고 논리적 작업을 통해 분리된 방식으로 연결할 수 있도록하는 패턴이다.

Example

public enum Gender {
  MALE, FEMALE
}
public enum MaritalStatus {
  SINGLE, MARRIED
}
public class Person {

  private String name;
  private String gender;
  private String maritalStatus;

  public Person(String name, String gender, String maritalStatus) {
    this.name = name;
    this.gender = gender;
    this.maritalStatus = maritalStatus;
  }

  public String getName() {
    return name;
  }

  public String getGender() {
    return gender;
  }

  public String getMaritalStatus() {
    return maritalStatus;
  }

}
  • Filter Pattern을 적용할 Person 객체를 선언한다.
public interface Criteria {

  public List<Person> meetCriteria(List<Person> persons);

}
  • 결합 조건과 단일 조건을 위한 Criteria 인터페이스를 구현한다.
public class CriteriaMale implements Criteria {

  @Override
  public List<Person> meetCriteria(List<Person> persons) {
    List<Person> malePersons = new ArrayList<Person>();

    for (Person person : persons) {
      if (Gender.MALE.equals(person.getGender())) {
        malePersons.add(person);
      }
    }
    return malePersons;
  }

}
public class CriteriaFemale implements Criteria {

  @Override
  public List<Person> meetCriteria(List<Person> persons) {
    List<Person> femalePersons = new ArrayList<Person>();
    for (Person person : persons) {
      if (Gender.FEMALE.equals(person.getGender())) {
        femalePersons.add(person);
      }
    }
    return femalePersons;
  }

}
public class CriteriaSingle implements Criteria {

  @Override
  public List<Person> meetCriteria(List<Person> persons) {
    List<Person> singlePersons = new ArrayList<Person>();
    for (Person person : persons) {
      if (MaritalStatus.SINGLE.equals(person.getMaritalStatus())) {
        singlePersons.add(person);
      }
    }
    return singlePersons;
  }

}
public class CriteriaMarried implements Criteria {

  @Override
  public List<Person> meetCriteria(List<Person> persons) {
    List<Person> singlePersons = new ArrayList<Person>();
    for (Person person : persons) {
      if (MaritalStatus.MARRIED.equals(person.getMaritalStatus())) {
        singlePersons.add(person);
      }
    }
    return singlePersons;
  }

}
  • Gender와 MaritalStatus 별 단일 조건을 수행하기 위한 CriteriaMale, CriteriaFemale, CriteriaSingle, CriteriaMarried 클래스를 구현한다.
public class AndCriteria implements Criteria {

  private Criteria criteria;
  private Criteria otherCriteria;

  public AndCriteria(Criteria criteria, Criteria otherCriteria) {
    this.criteria = criteria;
    this.otherCriteria = otherCriteria;
  }

  @Override
  public List<Person> meetCriteria(List<Person> persons) {
    List<Person> firstCriteriaPersons = criteria.meetCriteria(persons);
    return otherCriteria.meetCriteria(firstCriteriaPersons);
  }

}
public class OrCriteria implements Criteria {

  private Criteria criteria;
  private Criteria otherCriteria;

  public OrCriteria(Criteria criteria, Criteria otherCriteria) {
    this.criteria = criteria;
    this.otherCriteria = otherCriteria;
  }

  @Override
  public List<Person> meetCriteria(List<Person> persons) {
    List<Person> firstCriteriaItems = criteria.meetCriteria(persons);
    List<Person> otherCriteriaItems = otherCriteria.meetCriteria(persons);

    for (Person person : otherCriteriaItems) {
      if (!firstCriteriaItems.contains(person)) {
        firstCriteriaItems.add(person);
      }
    }
    return firstCriteriaItems;
  }

}
  • 두 가지 조건으로 결합하여 조건을 수행하기 위한 AndCriteria와 OrCriteria를 구현한다.
public class CriteriaPatternMain {

  public static void main(String[] args) {
    List<Person> persons = new ArrayList<Person>();

    persons.add(new Person("Robert", Gender.MALE, MaritalStatus.SINGLE));
    persons.add(new Person("John", Gender.MALE, MaritalStatus.MARRIED));
    persons.add(new Person("Laura", Gender.FEMALE, MaritalStatus.MARRIED));
    persons.add(new Person("Diana", Gender.FEMALE, MaritalStatus.SINGLE));
    persons.add(new Person("Mike", Gender.MALE, MaritalStatus.SINGLE));
    persons.add(new Person("Bobby", Gender.MALE, MaritalStatus.SINGLE));

    Criteria male = new CriteriaMale();
    Criteria female = new CriteriaFemale();
    Criteria single = new CriteriaSingle();
    Criteria singleMale = new AndCriteria(single, male);
    Criteria singleOrFemale = new OrCriteria(single, female);

    System.out.println("Males: ");
    printPersons(male.meetCriteria(persons));

    System.out.println("Females: ");
    printPersons(female.meetCriteria(persons));

    System.out.println("Single Males: ");
    printPersons(singleMale.meetCriteria(persons));

    System.out.println("Single Or Females: ");
    printPersons(singleOrFemale.meetCriteria(persons));
  }

  public static void printPersons(List<Person> persons) {
    for (Person person : persons) {
      System.out.println("Person : [ Name : " + person.getName() + ", Gender : " + person.getGender()
          + ", Marital Status : " + person.getMaritalStatus() + " ]");
    }
  }

}
  • 각 독립적인 속성을 조건을 활용하여 분류가 가능하며, 조합도 가능하다.

Source

Sample Code는 여기에서 확인 가능합니다.

댓글남기기