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