- 浏览: 8042 次
最近访客 更多访客>>
文章分类
最新评论
-
gordonAtJava:
补充以下,http://www.iteye.com/topic ...
在java中小试FP(一) -
gordonAtJava:
在java中实现functional programming的 ...
在java中小试FP(二) -
ray_linn:
能不能先告诉我这一大段到底是要干什么?
在java中小试FP(二) -
gordonAtJava:
gordon@java 写道笨笨狗 写道Prototype1. ...
javascript中的curry -
gordonAtJava:
笨笨狗 写道Prototype1.6就有这个扩展……
嘿嘿, ...
javascript中的curry
一些说明,仿佛没有说明的代码基本都没有人会看
以下代码是为了用200行以内的java代码实现一些functional programming的特性,并且可以直接用spring定义任意程序流程.
User类是一个pojo
UserHandler和UserValidator是包含一些业务逻辑的类,包含了一些业务方法,
包括一下方法
UserValidator.java
UserHandler.java
现在可以直接通过对这些已经有的功能组合就能有新的功能,比如
这样的代码
可以这样写
这里的newProcess就是一个新的程序流程(或者说片断),
也可以使用标准的spring xml定义作为程序流程定制
比如
仔细考虑一下,用fp做个简单的流程拼装器应该会比较简单。
把上次的代码稍微修改一下,再配上spring就马上可以订制流程咯。
测试代码
Test.java
流程定义文件
flow.xml
核心类
Functor.java
这个类是为了给spring写配置简单写用的
Combinator.java
一个基本的用来判断相等的Functor类
EqualFunctor.java
测试用的其他类
User.java
UserHandler.java
UserValidator.java
以下代码是为了用200行以内的java代码实现一些functional programming的特性,并且可以直接用spring定义任意程序流程.
User类是一个pojo
UserHandler和UserValidator是包含一些业务逻辑的类,包含了一些业务方法,
包括一下方法
UserValidator.java
boolean validate(User u);
UserHandler.java
User demoActionOne(User u); User demoActionTwo(User u); String getRole(User u); User makeTaller(User u);
现在可以直接通过对这些已经有的功能组合就能有新的功能,比如
这样的代码
User u = new User("gordon", 25, 173); UserValidator v=new UserValidator(); UserHandler h=new UserHandler(); if(v.validate(u)){ h.demoActionOne(u); }else{ h.demoActionTwo(u); }
可以这样写
Functor validate=Functor.define(new UserValidator(),"validate"); Functor actOne=Functor.define(new UserHandler(),"demoActionOne"); Functor actTwo=Functor.define(new UserHandler(),"demoActionTwo"); Functor newProcess=validate.sw(true,actOne,false,actTwo); User u = new User("gordon", 25, 173); newProcess.apply(u);
这里的newProcess就是一个新的程序流程(或者说片断),
也可以使用标准的spring xml定义作为程序流程定制
比如
<bean parent="define" id="validate"> <constructor-arg ref="userValidator"/> <constructor-arg value="validate"/> </bean> <bean parent="define" id="actOne"> <constructor-arg ref="userHandler"/> <constructor-arg value="demoActionOne"/> </bean> <bean parent="define" id="actTwo"> <constructor-arg ref="userHandler"/> <constructor-arg value="demoActionTwo"/> </bean> <bean id="process1" parent="choice"> <constructor-arg ref="userRoleEq2driver"/> <constructor-arg><map> <entry><key><value type="boolean">true</value></key><ref bean="actOne"/></entry> <entry><key><value type="boolean">false</value></key><ref bean="actTwo"/></entry> </map></constructor-arg> </bean>
仔细考虑一下,用fp做个简单的流程拼装器应该会比较简单。
把上次的代码稍微修改一下,再配上spring就马上可以订制流程咯。
测试代码
Test.java
package com.gordon.functor.test; import com.gordon.functor.Functor; import com.gordon.functor.functors.EqualFunctor; import com.gordon.functor.legacy.User; import com.gordon.functor.legacy.UserHandler; import com.gordon.functor.legacy.UserValidator; import java.util.HashMap; import java.util.Map; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) throws Exception { User u1 = new User("gordon", 25, 173); User u2 = new User("jiacheng",25,173); ApplicationContext context = new ClassPathXmlApplicationContext( new String[] {"flow.xml"}); Functor process3=(Functor)context.getBean("process1"); process3.apply(u1); process3.apply(u2); System.out.println(); Functor p2=(Functor)context.getBean("p2"); p2.apply(u2); Functor p3=(Functor)context.getBean("setusername"); p3.apply("testname",u2); System.out.println(u2); Functor setUserNameToLarry=p3.curry("larry"); setUserNameToLarry.apply(u2); System.out.println(u2); } }
流程定义文件
flow.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <!--common settings--> <bean id="sequence" abstract="true" class="com.gordon.functor.Combinator" factory-method="sequence"/> <bean id="choice" abstract="true" class="com.gordon.functor.Combinator" factory-method="sw"/> <bean id="define" abstract="true" class="com.gordon.functor.Combinator" factory-method="define"/> <bean id="eq" class="com.gordon.functor.functors.EqualFunctor"/> <bean id="eq2" abstract="true" factory-bean="eq" factory-method="to"/> <!--old system module/class/function--> <bean id="userValidator" class="com.gordon.functor.legacy.UserValidator"/> <bean id="userHandler" class="com.gordon.functor.legacy.UserHandler"/> <!--new function based on functor which shouldn't be created,for demo only--> <bean parent="define" id="demoActionOne"> <constructor-arg ref="userHandler"/> <constructor-arg value="demoActionOne"/> </bean> <bean parent="define" id="demoActionTwo"> <constructor-arg ref="userHandler"/> <constructor-arg value="demoActionTwo"/> </bean> <!--define step validation with old UserValidator class--> <bean parent="define" id="validate"> <constructor-arg ref="userValidator"/> <constructor-arg value="validate"/> </bean> <!--define step makeTaller with old UserHandler class--> <bean parent="define" id="makeTaller"> <constructor-arg ref="userHandler"/> <constructor-arg value="makeTaller"/> </bean> <!--define step getRole with old validator class--> <bean parent="define" id="getUserRole"> <constructor-arg ref="userValidator"/> <constructor-arg value="getRole"/> </bean> <bean parent="define" id="setusername"> <constructor-arg value="setName"/> </bean> <bean id="userRoleEq2driver" parent="sequence"> <constructor-arg><list> <ref bean="getUserRole"/> <bean parent="eq2"> <constructor-arg><value type="java.lang.String">driver</value></constructor-arg> </bean> </list></constructor-arg> </bean> <!--define process one--> <bean id="process1" parent="choice"> <constructor-arg ref="userRoleEq2driver"/> <constructor-arg><map> <entry><key><value type="boolean">true</value></key><ref bean="demoActionOne"/></entry> <entry><key><value type="boolean">false</value></key><ref bean="demoActionTwo"/></entry> </map></constructor-arg> </bean> <bean id="p2" parent="sequence"> <constructor-arg><list> <ref bean="process1"/> <ref bean="makeTaller"/> <ref bean="demoActionOne"/> </list></constructor-arg> </bean> </beans>
核心类
Functor.java
package com.gordon.functor; import java.util.HashMap; import java.util.Map; public abstract class Functor { public abstract Object apply(Object... args); public static Functor define(final String action){ return new Functor() { public Object apply(Object... args){ if(args==null)return null; if(args.length>1){ Object[] tail=new Object[args.length-1]; System.arraycopy(args,0,tail,0,tail.length); return run(args[args.length-1],action,tail); }else{ return run(args[0],action); } } }; } public static Functor define(final Object worker, final String action) { return new Functor() { public Object apply(Object... args) { return run(worker, action, args); } }; } public Functor and(final Functor... functors) { final Functor first = this; return new Functor() { public Object apply(Object... args) { Boolean result = (Boolean)first.apply(args); for (Functor f: functors) { result = result && (Boolean)f.apply(args); } return result; } }; } public Functor or(final Functor... functors) { final Functor first = this; return new Functor() { public Object apply(Object... args) { Boolean result = (Boolean)first.apply(args); for (Functor f: functors) { result = result || (Boolean)f.apply(args); } return result; } }; } public Functor sw(final Map<Object, Functor> switchMap) { final Functor f = this; return new Functor() { public Object apply(Object... args) { Object firstResult = f.apply(args); if (!switchMap.containsKey(firstResult)) return args; return switchMap.get(firstResult).apply(args); } }; } public Functor sw(Object... args) { if (args.length > 1 && args.length % 2 == 0) { Map<Object, Functor> sw = new HashMap<Object, Functor>(); for (int i = 0; i < args.length; i = i + 2) { sw.put(args[i], (Functor)args[i + 1]); } return this.sw(sw); } else throw new java.lang.IllegalArgumentException("incorrect number of arguments for Functor.sw , correct format should be (case,Functor,case,Functor...)"); } public Functor curry(final Object... pargs) { final Functor self = this; return new Functor() { public Object apply(Object... args) { Object[] arg = new Object[pargs.length + args.length]; System.arraycopy(pargs, 0, arg, 0, pargs.length); System.arraycopy(args, 0, arg, pargs.length, args.length); return self.apply(arg); } }; } public Functor then(final Functor... functors) { final Functor first = this; return new Functor() { public Object apply(Object... args) { Object result = first.apply(args); if (functors != null) for (Functor f: functors) { result = f.apply(result); } return result; } }; } public Functor to(final Object... args) { return this.curry(args); } public Functor than(final Object... args) { return this.curry(args); } protected static Object run(Object worker, String action, Object... arguments) { java.lang.reflect.Method mx = null; for (java.lang.reflect.Method m: worker.getClass().getMethods()) { if (m.getName().equals(action)) { mx = m; break; } } Object result = null; try { if (!mx.isVarArgs()) { result = mx.invoke(worker, arguments); } else { if (arguments.length == mx.getParameterTypes().length) { result = mx.invoke(worker, arguments); } else { Object[] args = new Object[mx.getParameterTypes().length]; for (int i = 0; i < args.length; i++) { if (i != args.length - 1) args[i] = arguments[i]; else { Object[] var = (Object[])java.lang.reflect.Array.newInstance(mx.getParameterTypes()[i].getComponentType(), arguments.length - i); System.arraycopy(arguments, i, var, 0, var.length); args[i] = var; } } result = mx.invoke(worker, args); } } } catch (Exception e) { e.printStackTrace(); } return result; } }
这个类是为了给spring写配置简单写用的
Combinator.java
package com.gordon.functor; import java.util.List; import java.util.Map; public abstract class Combinator { public static Functor and(Functor... functors){ if(functors!=null) return head(functors).and(tail(functors)); else return null; } public static Functor and(List<Functor> functors){ if(functors!=null) return and(functors.toArray(new Functor[functors.size()])); else return null; } public static Functor or(Functor... functors){ if(functors!=null) return head(functors).or(tail(functors)); else return null; } public static Functor or(List<Functor> functors){ if(functors!=null) return or(functors.toArray(new Functor[functors.size()])); else return null; } public static Functor sw(Functor choice,Map<Object,Functor> switchMap){ return choice.sw(switchMap); } public static Functor sw(Functor choice,Object... args){ return choice.sw(args); } public static Functor curry(Functor self,Object... args){ return self.curry(args); } public static Functor sequence(List<Functor> functors){ return sequence(functors.toArray(new Functor[functors.size()])); } public static Functor sequence(Functor[] functors){ if(functors!=null) return head(functors).then(tail(functors)); else return null; } private static Functor head(Functor[] array){ if(array!=null&&array.length>0)return array[0]; else return null; } private static Functor[] tail(Functor[] array){ if(array.length<2) return null; Functor[] tail=new Functor[array.length-1]; System.arraycopy(array,1,tail,0,array.length-1); return tail; } public static Functor define(Object worker,String action){ return Functor.define(worker,action); } public static Functor define(String action){ return Functor.define(action); } }
一个基本的用来判断相等的Functor类
EqualFunctor.java
package com.gordon.functor.functors; import com.gordon.functor.Functor; public class EqualFunctor extends Functor { public EqualFunctor() { } public Object apply(Object... args) { if(args.length<2) return null; return args[0].equals(args[1]); } }
测试用的其他类
User.java
package com.gordon.functor.legacy; public class User{ private String name; private int age; private int height; public User(String name,int age,int height){ this.name=name; this.age=age; this.height=height; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } public String toString(){ return "{name:"+this.name+",age:"+this.age+",height:"+this.height+"}"; } }
UserHandler.java
package com.gordon.functor.legacy; public class UserHandler { public UserHandler() { } public User makeTaller(User u){ if(u!=null)u.setHeight(u.getHeight()+10); return u; } public User demoActionOne(User u){ System.out.println("this is demo action one"); if(u!=null){ System.out.println("user="+u); } return u; } public User demoActionTwo(User u){ System.out.println("this is demo action two"); if(u!=null){ System.out.println("user="+u); } return u; } }
UserValidator.java
package com.gordon.functor.legacy; public class UserValidator{ public boolean validate(User u){ return (u.getName().equals("gordon")); } public String getRole(User u){ if(u.getName().equals("gordon"))return "developer"; if(u.getName().equals("jiacheng"))return "driver"; if(u.getName().equals("dylan"))return "dba"; return "staff"; } }
评论
2 楼
gordonAtJava
2008-03-01
在java中实现functional programming的一些特性,并且可以和spring直接结合做流程引擎,具体请看刚补上的说明
ray_linn 写道
能不能先告诉我这一大段到底是要干什么?
1 楼
ray_linn
2008-02-29
能不能先告诉我这一大段到底是要干什么?
相关推荐
MongoDB在Java中被广泛用于构建高性能、可扩展的数据存储解决方案。MongoDB是一个NoSQL数据库,以其灵活性、可伸缩性和高性能而闻名。在Java中使用MongoDB,我们可以借助Spring Data MongoDB框架,它提供了一种简化...
在Java中,使用Hessian主要涉及以下几个步骤: **1. 引入依赖** 在项目中引入Hessian的库,通常是Caucho公司的Hessian库,可以通过Maven或Gradle添加依赖。 **2. 定义服务接口** 创建一个Java接口,声明需要暴露的...
在这个项目中,我们将学习如何使用Java的Swing库来创建一个基本的图形用户界面,让用户能够进行简单的绘图操作。 【描述】这篇博客文章通过一个具体的实例,向读者展示了如何在Java环境中构建一个简单的画图应用。...
在Java中实现音乐播放功能,主要涉及到以下几个核心知识点: 1. **音频文件处理**:Java提供了一系列的类库来处理音频文件,如`javax.sound.sampled`包中的`AudioSystem`和`AudioInputStream`等。这些类允许开发者...
NULL 博文链接:https://zhuchengzzcc.iteye.com/blog/1534671
java 计算均值 小试身手
当用户在`RightPanel`中选择不同的图片时,`MainPanel`中的图片会相应更新。 - **右侧边栏** (`RightPanel`): 显示同一文件夹下的所有图片缩略图,用户可以通过点击这些缩略图来切换`MainPanel`中的图片。 - 当图片...
1. 营销漏斗理论:在描述中提到的“营销漏斗”,是指潜在客户从认知品牌到最终购买的过程,通常分为曝光与发现、考虑与购买意图、采取行动和复购等阶段。对于刚建立的户外用品电商网站,目标是增加品牌知名度,所以...
- 分析Java中的关键字和保留字,了解它们的作用和用法。 **小试牛刀:** - 实践基本的数据类型操作,如整型、浮点型、字符型等。 - 编写简单的控制结构程序,如if-else语句、switch-case语句。 **挑战自我:** - ...
用JAVA实现的排序额 学JAVA 小试身手
在JExcelOperate.java中,通常会包括以下步骤: 1. **导入JExcel库**:首先,我们需要导入JExcel所需的库,这通常是通过在代码顶部添加import语句完成的。 ```java import net.sourceforge.jexcelapi.*; ``` 2. **...
3. 控制器层:在Java中,控制器可能是Servlet或使用Spring MVC框架的Controller类。它们处理用户的HTTP请求,比如玩家的移动指令、释放炸弹的操作等,调用服务层方法进行处理,然后将响应数据(如更新的游戏状态)...
本文档《通达信指标公式源码 小试牛刀精髓.doc》主要介绍了如何利用公式进行技术分析,帮助用户在股市中寻找潜在的投资机会。以下是其中涉及的一些关键知识点: 1. **移动平均线(MA)**: - 移动平均线是股票分析...
在Java编程中,小应用程序(Applet)是一种可以在Web浏览器中运行的轻量级程序。在本章"Java小应用"中,我们将深入探讨Applet的基本概念、生命周期及其在实践中的应用。 2.1 所有小应用程序的根源 Java的小应用程序...
在Java中,JNI提供了接口让Java代码能够调用本地(native)代码,通常是C或C++编写的库。这个过程涉及到以下几个主要步骤: 1. **定义本地方法**:在Java类中声明本地方法,方法的实现使用`native`关键字标注。例如...
在Java中实现WebSocket,我们通常会用到JSR 356规范,这是Java EE 7引入的标准,提供了方便的API来创建WebSocket服务。 在本Java WebSocket实例中,我们将探讨以下几个关键知识点: 1. **WebSocket协议**:...
在压缩包文件中,"jar"可能包含了一个包含JDBC驱动和其他相关库的Java档案,这些库使得Java程序能够与数据库进行通信。".idea"目录通常是IntelliJ IDEA这样的开发环境的项目配置文件,包含了一些元数据和设置。"JDBC...
在《牛刀小试VC》中,读者将逐步了解如何利用VC++来创建、编译和调试C++程序。 首先,教程可能会介绍如何安装和配置VC++环境,包括设置开发环境、创建新项目以及管理工程文件。这部分内容对于初学者来说至关重要,...
在"第5季-小试牛刀-项目开发"的压缩包中,可能包含了关于以上各个知识点的实践教程、代码示例或者项目案例。通过学习这些内容,开发者可以深入理解Linux驱动开发的过程,掌握从识别硬件接口到编写驱动代码,再到测试...