前言
各位java技术爱好者,我们又见面了!
之前我在面试的时候遇到这个问题,当时答不上来。这件事就一直在我心里耿耿于怀。相信很多人面试完都有这种体验,哈哈~
不过今日不同往日了,现在我已经搞懂了,其实并不是很难。
开始搞事情
要学习一种技术,当然要搞清楚能解决什么问题,这是最关键的,否则就像买了一个开瓶器,还是用嘴咬开啤酒瓶盖一样(比喻很巧妙)。
例子
首先我们用Request
对象,表示一个请求。
public class Request {
//请求数据
private String data;
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
假设data
中有很多数据,我们要过滤掉一些关键字,比如水果
、蔬菜
。
如果不用设计模式,直接用if
解决,就是这样写:
public static void main(String[] args) throws Exception {
//创建请求体
String data = "肉蛋葱鸡水果蔬菜千层饼雅俗共赏第五层的马老师";
Request request = new Request();
request.setData(data);
String requestData = request.getData();
//如果包含水果关键字
if (requestData.contains("水果")) {
//过滤水果关键字
requestData = filterByWord(requestData, "水果");
}
//如果包含蔬菜关键字
if (requestData.contains("蔬菜")) {
//过滤蔬菜关键字
requestData = filterByWord(requestData, "蔬菜");
}
request.setData(requestData);
System.out.println(requestData);//肉蛋葱鸡千层饼雅俗共赏第五层的马老师
}
//过滤关键字的方法
private static String filterByWord(String data, String word) {
StringBuilder sb = new StringBuilder(data);
while (true) {
int index = sb.indexOf(word);
//如果不等于-1,搜索到关键字
if (index != -1) {
for (int i = 0; i < word.length(); i++) {
//关键字有多长就删多少次,比如水果,在index位置上删两次
sb.deleteCharAt(index);
}
} else {
//等于-1,没有关键字,跳出循环
break;
}
}
return sb.toString();
}
}
这样的代码在项目中不要太多,遇事不决来个if
,不行就再来一个。一般这种程序员就只看到了第一层。
问题:
1.如果这时候要增加多一些关键字呢,怎么处理?在原来的代码里继续加if
的话,那这个方法就越写越长。而且破坏了开闭原则
。
2.如果要调换顺序呢。难道要剪切复制代码?
所以一个好的程序员,实现功能只是基本要求,重要是代码要有好的维护性和扩展性。
怎么优化呢?
我们可以这样想,把每个过滤关键字的方法抽成一个类,然后定义一个过滤关键字的方法,因为有很多个类似职责的类,所以定义一个接口,公共的方法可以定义在接口。
第一步:定义过滤器接口
public interface Filter {
//接口方法
String doFilter(String data, FilterChain filterChain);
//过滤关键字的方法
default String filterByWord(String data, String word) {
StringBuilder sb = new StringBuilder(data);
while (true) {
int index = sb.indexOf(word);
if (index != -1) {
for (int i = 0; i < word.length(); i++) {
//关键字有几个字,就删几次。比如水果就在index删两次即可
sb.deleteCharAt(index);
}
} else {
//如果找不到关键字,就跳出循环
break;
}
}
return sb.toString();
}
}
第二步:定义水果关键字过滤器