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는 여기에서 확인 가능합니다.
댓글남기기