给一个多处使用到的类中的某些方法添加额外的处理动作

Author: ChinSyun Pang
Weibo: arthinking_plus
Posted in: http://www.itzhai.com

现有如下程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public interface Searcher {
List<String> searchSong(int songType);
}

public class LuceneSearcher implements Searcher{

@Override
public List<String> searchSong(int songType) {
List<String> result = new ArrayList<String>();
result.add("Wings you are the hero");
return result;
}
}

public class ProxyMain {

public static void main(String[] args){
LuceneSearcher searcher = new LuceneSearcher();
searcher.searchSong(1);
}
}

LuceneSearcher在项目中的很多地方都用到了,现在想在LuceneSearcher的searchSong()方法添加一个处理逻辑,为了进行全局的改动,避免在多处地方分别改动,现在使用代理模式,创建一个Searcher的代理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class CustomSearcher implements Searcher{

private Searcher searcher;

public CustomSearcher(Searcher searcher){
this.searcher = searcher;
}

@Override
public List<String> searchSong(int songType) {
List<String> result = searcher.searchSong(songType);
result.add("big blue ocean");
return result;
}

}

这样就可以只在对象的声明创建语句改动下,程序中调用的地方就可以保持原样了:

1
2
3
4
5
6
7
public class ProxyMain {

public static void main(String[] args){
LuceneSearcher searcher = new LuceneSearcher();
searcher.searchSong(1); // 调用的语句保持原样
}
}

如果Searcher接口有其他的实现,也可以很方便的使用这个代理方法改写方法了。另外,如果确定需要为接口的所有方法都使用代理进行改写,可以使用动态代理实现,而且通过使用动态代理(JDK动态代理也可以通过invoke方法判断当前是否想要改写的方法而进行处理,CGLib动态代理]对应为intercept方法),可以通过写一个代理处理类,就同时可以代理其他的类了,使用起来更灵活。

如果LuceneSearcher并不是通过实现接口的方式编写的,那么我们可以继承这个LuceneSearcher接口,并覆盖searchSong方法加入处理逻辑,这样也通过改动创建语句就可以很方便的对代码进行了调整。