<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>gordon@java</title>
    <description></description>
    <link>http://gordon-b-hu.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>在java中小试FP（二）</title>
        <author>gordon@java</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://gordon-b-hu.javaeye.com">gordon@java</a>&nbsp;
          链接：<a href="http://gordon-b-hu.javaeye.com/blog/166254" style="color:red;">http://gordon-b-hu.javaeye.com/blog/166254</a>&nbsp;
          发表时间: 2008年02月29日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          一些说明，仿佛没有说明的代码基本都没有人会看<br /><br /><span style="color: red"><br />以下代码是为了用200行以内的java代码实现一些functional programming的特性,并且可以直接用spring定义任意程序流程.<br /></span><br />User类是一个pojo<br />UserHandler和UserValidator是包含一些业务逻辑的类，包含了一些业务方法，<br />包括一下方法<br />UserValidator.java<br /><pre name="code" class="java">
boolean validate(User u);
</pre><br /><br />UserHandler.java<br /><pre name="code" class="java">
User demoActionOne(User u);
User demoActionTwo(User u);
String getRole(User u);
User makeTaller(User u);
</pre><br /><br />现在可以直接通过对这些已经有的功能组合就能有新的功能，比如<br />这样的代码<br /><pre name="code" class="java">
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);
}
</pre><br /><br />可以这样写<br /><pre name="code" class="java">
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);
</pre><br />这里的newProcess就是一个新的程序流程（或者说片断），<br />也可以使用标准的spring xml定义作为程序流程定制<br /><br />比如<br /><pre name="code" class="xml">
  &lt;bean parent="define" id="validate">
      &lt;constructor-arg ref="userValidator"/>
      &lt;constructor-arg value="validate"/>
  &lt;/bean>
  &lt;bean parent="define" id="actOne">  
    &lt;constructor-arg ref="userHandler"/>  
    &lt;constructor-arg value="demoActionOne"/>  
  &lt;/bean>  
  &lt;bean parent="define" id="actTwo">  
    &lt;constructor-arg ref="userHandler"/>  
    &lt;constructor-arg value="demoActionTwo"/>  
  &lt;/bean>
  &lt;bean id="process1" parent="choice">
    &lt;constructor-arg ref="userRoleEq2driver"/>
    &lt;constructor-arg>&lt;map>
          &lt;entry>&lt;key>&lt;value type="boolean">true&lt;/value>&lt;/key>&lt;ref bean="actOne"/>&lt;/entry>
          &lt;entry>&lt;key>&lt;value type="boolean">false&lt;/value>&lt;/key>&lt;ref bean="actTwo"/>&lt;/entry>
    &lt;/map>&lt;/constructor-arg>
  &lt;/bean>
</pre><br /><br /><br /><br /><br />仔细考虑一下，用fp做个简单的流程拼装器应该会比较简单。<br />把上次的代码稍微修改一下，再配上spring就马上可以订制流程咯。<br /><br />测试代码<br />Test.java<br /><pre name="code" class="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);
    }
}

