from abc import ABCMeta, abstractmethod """ 1、设计要点: 过滤器模式中主要有三个角色,在设计过滤模式时要找到并区分这些角色。 (1)过滤的目标:即要被过滤的对象,通常是一个对象数组(对象列表)。 (2)过滤器:负责过滤不需要的对象,一般一个规则对应一个类。 (3)过滤器链:即过滤器的集合,负责管理和维护过滤器,用这个对象进行过滤器,它包含的每一个子过滤器都会进行一次过滤。这个类并不总是必要的, 但如果有多个过滤器,有这个类会带来极大的便利。 2、过滤器模式的优缺点 优点: (1)将对象的过滤、校验逻辑抽离出来,降低系统的复杂度。 (2)过滤规则可实现重复利用。 缺点: 性能较低,每个过滤器对每一个元素都会进行遍历。如果有n个元素,m个过滤器,则负责度为O(mn) 3、应用场景 (1)敏感词过滤、舆情监测。 (2)需要对对象列表(或数据列表)进行校验、审查或预处理的场景。 (3)对网络接口的请求和响应进行拦截,例如对每一个请求和响应记录日志,一遍日后分析。 在Scrapy的爬虫和下载器中间件、Django的中间件中都有点像应用了过滤器的模式。 """ class Filter(metaclass=ABCMeta): """过滤器""" @abstractmethod def doFilter(self, elements): pass class FilterChain(Filter): """过滤器链""" def __init__(self): self.__filters = [] def addFilter(self, filter): self.__filters.append(filter) def remove(self, filter): self.__filters.remove(filter) def doFilter(self, elements): for filter in self.__filters: elements = filter.doFilter(elements) return elements import re class SensitiveFilter(Filter): """敏感词过滤""" def __init__(self): self.__sensitives = ["黄色", "反动", "贪污"] def doFilter(self elements): # 敏感词列表转换成正则表达式 regex = "" for word in self.__sensitives: regex += word + "|" regex = regex[0:len(regex)-1] # 对每个元素进行过滤 newElements = [] for element in elements: item, num = re.subn(regex, "", element) newElements.append(item) return newElements class HtmlFilter(FIlter): """HTML特殊字符转换""" def __init__(self): self.__wordMap = { "&": "&", "'": " &apos", ">": ">", "<": "<", """: """, } def doFIlter(self, elements): newElements = [] for element in elements: for key, value in self.__wordMap.items(): element = element.replace(key, value) newElements.append(element) return newElements