`
mwei
  • 浏览: 121725 次
  • 性别: Icon_minigender_1
  • 来自: 抽象空间
社区版块
存档分类
最新评论

Scala:使用Curry实现AOP

阅读更多
业余时间学了学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的学习队伍中来吧。
分享到:
评论
4 楼 mwei 2011-03-19  
mefan 写道

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


偏应用函数的实现得益于curry化
3 楼 mefan 2011-02-01  
sirxenofex 写道
Scala作为函数式语言,根本用不着什么通用AOP把,随手一个Curry函数,就实现了

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

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


希望神样的scala在中国的推广越来越好!!!
2 楼 sirxenofex 2011-02-01  
Scala作为函数式语言,根本用不着什么通用AOP把,随手一个Curry函数,就实现了
1 楼 liusong1111 2011-01-30  
使用trait实现AOP的一般思路是利用它的stackable modification特性。我平时接触的AOP多在一个实现上进行若干次切面,楼主这个正好相反,倾向于基于多个实现的顺序调用,对应固定的两个切面(一个before一个after),这样就更象使用了偏函数的observer模式,没有更详细的场景不好更深入讨论下去。
如果按常规AOP套路考虑,我觉得重点是切面(before/after)的灵活性,比如,可以绑多个before/after方法,其签名与主实现一致,同时考虑before里可以控制是否把控制转向下一个,after里可以拿到主实现的返回值等等。这个在scala里由于有更强大的类型系统和偏函数等概念,会更有意思,我也没想清楚,请大家继续讨论。

相关推荐

Global site tag (gtag.js) - Google Analytics