</pre><br /><br /><br />流程定义文件<br />flow.xml<br /><pre name="code" class="xml">
&lt;?xml version="1.0" encoding="UTF-8"?>
&lt;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">
  &lt;!--common settings-->
  &lt;bean id="sequence" abstract="true" class="com.gordon.functor.Combinator" factory-method="sequence"/>
  &lt;bean id="choice" abstract="true" class="com.gordon.functor.Combinator" factory-method="sw"/>
  &lt;bean id="define" abstract="true" class="com.gordon.functor.Combinator" factory-method="define"/>
  &lt;bean id="eq" class="com.gordon.functor.functors.EqualFunctor"/>
  &lt;bean id="eq2" abstract="true" factory-bean="eq" factory-method="to"/>
  
  &lt;!--old system module/class/function-->
  &lt;bean id="userValidator" class="com.gordon.functor.legacy.UserValidator"/>
  &lt;bean id="userHandler" class="com.gordon.functor.legacy.UserHandler"/>
  
  &lt;!--new function based on functor which shouldn't be created,for demo only-->
  &lt;bean parent="define" id="demoActionOne">
    &lt;constructor-arg ref="userHandler"/>
    &lt;constructor-arg value="demoActionOne"/>
  &lt;/bean>
  &lt;bean parent="define" id="demoActionTwo">
    &lt;constructor-arg ref="userHandler"/>
    &lt;constructor-arg value="demoActionTwo"/>
  &lt;/bean>
  
  &lt;!--define step validation with old UserValidator class-->
  &lt;bean parent="define" id="validate">
      &lt;constructor-arg ref="userValidator"/>
      &lt;constructor-arg value="validate"/>
  &lt;/bean>
  
  &lt;!--define step makeTaller with old UserHandler class-->
  &lt;bean parent="define" id="makeTaller">
      &lt;constructor-arg ref="userHandler"/>
      &lt;constructor-arg value="makeTaller"/>
  &lt;/bean>
  &lt;!--define step getRole with old validator class-->
  &lt;bean parent="define" id="getUserRole">
      &lt;constructor-arg ref="userValidator"/>
      &lt;constructor-arg value="getRole"/>
  &lt;/bean>

  &lt;bean parent="define" id="setusername">
    &lt;constructor-arg value="setName"/>
  &lt;/bean>
  
  &lt;bean id="userRoleEq2driver" parent="sequence">
    &lt;constructor-arg>&lt;list>
      &lt;ref bean="getUserRole"/>
      &lt;bean parent="eq2">
        &lt;constructor-arg>&lt;value type="java.lang.String">driver&lt;/value>&lt;/constructor-arg>
      &lt;/bean>
    &lt;/list>&lt;/constructor-arg>
  &lt;/bean>
  
  &lt;!--define process one-->
  &lt;bean id="process1" parent="choice">
    &lt;constructor-arg ref="userRoleEq2driver"/>
    &lt;constructor-arg>&lt;map>
          &lt;entry>&lt;key>&lt;value type="boolean">true&lt;/value>&lt;/key>&lt;ref bean="demoActionOne"/>&lt;/entry>
          &lt;entry>&lt;key>&lt;value type="boolean">false&lt;/value>&lt;/key>&lt;ref bean="demoActionTwo"/>&lt;/entry>
    &lt;/map>&lt;/constructor-arg>
  &lt;/bean>
  
  &lt;bean id="p2" parent="sequence">
    &lt;constructor-arg>&lt;list>
        &lt;ref bean="process1"/>
        &lt;ref bean="makeTaller"/>
        &lt;ref bean="demoActionOne"/>
    &lt;/list>&lt;/constructor-arg>
  &lt;/bean>
  
&lt;/beans>

</pre><br /><br />核心类<br />Functor.java<br /><pre name="code" class="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&lt;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&lt;Object, Functor> sw = new HashMap&lt;Object, Functor>();
            for (int i = 0; i &lt; 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 &lt; 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;
    }
}

</pre><br /><br />这个类是为了给spring写配置简单写用的<br />Combinator.java<br /><pre name="code" class="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&lt;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&lt;Functor> functors){
        if(functors!=null) return or(functors.toArray(new Functor[functors.size()]));
        else return null;
    }
    
    public static Functor sw(Functor choice,Map&lt;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&lt;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&lt;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);
    }
}

</pre><br /><br />一个基本的用来判断相等的Functor类<br />EqualFunctor.java<br /><pre name="code" class="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&lt;2) return null;
        return args[0].equals(args[1]);
    }
}

</pre><br /><br />测试用的其他类<br />User.java<br /><pre name="code" class="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+"}";
        }
}
</pre><br /><br />UserHandler.java<br /><pre name="code" class="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;
    }
}
</pre><br /><br />UserValidator.java<br /><pre name="code" class="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";
    }
}
</pre>
          <br/><br/>
          <span style="color:red;">
            <a href="http://gordon-b-hu.javaeye.com/blog/166254#comments" style="color:red;">已有 <strong>2</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 29 Feb 2008 20:15:23 +0800</pubDate>
        <link>http://gordon-b-hu.javaeye.com/blog/166254</link>
        <guid>http://gordon-b-hu.javaeye.com/blog/166254</guid>
      </item>
      <item>
        <title>在java中小试FP（一）</title>
        <author>gordon@java</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://gordon-b-hu.javaeye.com">gordon@java</a>&nbsp;
          链接：<a href="http://gordon-b-hu.javaeye.com/blog/166250" style="color:red;">http://gordon-b-hu.javaeye.com/blog/166250</a>&nbsp;
          发表时间: 2008年02月29日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          最近看了点functional programming的东西，觉得可以借鉴的地方还不少，所以做了点尝试<br /><br />就是想把java这样写<br /><br />从<br /><pre name="code" class="java">
User user=new User("gordon",28,170);
if(user.getHeight()>160&&user.getName().equals("gordon"){
  do something...
}else{
  do something else...
}
</pre><br />到<br /><pre name="code" class="java">
User user=new User("gordon",28,170);
Functor process=taller.than(160).and(matchName.to("gordon")).case(true,someAction,false,otherAction);
process.apply(user);
</pre><br />在java中的fp尝试，可以用已有的程序创造新的程序<br /><pre name="code" class="java">
package com.gordon;

import java.util.HashMap;
import java.util.Map;

public class Functor {
     public Object apply(Object... args){
          return null;
     }
     
     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&lt;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&lt;Object,Functor> sw=new HashMap&lt;Object,Functor>();
               for(int i=0;i&lt;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);
                    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);
     }

     public static void main(String args[]) throws Exception{
          Functor t=new Functor(){
               public Object apply(Object... args){
                    return true;
               }
          };
          Functor f=new Functor(){
               public Object apply(Object... args){
                    return false;
               }
          };
          Functor trueAction=new Functor(){
               public Object apply(Object... args){
                    System.out.println(""+true+" "+args.length);
                    return null;
               }
          };
          Functor falseAction=new Functor(){
               public Object apply(Object... args){
                    System.out.println(""+false+" "+args.length);
                    return null;
               }
          };
          Functor eq=new Functor(){
               public Object apply(Object... args){
                    return args[0].equals(args[1]);
               }
          };
          
          Functor matchUserName=new Functor(){
               public Object apply(Object... args){
                    return args[0].equals(((User)args[1]).getName());
               }
          };

          Functor matchUserAge=new Functor(){
               public Object apply(Object... args){
                    return args[0].equals(((User)args[1]).getAge());
               }
          };
          
          Functor taller=new Functor(){
               public Object apply(Object... args){
                    return (Integer)args[0]&lt;((User)args[1]).getHeight();
               }
          };

          User u=new User("gordon",25,173);
          
          Functor eqGordon=eq.to("gordon");
          System.out.println(eqGordon.apply("gordon"));
          
          Map&lt;Object,Functor> sw=new HashMap&lt;Object,Functor>();
          sw.put(true, trueAction);
          sw.put(false, falseAction);
          
          Functor and=t.and(t,t);
          Functor or=f.or(f,f,f);
          or.sw(true,trueAction,false,falseAction).apply();
          
          matchUserName.to("gordon1").or(matchUserAge.to(26)).or(taller.than(160)).sw(true,trueAction,false,falseAction).apply(u);
          
     }
}
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;
     }
     
}
</pre>
          <br/><br/>
          <span style="color:red;">
            <a href="http://gordon-b-hu.javaeye.com/blog/166250#comments" style="color:red;">已有 <strong>1</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 29 Feb 2008 20:03:30 +0800</pubDate>
        <link>http://gordon-b-hu.javaeye.com/blog/166250</link>
        <guid>http://gordon-b-hu.javaeye.com/blog/166250</guid>
      </item>
      <item>
        <title>javascript中的curry</title>
        <author>gordon@java</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://gordon-b-hu.javaeye.com">gordon@java</a>&nbsp;
          链接：<a href="http://gordon-b-hu.javaeye.com/blog/162531" style="color:red;">http://gordon-b-hu.javaeye.com/blog/162531</a>&nbsp;
          发表时间: 2008年02月15日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          curry 用来组合function还是8错的<br /><pre name="code" class="js">
	//curry function
	Function.prototype.curry=function(){
		var originFunc=this;
		var args=[];
		for(var i=0;i&lt;arguments.length;i++){
			args[i]=arguments[i];
		}
		if(args.length==0) args=null;
		var newFunc=function(){
			var args=[];
			for(var i=0;i&lt;arguments.length;i++){
				args[i]=arguments[i];
			}
			args=arguments.callee.curryArgs.concat(args);
			if(args.length==0)args=null;
			return arguments.callee.originFunc.apply(this,args);
		}
		newFunc.curryArgs=args;
		newFunc.originFunc=originFunc;
		return newFunc;
	}
	//each function for array . test curry
	Array.prototype.each=function(f){
		for(var i=0;i&lt;this.length;i++){
			f(this[i]);
		}
	}
	//map function for array,generate new array, test curry
	Array.prototype.map=function(f){
		var result=[];
		for(var i=0;i&lt;this.length;i++){
			result[i]=f(this[i]);
		}
		return result;
	}
	//test run
	function run(){
		
		var composit=function(f,g,x){
			return f(g(x));
		}
		
		var mul=function(x,y){
			return x*y;
		}
		//var triple=mul.curry(3);
		//alert(triple(4));
		var double=mul.curry(2);
		//var sixTimes=composit.curry(double).curry(triple);
		//var al6=composit.curry(alert).curry(sixTimes);
		//al6(10);
		
		var app=function(f,list){
			list.each(f);
		}
		var map=function(f,list){
			return list.map(f);
		}
		var l=[8,7,6];
		l.alertEach=l.each.curry(alert);
		l.alertEach();
		app.curry(alert)(l);
		composit.curry(alert,map.curry(double))(l);
	}
	run();
