敏感词null是什么null啥意思医学上?

1.DFA实现原理DFA全称为:Deterministic Finite Automaton,即确定有穷自动机。存储:一次性的把所有的敏感词存储到了多个map中,就是下图表示这种结构敏感词:冰毒、大麻、大坏蛋检索的过程2.实现步骤2.1 创建敏感词数据库表1).2).创建实体类package com.heima.model.wemedia.pojos; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.io.Serializable; import java.util.Date; /** *

* 敏感词信息表 *

* * @author itheima */ @Data @TableName("wm_sensitive") public class WmSensitive implements Serializable { private static final long serialVersionUID = 1L; /** * 主键 */ @TableId(value = "id", type = IdType.AUTO) private Integer id; /** * 敏感词 */ @TableField("sensitives") private String sensitives; /** * 创建时间 */ @TableField("created_time") private Date createdTime; } 3.创建Mapper,查询敏感词库存入集合package com.heima.wemedia.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.heima.model.wemedia.pojos.WmSensitive; import org.apache.ibatis.annotations.Mapper; @Mapper public interface WmSensitiveMapper extends BaseMapper { } 这里用到了工具类中的两个方法,第一个initMap是给每一个字存入Map集合,加个0或1的标记,用来区分是否是结尾的字,第二个matchWords是查找对应的词是否在敏感词库,如果在里面就返回Map对象,实例:贷款=1意思是该词出现了多少次。 //初始化敏感词库 SensitiveWordUtil.initMap(sensitiveList); //查看文章中是否包含敏感词 Map map = SensitiveWordUtil.matchWords(content); 工具类package com.heima.utils.common; import java.util.*; public class SensitiveWordUtil { public static Map dictionaryMap = new HashMap<>(); /** * 生成关键词字典库 * @param words * @return */ public static void initMap(Collection words) { if (words == null) { System.out.println("敏感词列表不能为空"); return ; } // map初始长度words.size(),整个字典库的入口字数(小于words.size(),因为不同的词可能会有相同的首字) Map map = new HashMap<>(words.size()); // 遍历过程中当前层次的数据 Map curMap = null; Iterator iterator = words.iterator(); while (iterator.hasNext()) { String word = iterator.next(); curMap = map; int len = word.length(); for (int i =0; i < len; i++) { // 遍历每个词的字 String key = String.valueOf(word.charAt(i)); // 当前字在当前层是否存在, 不存在则新建, 当前层数据指向下一个节点, 继续判断是否存在数据 Map wordMap = (Map) curMap.get(key); if (wordMap == null) { // 每个节点存在两个数据: 下一个节点和isEnd(是否结束标志) wordMap = new HashMap<>(2); wordMap.put("isEnd", "0"); curMap.put(key, wordMap); } curMap = wordMap; // 如果当前字是词的最后一个字,则将isEnd标志置1 if (i == len -1) { curMap.put("isEnd", "1"); } } } dictionaryMap = map; } /** * 搜索文本中某个文字是否匹配关键词 * @param text * @param beginIndex * @return */ private static int checkWord(String text, int beginIndex) { if (dictionaryMap == null) { throw new RuntimeException("字典不能为空"); } boolean isEnd = false; int wordLength = 0; Map curMap = dictionaryMap; int len = text.length(); // 从文本的第beginIndex开始匹配 for (int i = beginIndex; i < len; i++) { String key = String.valueOf(text.charAt(i)); // 获取当前key的下一个节点 curMap = (Map) curMap.get(key); if (curMap == null) { break; } else { wordLength ++; if ("1".equals(curMap.get("isEnd"))) { isEnd = true; } } } if (!isEnd) { wordLength = 0; } return wordLength; } /** * 获取匹配的关键词和命中次数 * @param text * @return */ public static Map matchWords(String text) { Map wordMap = new HashMap<>(); int len = text.length(); for (int i = 0; i < len; i++) { int wordLength = checkWord(text, i); if (wordLength > 0) { String word = text.substring(i, i + wordLength); // 添加关键词匹配次数 if (wordMap.containsKey(word)) { wordMap.put(word, wordMap.get(word) + 1); } else { wordMap.put(word, 1); } i += wordLength - 1; } } return wordMap; } public static void main(String[] args) { List list = new ArrayList<>(); list.add("**"); list.add("**"); initMap(list); String content="我是一个好人,并不会卖**,也不操练***,我真的不卖**"; Map map = matchWords(content); System.out.println(map); } } 3.图片文字识别什么是OCR?OCR (Optical Character Recognition,光学字符识别)是指电子设备(例如扫描仪或数码相机)检查纸上打印的字符,通过检测暗、亮的模式确定其形状,然后用字符识别方法将形状翻译成计算机文字的过程方案 说明 百度OCR 收费 Tesseract-OCR Google维护的开源OCR引擎,支持Java,Python等语言调用 Tess4J 封装了Tesseract-OCR ,支持Java调用 3.1Tess4j案例3.1.1.创建项目导入tess4j对应的依赖 net.sourceforge.tess4j tess4j 4.1.1 3.1.2.导入中文字体库, 把资料中的tessdata文件夹拷贝到自己的工作空间下(这里我放到MinIo了)3.1.3.编写测试类进行测试package com.heima.tess4j; import net.sourceforge.tess4j.ITesseract; import net.sourceforge.tess4j.Tesseract; import java.io.File; public class Application { public static void main(String[] args) { try { //获取本地图片 File file = new File("D:\\26.png"); //创建Tesseract对象 ITesseract tesseract = new Tesseract(); //设置字体库路径 tesseract.setDatapath("D:\\workspace\\tessdata"); //中文识别 tesseract.setLanguage("chi_sim"); //执行ocr识别 String result = tesseract.doOCR(file); //替换回车和tal键 使结果为一行 result = result.replaceAll("\\r|\\n","-").replaceAll(" ",""); System.out.println("识别的结果为:"+result); } catch (Exception e) { e.printStackTrace(); } } } 注:记得下载MinIo里的图片的时候别忘了调用它自己下载的方法,先下下来审核,如果是本地的话当我没说
真正的大师,永远都怀着一颗学徒的心 -------无极剑圣 · 易适配器是什么?适配器是一个接口转换器,它可以是一个独立的硬件接口设备,允许硬件或电子接口与其它硬件或电子接口相连,也可以是信息接口。比如:电源适配器、三角架基座转接部件、USB与串口的转接设备等(百度百科)。很抽象?我们来看几张图片,你就会明白适配器是什么了。投影转接头,由于有些电脑的接口与投影的接口不一致,所以就会导致电脑使用不了投影,所以投影转接头就是将电脑和投影两者做了适配,让电脑可能正常使用与它不匹配的投影。耳机转接头,用过苹果手机的应该都知道,3.5mm的耳机接口是无法接入苹果手机的,但是我又想用它,怎么办呢?这个时候耳机转接头出现了,他负责将3.5mm的耳机接口适配成苹果支持的耳机接口,这样,我们就可以拿着3.5mm的耳机去连接苹果手机。通过这两个例子大家对适配器是什么应该有了一个大致的了解了吧,而我们今天要讲的内容是设计模式中常见的一种:适配器模式。什么是适配器模式?适配器模式(英语:adapter pattern)有时候也称包装样式或者包装(英语:wrapper)。将一个类的接口转接成用户所期待的。一个适配使得因接口不兼容而不能在一起工作的类能在一起工作,做法是将类自己的接口包裹在一个已存在的类中。专业解释总是那么的不近人情,让人捉摸不透,我来举个简单的例子吧,假如你开发的系统现在正在升级,由 1.0 -> 2.0 许多接口都发生了翻天覆地的变化,由于兼容性的问题,并不能直接将老接口删除,但是老接口的实现确实严重拖慢了程序的效率,老接口和新接口的参数完全不一样,这个时候怎么办呢?有没有一个类可以帮忙做个中转,将老接口的数据转换成新接口的数据,然后调用新接口,这样效率是不是就快很多了呢?没错,适配器模式就是干这个的,他就是将两个原本不兼容的方法或者接口通过转接变成可以相互通信的工具。看起来是不是很简单呢?适配器模式的原理确实很简单,那我们应该怎么去实现它呢?适配器模式的实现方式主要有两种:继承、组合,什么时候用继承,什么时候用组合呢?简单点来说就是类适配器使用继承关系实现,对象适配器使用组合关系实现,很抽象?没关系,我们一起用代码实现这两种方式,看完代码之后你就能理解这两种实现方式了。废话不多说,先看第一种:类适配器。package com.liuxing.adapter.adaptee;
/**
* @ProjectName: hxjm
* @Package: com.hxjm.fish
* @ClassName: FishGwService
* @Author: 流星007
* @Description: 需要转接的接口定义
类适配器
基于继承
* csdn:https://blog.csdn.net/qq_33220089
* 今日头条:https://www.toutiao.com/c/user/5372182357/#mid=1637641735275523
* @Date: 2021/4/19 20:38
* @Version: 1.0
*/
public interface ITarget {
void doSomthing1();
void doSomthing2();
void doSomthing3();
}
package com.liuxing.adapter.adaptee;
/**
* @ClassName MyAdaptee
* @Description 与Itarget定义的接口不兼容的类
* csdn:https://blog.csdn.net/qq_33220089
* 今日头条:https://www.toutiao.com/c/user/5372182357/#mid=1637641735275523
* @Author ymy
* @Date 2021/4/27 11:14
*/
public class MyAdaptee {
public void todo1(){
System.out.println("这是 todo1");
}
public void todo2(){
System.out.println("这是 todo2");
}
public void doSomthing3(){
System.out.println("这是 todo3");
}
}
package com.liuxing.adapter.adaptee;
/**
* @ClassName MyAdaptor
* @Description 适配器,将原本不兼容Itarget的接口转化为兼容Itarget的接口
* csdn:https://blog.csdn.net/qq_33220089
* 今日头条:https://www.toutiao.com/c/user/5372182357/#mid=1637641735275523
* @Author ymy
* @Date 2021/4/27 11:20
*/
public class MyAdaptor extends MyAdaptee implements ITarget {
@Override
public void doSomthing1() {
super.todo1();
}
@Override
public void doSomthing2() {
System.out.println("我是被重新实现的dosomthing2");
}
}第二种:对象适配器package com.liuxing.adapter;
/**
* @ClassName MyObjectAdaptor
* @Description 适配器,对象适配器
* @Author: 流星007
* @Date 2021/4/27 14:08
*/
public class MyObjectAdaptor implements ITarget {
private MyAdaptee myAdaptee;
public MyObjectAdaptor(MyAdaptee myAdaptee) {
this.myAdaptee = myAdaptee;
}
@Override
public void doSomthing1() {
//交给 MyAdaptee 实现
myAdaptee.todo1();
}
@Override
public void doSomthing2() {
System.out.println("我是被重新实现的dosomthing2");
}
@Override
public void doSomthing3() {
myAdaptee.doSomthing3();
}
}
package com.liuxing.adapter;
import com.sun.corba.se.spi.oa.ObjectAdapter;
/**
* @ClassName Test
* @Description 测试
* @Author: 流星007
* @Date 2021/4/27 13:56
*/
public class Test {
public static void main(String[] args) {
//类适配器
ITarget classAdaptor = new MyClassAdaptor();
classAdaptor.doSomthing1();
classAdaptor.doSomthing2();
classAdaptor.doSomthing3();
System.out.println("============================");
//对象适配器
ITarget objectAdaptor = new MyObjectAdaptor(new MyAdaptee());
objectAdaptor.doSomthing1();
objectAdaptor.doSomthing2();
objectAdaptor.doSomthing3();
}
}ITarget:表示需要转接成的接口定义。MyAdaptee:是不兼容 ITarget 接口定义的接口。MyClassAdaptor:将 Adaptee 转化成一组符合 ITarget 接口定义的接口(类适配器)。MyObjectAdaptor:将 Adaptee 转化成一组符合 ITarget 接口定义的接口(对象适配器)。Test:测试类输出结果如下这是 todo1
我是被重新实现的dosomthing2
这是 todo3
============================
这是 todo1
我是被重新实现的dosomthing2
这是 todo3
Process finished with exit code 0这两种实现方式都比较的巧妙,如果看不太明白的话可以结合着实际的应用场景再试试,个人觉得还是没有那么难理解,不过现在还有一个问题需要我们进一步分析,是什么呢?什么时候使用类适配器,什么时候使用对象适配器呢?我们都说组合优于继承,当然是优先选择对象适配器啦,千万不要有这种想法,虽然组合优于继承,但这并不能说明任何情况组合都比继承适用,那我们如何来判断这两种实现方式呢?标准主要有两个,第一个是 MyAdaptee 的接口个数,第二个则是 MyAdaptee 与 ITarget 的契合程度。这怎么理解呢?MyAdaptee 接口较少,类适配器和对象适配器两者任选其一即可。MyAdaptee 接口很多,但是大部分的接口 都是与 ITarget 相同,只是少部分存在区别,那么推荐使用类适配器(继承实现),改动代码量相对于对象适配器来说较少。MyAdaptee 接口很多,并且大部分的接口都不相同,这个时候推荐使用对象适配器(组合实现),因为组合比继承更加的灵活。适配器模式应用场景适配器模式的应用场景还是比较多的,但是这种设计模式多用于补救,当程序设计出现问题,升级改变较大时,需要一个类似适配器的东西将他们连接起来,所以我们在正常的开发中使用这种模式的机会还是不多的,也希望同学们设计的程序都是很稳定,不会用到适配器来做补救。敏感词过滤升级兼容架构设计缺陷Slf4j日志打印外部依赖应用场景太多,我拿敏感词过滤来做一个demo说明吧,敏感词大家应该都了解过,玩游戏的时候如果有一个队友超鬼了,那么其他队友就会对他进行亲切的问候,这个时候有些太过优雅的词会被 ”**“ 代替,这个就是我们说的敏感词过滤。假设我们系统一共有三家敏感词过滤的厂商,但是他们的接口标准都不相同,一般的写法是什么样的呢?上代码package com.liuxing.adapter.demo;
import org.apache.commons.lang3.ObjectUtils;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName AliSensitiveWordFilter
* @Description 某里云过滤
* @Author liuxing007
* @Date 2021/4/27 16:07
*/
public class AliSensitiveWordFilter {
private static final List<String> sensitiveWords = new ArrayList<>(3);
static {
sensitiveWords.add("垃圾");
sensitiveWords.add("废物");
sensitiveWords.add("滚");
}
/**
* @param filterWordVo
* @return java.lang.String
* @Description 过滤
* @Date 2021/4/27 16:34
*/
public String filterWord(FilterWordVo filterWordVo) {
if (ObjectUtils.isEmpty(filterWordVo)) {
return null;
}
String repWord = filterWordVo.getRepWord();
String word = filterWordVo.getWord();
for (String sensitiveWord : sensitiveWords) {
if (word.indexOf(sensitiveWord) >= 0) {
System.out.println("找到敏感词:" + sensitiveWord + ",直接替换");
word = word.replaceAll(sensitiveWord, repWord);
}
}
return word;
}
}
package com.liuxing.adapter.demo;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName DuSensitiveWordFilter
* @Description 某度云过滤
* @Author liuxing007
* @Date 2021/4/27 16:07
*/
public class DuSensitiveWordFilter {
private static final List<String> sensitiveWords = new ArrayList<>(3);
static {
sensitiveWords.add("爸");
sensitiveWords.add("妈");
sensitiveWords.add("爷");
}
/**
* @param word
需要过滤的内容
* @param repWord 需要替换成什么
* @return java.lang.String
* @Description 过滤
* @Date 2021/4/27 16:34
*/
public String filterWord(String word, String repWord) {
if (StringUtils.isAllEmpty(word, repWord)) {
return null;
}
for (String sensitiveWord : sensitiveWords) {
if (word.indexOf(sensitiveWord) >= 0) {
System.out.println("找到敏感词:" + sensitiveWord + ",直接替换");
word = word.replaceAll(sensitiveWord, repWord);
}
}
return word;
}
}
package com.liuxing.adapter.demo;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @ClassName WeiSensitiveWordFilter
* @Description 某为云过滤
* @Author ymy
* @Date 2021/4/27 16:07
*/
public class WeiSensitiveWordFilter {
private static Map<Integer, String> filterMap = new HashMap<>();
private static final List<String> sensitiveWords = new ArrayList<>(3);
static {
//将敏感词过滤为 *
filterMap.put(1, "*");
//将敏感词过滤为空字符串
filterMap.put(2, "");
//将敏感词过滤为 -
filterMap.put(3, "-");
sensitiveWords.add("干");
sensitiveWords.add("操");
sensitiveWords.add("怼");
}
/**
* @param word 需要过滤的内容
* @param type 需要替换成什么
* @return java.lang.String
* @Description 过滤
* @Date 2021/4/27 16:34
*/
public String filterWord(String word, Integer type) {
if (StringUtils.isEmpty(word)
type == null) {
return null;
}
String repWord = filterMap.get(type);
for (String sensitiveWord : sensitiveWords) {
if (word.indexOf(sensitiveWord) >= 0) {
System.out.println("找到敏感词:" + sensitiveWord + ",直接替换");
word = word.replaceAll(sensitiveWord, repWord);
}
}
return word;
}
}
package com.liuxing.adapter.demo.normal;
import com.liuxing.adapter.demo.AliSensitiveWordFilter;
import com.liuxing.adapter.demo.DuSensitiveWordFilter;
import com.liuxing.adapter.demo.FilterWordVo;
import com.liuxing.adapter.demo.WeiSensitiveWordFilter;
/**
* @ClassName SensitiveWordFilterService
* @Description 敏感词过滤处理
* @Author liuxing007
* @Date 2021/4/27 17:28
*/
public class SensitiveWordFilterService {
private AliSensitiveWordFilter aliSensitiveWordFilter = new AliSensitiveWordFilter();
private DuSensitiveWordFilter duSensitiveWordFilter = new DuSensitiveWordFilter();
private WeiSensitiveWordFilter weiSensitiveWordFilter = new WeiSensitiveWordFilter();
public String filter(String word) {
FilterWordVo filterWordVo = FilterWordVo.builder().word(word).repWord("*").build();
word = aliSensitiveWordFilter.filterWord(filterWordVo);
word = duSensitiveWordFilter.filterWord(word, "*");
word = weiSensitiveWordFilter.filterWord(word, 1);
return word;
}
}
package com.liuxing.adapter.demo;
import lombok.Builder;
import lombok.Data;
/**
* @ClassName FilterWordVo
* @Description 敏感词过滤参数
* @Author liuxing007
* @Date 2021/4/27 16:09
*/
@Data
@Builder
public class FilterWordVo {
/**
*需要替换的内容
*/
private String word;
/**
*替换成什么
*/
private String repWord;
}
package com.liuxing.adapter.demo.normal;
/**
* @ClassName Test
* @Description 敏感词过滤测试
* @Author liuxing007
* @Date 2021/4/27 16:38
*/
public class Test {
public static void main(String[] args) {
SensitiveWordFilterService sensitiveWordFilterService = new SensitiveWordFilterService();
String word = sensitiveWordFilterService.filter("你就是一个垃圾,这么菜,你妈妈没教你打游戏吗?干");
System.out.println("过滤后的内容:" + word);
}
}AliSensitiveWordFilter:某里云过滤DuSensitiveWordFilter:某度过滤WeiSensitiveWordFilter:某为云过滤FilterWordVo:敏感词过滤所需要的参数信息SensitiveWordFilterService:敏感词过滤处理类Test:测试类一共有三家过滤敏感词的厂商,我在SensitiveWordFilterService 类中 filter()方法分别组装了这三家厂商需要的参数,然后进行依次调用过滤,将最终的结果进行返回。这样写完全没有问题,但是这里有一个问题,那就是扩展性很差,如果我继续增加一个厂商或者删除一个厂商,我都需要去改 SensitiveWordFilterService 类中的 filter()方法,非常麻烦而且还是容出现bug,所以这个时候,就需要我们的适配器模式上场了,我们把过滤这件事情交给它,由它去对每个厂商做适配,这样,在后续改动的过程中,我就不需要平凡的去改动 SensitiveWordFilterService 类 。适配器改造代码开始package com.liuxing.adapter.demo.adaptor;
public interface ISensitiveWordFilter {
/**
* @Description
过滤
* @Date
2021/4/27 17:51
* @param word
* @return java.lang.String
*/
String filter(String word);
}
package com.liuxing.adapter.demo.adaptor;
import com.liuxing.adapter.demo.AliSensitiveWordFilter;
import com.liuxing.adapter.demo.FilterWordVo;
/**
* @ClassName AliSensitiveWordFilterAdaptor
* @Description 某里云适配类
* @Author liuxing007
* @Date 2021/4/27 17:52
*/
public class AliSensitiveWordFilterAdaptor implements ISensitiveWordFilter {
private AliSensitiveWordFilter aliSensitiveWordFilter = new AliSensitiveWordFilter();
@Override
public String filter(String word) {
FilterWordVo filterWordVo = FilterWordVo.builder().word(word).repWord("*").build();
return aliSensitiveWordFilter.filterWord(filterWordVo);
}
}
package com.liuxing.adapter.demo.adaptor;
import com.liuxing.adapter.demo.DuSensitiveWordFilter;
/**
* @ClassName AliSensitiveWordFilterAdaptor
* @Description 某度适配类
* @Author liuxing007
* @Date 2021/4/27 17:52
*/
public class DuSensitiveWordFilterAdaptor implements ISensitiveWordFilter {
private DuSensitiveWordFilter duSensitiveWordFilter = new DuSensitiveWordFilter();
@Override
public String filter(String word) {
return duSensitiveWordFilter.filterWord(word, "*");
}
}
package com.liuxing.adapter.demo.adaptor;
import com.liuxing.adapter.demo.WeiSensitiveWordFilter;
/**
* @ClassName AliSensitiveWordFilterAdaptor
* @Description 某为适配类
* @Author liuxing007
* @Date 2021/4/27 17:52
*/
public class WuiSensitiveWordFilterAdaptor implements ISensitiveWordFilter {
private final WeiSensitiveWordFilter weiSensitiveWordFilter = new WeiSensitiveWordFilter();
@Override
public String filter(String word) {
return weiSensitiveWordFilter.filterWord(word, 1);
}
}
package com.liuxing.adapter.demo.adaptor;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName AdaptorManagent
* @Description 适配器管理
* @Author liuxing007
* @Date 2021/4/27 17:57
*/
public class AdaptorManagent {
private List<ISensitiveWordFilter> sensitiveWordFilters = new ArrayList<>();
public void addAdaptor(ISensitiveWordFilter sensitiveWordFilter) {
sensitiveWordFilters.add(sensitiveWordFilter);
}
public String filter(String word){
for(ISensitiveWordFilter sensitiveWordFilter: sensitiveWordFilters){
word = sensitiveWordFilter.filter(word);
}
return word;
}
}
package com.liuxing.adapter.demo.adaptor;
/**
* @ClassName AdaptorTest
* @Description 测试
* @Author ymy
* @Date 2021/4/27 18:01
*/
public class AdaptorTest {
public static void main(String[] args) {
AdaptorManagent adaptorManagent = new AdaptorManagent();
adaptorManagent.addAdaptor(new AliSensitiveWordFilterAdaptor());
adaptorManagent.addAdaptor(new DuSensitiveWordFilterAdaptor());
adaptorManagent.addAdaptor(new WuiSensitiveWordFilterAdaptor());
String word = adaptorManagent.filter("你就是一个垃圾,这么菜,你妈妈没教你打游戏吗?干");
System.out.println("过滤后的内容:" + word);
}
}很明显,通过引入适配器模式的改造,代码变多了,这是不是就意味着变复杂了呢?有没有变复杂,我觉得它是相对的,如果敏感词过滤只有两家厂商,永远都不会添加或者删除了,我们引入适配器模式,这样确实把简单问题复杂化了,有点画蛇添足,很明显,敏感词过滤的厂商当然是多多益善,而且变动也会比较频繁,比如某一家厂商价格升高了,那我就换一家,我觉得现在用的这几家还是不能过滤所有的敏感词,我又引入了 2 家新的厂商,在这些情况下,普通的实现方式会比较吃力,每次修改厂商都需要改动核心代码,非常容易就整出bug,不但你难过,测试也难过,明明之前没有问题的,加了一个厂商就导致所有厂商都有问题了,一个脑袋两个大,所以,这个时候,推荐使用适配器模式,在适配器模式下,你无需改动过滤的核心代码,如果你添加新的厂商,只需要新增一个类,并且实现ISensitiveWordFilter 接口即可,有的同学可能就会问了,添加删除的时候不是在 main 函数中也有修改吗?没错,目前demo中确实需要在main函数中做修改,但是正常开发中,肯定是不会这么写的,你可以通过注解的方式在项目启动的时候就把所有的适配器都加载出来,这样后续的改动,只需要增加或者删除实现类即可,非常的方便。总结什么是适配器模式?适配器模式(英语:adapter pattern)有时候也称包装样式或者包装(英语:wrapper)。将一个类的接口转接成用户所期待的。一个适配使得因接口不兼容而不能在一起工作的类能在一起工作,做法是将类自己的接口包裹在一个已存在的类中。简单点来说,就是让两个原本不发通信的两个类通过转接编程可以正常通信。适配器的两种实现方式?类适配器:使用继承关系实现,如果需要适配的接口很多,并且大部分相同,只存在少部分不同的场景推荐使用类适配器。对象适配器:对象适配器使用组合关系实现,如果需要适配的接口很多,并且大部分接口都不相同的场景下推荐对象适配器。适配器的应用场景?适配器模式的应用场景还是比较多的,但是这种设计模式多用于补救,当程序设计出现问题,升级改变较大时,需要一个类似适配器的东西将他们连接起来,所以我们在正常的开发中使用这种模式的机会还是不多的,也希望同学们设计的程序都是很稳定,不会用到适配器来做补救。敏感词过滤升级兼容架构设计缺陷Slf4j日志打印外部依赖总的来说,适配器用于补救,当我们设计接口的时候一定要考虑到它的扩展性,不能为了一时方便,导致后面为了填坑而掉头发。所以不要总是想着先实现,后面再优化,可能到了后面,头发掉完了都不一定能成功将它优化。如果觉得我的博客对你有所帮助,还希望你能吝啬点个赞加关注,读者的肯定就是我写作的动力!源代码:https://github.com/361426201/design-mode.git推荐的设计模式文章「设计模式」单例模式「设计模式」观察者模式:一个注册功能也能使用到设计模式?「设计模式」建造者模式:你创建对象的方式有它丝滑吗?「设计模式」职责链模式:如果第三方短信平台挂了怎么办?「设计模式」原型模式:如何快速的克隆出一个对象?「设计模式」门面模式:接口就像门面,一眼就能看出你的代码水平「设计模式」职责链模式:如果第三方短信平台挂了怎么办?「设计模式」工厂模式:你还在使用一堆的if/else创建对象吗?

我要回帖

更多关于 null啥意思医学上 的文章

 

随机推荐