论坛首页 Java企业应用论坛

Scala:使用Curry实现AOP

浏览 4082 次
精华帖 (0) :: 良好帖 (4) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-01-28   最后修改:2011-01-28
业余时间学了学Scala,至今有3个多月了...这两天看到群(54813143)里有同学讨论AOP,于是就想出了如下实现;
见代码及注释,欢迎喜欢Scala的同学一起讨论:
//trait里没有任何抽象的值或方法
trait AOP{
	private var targets=List[Function1[String,Any]]() //List里放的都是函数对象
	private val placeholder="" //无意义,用来调用函数对象的

	def before=println("before...")
	def after=println("after...")
	def invoke(target:Function1[String,Any])={ //参数是个函数对象
		before
		target(placeholder) //什么时候调用,自己放置顺序
		after
	}
	def add(t:Function1[String,Any])= targets=t::targets  //收集所有被拦截的方法(函数对象)
	def invokeAll()={
		before
		targets.reverse.foreach(t=>t(placeholder)) //reverse:保证调用的顺序(FIFO)
		after
		//这里需要一个清空targets的方法,就不写了
	}
}

class Write extends AOP{
	def writeOne(x:String,y:String)(placeholder:String)={ //curry化,最后一个placeholder算是冗余参数
		println("one working..."+x+y)
	}
	def writeTwo(x:String,y:String,z:String)(placeholder:String)={
		println("two working..."+x+y+z)
	}
}

val w=new Write()
w.invoke(w.writeOne("hello"," world")_) //拦截的方式,使用了偏应用函数

w.add(w.writeOne("hello"," world")_) //收集
w.add(w.writeTwo("hello"," world"," more")_) //再收集
w.invokeAll //统一拦截

这里只是给喜欢Scala的同学一个思路,期望在此思路上进行扩展。
是不是很优雅? 还在等什么,快快加入到Scala的学习队伍中来吧。
   发表时间:2011-01-30   最后修改:2011-01-30
使用trait实现AOP的一般思路是利用它的stackable modification特性。我平时接触的AOP多在一个实现上进行若干次切面,楼主这个正好相反,倾向于基于多个实现的顺序调用,对应固定的两个切面(一个before一个after),这样就更象使用了偏函数的observer模式,没有更详细的场景不好更深入讨论下去。
如果按常规AOP套路考虑,我觉得重点是切面(before/after)的灵活性,比如,可以绑多个before/after方法,其签名与主实现一致,同时考虑before里可以控制是否把控制转向下一个,after里可以拿到主实现的返回值等等。这个在scala里由于有更强大的类型系统和偏函数等概念,会更有意思,我也没想清楚,请大家继续讨论。
0 请登录后投票
   发表时间:2011-02-01  
Scala作为函数式语言,根本用不着什么通用AOP把,随手一个Curry函数,就实现了
0 请登录后投票
   发表时间:2011-02-01   最后修改:2011-02-01
sirxenofex 写道
Scala作为函数式语言,根本用不着什么通用AOP把,随手一个Curry函数,就实现了

刚入javaeye就又见到placeholder你的aop了,呵呵
不过这里主要展示的还是trait,curry好像没怎么用到,是否标题有误

同样的,sirxenofex为什么会认为不需要切面aop呢


希望神样的scala在中国的推广越来越好!!!
0 请登录后投票
   发表时间:2011-03-19  
mefan 写道

不过这里主要展示的还是trait,curry好像没怎么用到,是否标题有误


偏应用函数的实现得益于curry化
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics