【Java8新特性】02 函数式接口和Lambda表达式实战练习:环绕执行模式使行为参数化

Java8 由Oracle在2014年发布,是继Java5之后最具革命性的版本。 

Java8吸收其他语言的精髓带来了函数式编程,lambda表达式,Stream流等一系列新特性,学会了这些新特性,可以让你实现高效编码优雅编码。

01  引入实例

首先引入一个实际的例子,我们常常会写一个dao类来操作数据库,比如查询记录,插入记录等。

下面的代码中实现了查询和插入功能(引入Mybatis三方件):

publicclassStudentDao{

/**

    * 根据学生id查询记录

*@paramid 学生id

*@return返回学生对象

    */

publicStudentqueryOne(intid){

        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();

SqlSession session =null;

try{

            session = sqlSessionFactory.openSession();

// 根据id查询指定的student对象

returnsession.selectOne("com.coderspace.mapper.student.queryOne", id);

}finally{

if(session !=null) {

                session.close();

            }

        }

    }

/**

    * 插入一条学生记录

*@paramstudent 待插入对象

*@returntrue if success, else return false

    */

publicbooleaninsert(Student student){

        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();

SqlSession session =null;

try{

            session = sqlSessionFactory.openSession();

// 向数据库插入student对象

introws = session.insert("com.coderspace.mapper.student.insert", student);

returnrows >0;

}finally{

if(session !=null) {

                session.close();

            }

        }

    }

  }

观察上面的两个方法可以发现:

return session.selectOne("com.coderspace.mapper.student.queryOne", id);

int rows = session.insert("com.coderspace.mapper.student.insert", student);

除了上面这两行,其他的代码都是一样的,都是先获取session,然后执行核心操作,最后关闭session。

获取session和关闭session这段代码围绕着具体的核心操作代码,我们可以称这段代码为模板代码。

假如又来了一个需求,需要实现删除student方法,那么你肯定会copy上面的获取session和关闭session代码,这样做有太多重复的代码,作为一名优秀的工程师肯定不会容忍这种事情的发生。


02  环绕执行模式使行为参数化

怎么解决呢?现在请出我们的主角:环绕执行模式使行为参数化。

啥叫行为参数化?上面例子中我们已经观察到了,除了核心操作代码其他代码都是一模一样,那我们是不是可以将核心操作代码作为入参传入模板方法中,根据不同的行为分别执行。

变量对象很容易作为参数传入,行为可以采用lambda表达式传入。

下面开始重构之前的例子,主要可以分为三步:

(1)定义函数式接口;

(2)定义模板方法;

(3)传递lambda表达式

所有的环绕执行模式都可以套用上面这三步公式。

第一步:定义函数式接口

@FunctionalInterface

publicinterfaceDbOperation{

/**

    * 通用操作数据库接口

*@paramsession 数据库连接session

*@parammapperId 关联mapper文件id操作

*@paramparams 操作参数

*@return返回值,R泛型

    */

Roperate(SqlSession session, String mapperId, Object params);

}

定义了一个operate抽象方法,接收三个参数,返回泛型R。

第二步:定义模板方法

DbOperation是一个函数式接口,作为入参传入:

publicclassCommonDao{

publicRproccess(DbOperation<R> dbOperation, String mappperId, Object params){

        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();

SqlSession session =null;

try{

            session = sqlSessionFactory.openSession();

// 核心操作

returndbOperation.operate(session, mappperId, params);

}finally{

if(session !=null) {

                session.close();

            }

        }

    }

  }

第三步:传递lambda表达式

// 根据id查询学生

String mapperId ="com.coderspace.mapper.student.queryOne";

intstudentNo =123;

CommonDao commonDao =newCommonDao<>();

// 使用lambda传递具体的行为

Student studentObj = commonDao.proccess(

        (session, mappperId, params) -> session.selectOne(mappperId, params),

        mapperId, studentNo);

// 插入学生记录

String mapperId2 ="com.coderspace.mapper.student.insert";

Student student =newStudent("coderspace",1,100);

CommonDao commonDao2 =newCommonDao<>();

// 使用lambda传递具体的行为

Boolean successInsert = commonDao2.proccess(

        (session, mappperId, params) -> session.selectOne(mappperId, params),

        mapperId2, student);

实现了上面三步,假如要实现删除方法,CommonDao里面一行代码都不用改,只用在调用方传入不同的参数即可实现。

环绕执行模式在现实环境中大有用途,如果你发现几行易变的代码外面围绕着一堆固定的代码,这个时候你应该考虑使用lambda环绕执行模式了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343