정의

책임 연쇄 패턴은 핸들러들의 체인을 따라 요청을 처리하는 행동 디자인 패턴입니다.

따라서 순서가 굉장히 중요합니다. 

각 핸들러는 주어진 요청에 대한 처리를 담당하게 됩니다. (요청을  처리할지 말지, 다음 체인으로 넘길지 등등)

 

 

코드

import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;

public class CoREx {
	//커맨드 객체
	static class Person {
		String name;
		String sex;
		int age;
		public Person(String name, String sex, int age) {
			this.name = name;
			this.sex = sex;
			this.age = age;
		}
		@Override
		public String toString() {
			return "Person [name=" + name + ", sex=" + sex + ", age=" + age + "]";
		}
	}
	//각 요소를 요청이라고 가정한다.
	static List<Person> persons = new ArrayList<>();
	static {
		persons.add(new Person("김필터", "남", 20));
		persons.add(new Person("임자바", "남", 33));
		persons.add(new Person("이자바", "여", 22));
		persons.add(new Person("김자바", "여", 18));
		persons.add(new Person("이육사", "남", 27));
		persons.add(new Person("김육사", "여", 15));
		persons.add(new Person("박세종", "남", 30));
		persons.add(new Person("김세종", "남", 30));
	}
	//핸들러 
	static class Filter<T>{
		//나의 다음 체인 참조변수
		private Filter<T> nextFilter;
		//요구 사항
		private final Predicate<T> predi;
		
		protected Filter(Predicate<T> predi) {
			this.predi = predi;
		}
		@SafeVarargs //필터 체인 형성
		public static <T> Filter<T> createFilterChain(Filter<T> first, Filter<T>...filters){
			Filter<T> nowFilter = first;
			for(Filter<T> filter : filters) {
				nowFilter.nextFilter = filter;
				nowFilter = filter;
			}
			return first;
		}
		public boolean check(T data) {
			return predi.test(data) ? nextCheck(data) : false;
		}
		public boolean nextCheck(T data) {
			return nextFilter == null ? true : nextFilter.check(data);
		}
	}
	
	public static void main(String[] args) {
		//필터체인
		Filter<Person> filterChain = Filter.createFilterChain(
				new Filter<>(per -> per.age>=20)
				,new Filter<>(per -> per.sex.startsWith("남"))
				,new Filter<>(per -> per.name.startsWith("김"))
				);
		for(Person person : persons) {
			if(filterChain.check(person)) {
				System.out.println(person);
			}
		}
	}
}

결과

Person [name=김필터, sex=남, age=20]
Person [name=김세종, sex=남, age=30]

Filter는 사실 인터페이스나 추상클래스로 다루는 것이 더 좋으나, 편의상 일반 클래스로 구현

 

유사한 구조는 스프링 시큐리티에서 볼 수 있다.

 

 

'개발 > 디자인 패턴' 카테고리의 다른 글

생성 - 프로토타입(Prototype)  (0) 2023.05.13
구조 - 플라이웨이트(Flyweight)  (0) 2023.05.09
구조 - 빌더 패턴(Builder)  (0) 2023.05.03

+ Recent posts