</pre>
          <br/><br/>
          <span style="color:red;">
            <a href="http://gordon-b-hu.javaeye.com/blog/162531#comments" style="color:red;">已有 <strong>6</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 15 Feb 2008 17:21:30 +0800</pubDate>
        <link>http://gordon-b-hu.javaeye.com/blog/162531</link>
        <guid>http://gordon-b-hu.javaeye.com/blog/162531</guid>
      </item>
      <item>
        <title>一个用cglib和WeakHashMap做的lazyload原形实现</title>
        <author>gordon@java</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://gordon-b-hu.javaeye.com">gordon@java</a>&nbsp;
          链接：<a href="http://gordon-b-hu.javaeye.com/blog/127270" style="color:red;">http://gordon-b-hu.javaeye.com/blog/127270</a>&nbsp;
          发表时间: 2007年09月26日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          写于3月份，耗时2小时，时间仓促肯定很多不周全，所以说是个初步原形<br />上代码<br /><br /><br />LazyLoadMethodInterceptor.java<br />其中session是一个persistence layer的session mockup，这个intercepter是用来对pojo的get方法做监听<br /><pre name="code" class="java">

package com.gordon.lazyload.aop;

import java.lang.reflect.Method;
import java.util.Map;
import com.gordon.lazyload.persistence.Session;
import com.gordon.lazyload.utils.ClassHelper;
import com.gordon.lazyload.utils.LazyLoadHelper;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

/**
 * @author hugo
 * @date 2007-3-7 0:34:23 LazyLoadMethodInterceptor
 */
public class LazyLoadMethodInterceptor implements MethodInterceptor {

	/**
	 * 
	 */
	public LazyLoadMethodInterceptor() {
		super();
		// TODO Auto-generated constructor stub
	}

	private Object target;

