[关闭]
@amoszhou 2014-04-28T16:52:37.000000Z 字数 1887 阅读 1108

借贷模式

scala 借贷模式


借贷模式,通俗一点说就是借鸡生蛋,相信这个词,大家都懂,在这篇博客中,我们主要讲讲这种思想,以及在scala和Java中的实现。

1.scala VS 借贷模式

我们先来看一段现成scala代码:

  1. import java.io.File
  2. import java.util.Scanner
  3. def withScanner(f: File, op: Scanner => Unit) = {
  4. val scanner = new Scanner(f)
  5. try {
  6. op(scanner)
  7. } finally {
  8. scanner.close()
  9. }
  10. }
  11. withScanner(new File("D:/modify.sql"), scanner => {
  12. while(scanner.hasNext)
  13. println("pid is" + scanner.next())
  14. })

首先,我们定义了一个方法withScanner,他接受2个参数:一个File类,还有一个是一个函数。在这里顺便说一下scala的匿名函数结构:
args=>returnType (多个参数直接用括号括起来,如(arg1,args2)=>returnType

接着,我们就调用了这个函数。结果就把modify.sql中的信息全打印出来了。

那么,看完这段代码,你现在能理解“借鸡生蛋”这种思想了吗?调用方,完全只需要关注自己的业务逻辑:

1.那个文件
2.通过scanner对这个文件做什么处理

我们不需要关注Scanner怎么创建,用完以后怎么关闭。我们只要专注于业务逻辑即可。

2.Java VS 借贷模式

上面我们基于scala语言的描述,那么我们现在将他转换为Java语言实现,直接看代码:

  1. public class ResourceHolder {
  2. public void withScanner(File file , TaskHandler handler) throws FileNotFoundException {
  3. Scanner scanner = new Scanner(file);
  4. try{
  5. handler.doTask(scanner);
  6. } finally {
  7. scanner.close();
  8. }
  9. }
  10. }
  11. public interface TaskHandler {
  12. void doTask(Scanner scanner);
  13. }

OK,架子就这样搭好了。怎么调用列?还是直接看代码:

  1. public static void main(String[] args) throws FileNotFoundException {
  2. withScanner(new File("D:/modify.sql"),new TaskHandler() {
  3. @Override
  4. public void doTask(Scanner scanner) {
  5. while (scanner.hasNext()){
  6. System.out.println(scanner.next());
  7. }
  8. }
  9. });
  10. }

这里我直接用了匿名类。你当然也可以写一个具体的实现类,然后new一个实例传进去。

3.课后联想

看了上面一段代码,你想到了什么?别急,静下心仔细想想。说几个我想到的:
1.早期用hibernate与spring集成的时候,大家写BaseDao,为了保证session在spring管控范围内,是不是写过这样的代码:

  1. public List findByPage(final String hql,final int offset,final int pageSize){
  2. List list = getHibernateTemplate().executeFind(
  3. new HibernateCallback(){
  4. public Object doInHibernate(Session session){
  5. List result = session.createQuery(hql)
  6. .setFirstResult(offset)
  7. .setMaxResults(pageSize)
  8. .list();
  9. return result;
  10. }
  11. });
  12. return list;
  13. }

怎么样?熟悉吧。
2.仔细想想Spring,SpringMVC的各个扩展点。是不是Spring都提供了一个接口(一般都会有一个default实现类),然后你只需要实现该接口,或者重写默认实现类。然后在Spring窗口中配置一下,你的扩展就生效了?仔细想想,其实实现原理也是这样。你不需要做很复杂的操作,你就可以获取到Ioc窗口中的Bean,Context等资源。

所以这其实是一个很好提供扩展点和资源管理的模式,如果你在你的工具类,或者是类库中合理使用,会让你的代码看起来更Nice,可护性更好。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注