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이 나옴.
댓글 없음:
댓글 쓰기