	public void setTarget(Object target) {
		this.target = target;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see net.sf.cglib.proxy.MethodInterceptor#intercept(java.lang.Object, java.lang.reflect.Method, java.lang.Object[],
	 *      net.sf.cglib.proxy.MethodProxy)
	 */
	public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
		// TODO Auto-generated method stub
		ClassHelper h = ClassHelper.getInstance();
		Map&lt;Object, Map&lt;String, String>> lazyMap = LazyLoadHelper.getInstance().getLazyMap();
		if (method.getName().substring(0, 3).equals("get") && !h.isPrimative(method.getReturnType())
				&& lazyMap.containsKey(target)) {
			// System.out.println(target.getClass().getName()+"."+method.getName()+" has been called");
			String fieldName = method.getName().substring(3).toLowerCase();
			Map&lt;String, String> propertyMap = lazyMap.get(target);
			if (propertyMap.containsKey(fieldName)) {
				String id = propertyMap.get(fieldName);
				System.out.println(target + " lazy loading [property:" + fieldName + ",id:" + id + "]");
				Session s = new Session();
				Object propertyValue = s.loadObjectById(method.getReturnType(), id);
				Method m = target.getClass().getMethod("set" + method.getName().substring(3), method.getReturnType());
				m.invoke(target, propertyValue);
				lazyMap.get(target).remove(fieldName);
				if (lazyMap.get(target).isEmpty()) lazyMap.remove(target);
				return propertyValue;
			}
		}
		return method.invoke(target, args);
	}
}


</pre><br /><br /><br />LazyLoadHelper.java<br />一个weakhashmap的singleton包装<br /><pre name="code" class="java">
package com.gordon.lazyload.utils;

import java.util.Collections;
import java.util.Map;
import java.util.WeakHashMap;


/**
 * @author hugo
 * @date 2007-3-7 2:30:22
 * LazyLoadHelper
 */
public class LazyLoadHelper {

	/**
	 * 
	 */
	private LazyLoadHelper() {
		super();
		lazyMap=Collections.synchronizedMap(new WeakHashMap&lt;Object,Map&lt;String,String>>());
		// TODO Auto-generated constructor stub
	}
	public static LazyLoadHelper getInstance() {
		if(llh==null)llh=new LazyLoadHelper();
		return llh;
	}
	private Map&lt;Object,Map&lt;String,String>> lazyMap;
	private static LazyLoadHelper llh=null;

	public Map&lt;Object, Map&lt;String,String>> getLazyMap() {
		return lazyMap;
	}

}
</pre><br /><br />Session.java<br />从数据库里面load对象的时候，如果该对象的某个属性是个bean就不load这个属性，直接把属性对应的id和属性的名字保存在weakhashmap里面，当该对象的get属性方法被调用时候才weakhashmap里面读取id，实行lazyload<br /><pre name="code" class="java">
package com.gordon.lazyload.persistence;

import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import com.gordon.lazyload.aop.LazyLoadMethodInterceptor;
import com.gordon.lazyload.utils.ClassHelper;
import com.gordon.lazyload.utils.LazyLoadHelper;
import net.sf.cglib.proxy.Enhancer;

/**
 * @author hugo
 * @date 2007-3-7 0:18:38
 * Session
 */
public class Session {

