public abstract class Filter {
protected Filter nextFilter;
abstract void process(String message);
public void setNextFilter(Filter nextFilter) {
this.nextFilter = nextFilter;
}
}
실제 적용할 필터 class LogFilter extends Filter {
@Override
void process(String message) {
Logger.info(message);
if (nextFilter != null) nextFilter.process(message);
}
}
class Profanityfilter extends Filter {
@Override
void process(String message) {
String newMessage = message.replaceAll("fuck","f*ck");
if (nextFilter != null) nextFilter.process(newMessage);
}
}
class RejectFilter extends Filter {
@Override
void process(String message) {
System.out.println("RejectFilter");
if (message.startsWith("[A Project NY]")) {
if (nextFilter. != null) nextFilter.process(message);
}
}
}
class StatisticsFilter extends Filter {
@Override
void process(String message) {
Statistics.addUsedChars(message.length());
if (nextFilter != null) nextFilter.process(message);
}
}
1. 각 필터를 만든다. 2. 서로 기차놀이처럼 연결한다. (순서를 만드는 것이다) Filter rejectFilter = new RejectFilter(); Filter logFilter = new LogFilter(); Filter profanityFilter = new ProfanityFilter(); Filter statsFilter = new StatisticsFilter(); rejectFilter.setNextFilter(logFilter); logFilter.setNextFilter(profanityFilter); profanityFilter.setNextFilter(statsFilter); String message = "[A PROFIT NY] What the fuck?"; rejectFilter.process(message);clojure 클로저는 각 필터를 함수로 만든다.
;; define filters
(defn log-filter [message]
(logger/log message)
message)
(defn stats-filter [message]
(stats/add-used-chars (count message))
message)
(defn profanity-filter [message]
(clojure.string/replace message "fuck" "f*ck"))
(defn reject-filter [message]
(if (.startsWith message "[A Profit NY]")
message))
(defn chain [message]
(some-> message
reject-filter
log-filter
stats-filter
profanity-filter))
저 some->가 뭐지? some->는 ->와 기능이 같다. 한가지만 빼고 표현식이 nil이면 멈춘다. 그리고 nil을 내뱉는다. nil이 아니면 값을 다음에 넘긴다.
(chain "fuck") => nil (chain "[A Profit NY] fuck") => "f*ck"[A profit NY] 가 없으면 reject-filter에서 이미 걸려서 nil이 나옴.
댓글 없음:
댓글 쓰기