	/**
	 * 
	 */
	public Session() {
		super();
		// TODO Auto-generated constructor stub
	}
	public&lt;E> E loadObjectById(Class&lt;E> cls,String id) throws Throwable {
		E obj=cls.newInstance();
		ClassHelper h=ClassHelper.getInstance();
		
		//using java.beans.PropertyDescriptor
		/*
		PropertyDescriptor[] properties=Introspector.getBeanInfo(cls).getPropertyDescriptors();
		for(PropertyDescriptor p:properties) {
			if(p.getPropertyType().equals(Class.class)) continue;
			if(h.isPrimative(p.getPropertyType())) {
				p.getWriteMethod().invoke(obj, h.getMockValue(p.getPropertyType()));
			}else {
				Map&lt;String,String> propertyMap=LazyLoadHelper.getInstance().getLazyMap().get(obj);
				if(propertyMap==null) {
					propertyMap=new HashMap&lt;String,String>();
					LazyLoadHelper.getInstance().getLazyMap().put(obj, propertyMap);
				}
				propertyMap.put(p.getName(), new String((String)h.getMockValue(String.class)));
			}
		}
		*/
		//using java.lang.reflect.Field
		for(Field f:cls.getDeclaredFields()) {
			if(h.isPrimative(f.getType())) {
				Method m=cls.getMethod(this.setter(f.getName()), f.getType());
				m.invoke(obj, h.getMockValue(f.getType(),f.getName()));
			}else {
				Map&lt;String,String> propertyMap=LazyLoadHelper.getInstance().getLazyMap().get(obj);
				if(propertyMap==null) {
					propertyMap=new HashMap&lt;String,String>();
					LazyLoadHelper.getInstance().getLazyMap().put(obj, propertyMap);
				}
				//这里把一个是pojo的property的名字和id放到weakhashmap里面
				propertyMap.put(f.getName(), new String((String)h.getMockValue(String.class,f.getName())));
			}
		}
		
		obj=(E)getWrappedInstance(obj);
		return obj;
	}
	private Object getWrappedInstance(Object obj) {
		Object result=null;
		Enhancer enhancer=new Enhancer();
		enhancer.setSuperclass(obj.getClass());
		LazyLoadMethodInterceptor mi=new LazyLoadMethodInterceptor();
		mi.setTarget(obj);
		enhancer.setCallback(mi);
		result=enhancer.create();
		return result;
	}
	private String capitalize(String str) {
		return str.substring(0,1).toUpperCase()+str.substring(1);
	}
	/*
	private String getter(String str) {
		return "get"+this.capitalize(str);
	}
	*/
	private String setter(String str) {
		return "set"+this.capitalize(str);
	}
}
</pre><br /><br /><br />Client.java<br />一个测试用的client<br /><pre name="code" class="java">
package com.gordon.lazy.test;

import com.gordon.lazyload.domain.Nonsense2;
import com.gordon.lazyload.domain.User;
import com.gordon.lazyload.persistence.Session;
import com.gordon.lazyload.utils.LazyLoadHelper;


/**
 * @author hugo
 * @date 2007-3-7 1:11:53
 * Client
 */
public class Client {

	/**
	 * 
	 */
	public Client() {
		super();
		// TODO Auto-generated constructor stub
	}
	public void runMe() {
		Session s=new Session();
		try {
			User u=s.loadObjectById(User.class, "1");
			u.getAccount();
			u.getAccount();
			u.getEmail().getContent();
			u.getEmail().getContent();
			User u2=s.loadObjectById(User.class, "2");
			u2.getAge();
			u2.getAlive();
			u2.getWealth();
			u2.getAccount();
			u2.getAccount();
			u2.getEmail().getContent();
			u2.getEmail().getContent();
			Nonsense2 n=s.loadObjectById(Nonsense2.class, "2");
			System.out.println(n.getName());
			System.out.println(n.getN().getText());
			System.out.println(LazyLoadHelper.getInstance().getLazyMap().keySet().size());
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Client c=new Client();
		c.runMe();
		System.gc();
		System.out.println(LazyLoadHelper.getInstance().getLazyMap().keySet().size());
	}
}
</pre><br /><br /><br />其实就是用cglib监听每个pojo的get方法，所有的pojo都在从数据库中load时候做了cglib包装，当pojo属性需要被lazyload时候就把相关信息放到一个weakhashmap里面，很简单滴
          <br/><br/>
          <span style="color:red;">
            <a href="http://gordon-b-hu.javaeye.com/blog/127270#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 26 Sep 2007 13:34:31 +0800</pubDate>
        <link>http://gordon-b-hu.javaeye.com/blog/127270</link>
        <guid>http://gordon-b-hu.javaeye.com/blog/127270</guid>
      </item>
  </channel>
</rss>