Commons Collections之函子(functor)综合学习
在公司没事做,无聊自己模拟情景来练习函子(functor)的使用。
自己定的一个场景:(自己假象出来的)
公司里面的工作的人有三种角色,分别是实习生、试用期员工、正式员工。
假定 :
实习生拿的基本工资是800元,试用期员工的基本工资是2000 ,正式员工的基本工资是3000。基本工资暂时是不会变的。实习生经过三个月的工作可以转成试用期员工,试用期员工经过三个月可以转到正式员工。每当一个项目完成后,正式员工可以拿到一部分分红,对于正式员工叫奖金,对于试用期员工叫补贴,实习生是没有的。
现在,有三个人,张三是实习生,李四是试用期员工,王五是正式员工。
要求模拟三个阶段:
1.刚开始,他们都在工作。
2.三个月后,张三变成了试用期员工,李四变成了正式员工。
3.项目结束后,试用期员工拿到补贴1500,正式员工拿到奖金5000
模拟三个阶段,张三、李四、王五拿到的总钱以及清单。
我用函子(functor),就是Apache Commons Collections提供的三个函子:
Predicate(逻辑判断器)、Transformer(对象转换器)、Closure(对象执行器)
实现如下:
首先看看人员角色的定义:
工作者抽象类:
/** * 劳动者,具体分成:实习生、试用期员工、正式员工 * @create 2010-7-30 */ public abstract class Worker { //姓名 private String name; public Worker(String name){ this.name = name; } /** * 打印收入项目 * @return */ public abstract void printItem(); /** * 获取总共收入 * @return */ public abstract int getTotal(); public String getName() { return name; } }
实习生类:
/** * 实习生类 * @create 2010-7-30 */ public class Intern extends Worker{ // 实习生基本工资800 private final int salary = 800; public Intern(String name){ super(name); } // 取得所有收入 @Override public int getTotal() { return salary; } // 打印收入清单 @Override public void printItem() { System.out.println(getName() + "[实习生]当月收入总收入为 [薪水" + salary + "元]=[" + getTotal() + "]元"); } }
试用期员工类:
/** * 试用期员工类 * @create 2010-7-30 */ public class Probationer extends Worker{ //薪水=2000 private final int salary = 2000; //试用期员工有补贴 private int allowance; public Probationer(String name){ super(name); } public void setAllowance(int allowance) { this.allowance = allowance; } @Override public int getTotal() { return salary+allowance; } @Override public void printItem() { System.out.println(getName() + "[试用期员工]当月收入总收入为 [薪水" + salary + "元]+[补贴" + allowance + "]=[" + getTotal() + "]元"); } }
正式员工类:
/** * 正式员工 * @create 2010-7-30 */ public class Employee extends Worker{ //薪水 = 3000 private final int salary = 3000; //正式员工有奖金 private int bonus; public Employee(String name){ super(name); } public void setBonus(int bonus) { this.bonus = bonus; } @Override public int getTotal() { return salary+bonus; } @Override public void printItem() { System.out.println(getName() + "[正式员工]当月收入总收入为 [薪水" + salary + "元]+[奖金" + bonus + "]=[" + getTotal() + "]元"); } }
接下来,看看定义的两个转换器
实习生转试用期员工的转换器:
/** * 实习生转成 试用期员工 的一个 函子(functor) * @create 2010-7-30 */ public class TransProbationer implements Transformer { @Override public Object transform(Object input) { Intern inter = (Intern) input; Probationer probationer = new Probationer(inter.getName()); return probationer; } }
试用期员工转成正式员工的转换器
/** * 试用期员工转成正式员工 的一个 函子(functor) * @create 2010-7-30 */ public class TransEmployee implements Transformer { @Override public Object transform(Object input) { Probationer probationer = (Probationer) input; Employee employee = new Employee(probationer.getName()); return employee; } }
再来看看定义的两个执行器:
给试用期员工发1500补贴的执行器:
/** * 试用期员工发1500补贴 的 一个 函子 * @create 2010-7-30 */ public class AddAllowanceClosure implements Closure { @Override public void execute(Object input) { Probationer probationer = (Probationer) input; probationer.setAllowance(1500); } }
给正式员工发5000奖金的执行器
/** * 正式员工发5000奖金的 一个 函子 * @create 2010-7-30 */ public class AddGonusClosure implements Closure { @Override public void execute(Object input) { Employee employee = (Employee) input; employee.setBonus(5000); } }
开始模拟场景:
public class TestFunctor { public static void main(String[] args) { //定义是否是试用期员工的一个函子 Predicate isProbationerPredicate = new InstanceofPredicate( Probationer.class); //定义是否是正式员工的一个函子 Predicate isEmployeePredicate = new InstanceofPredicate(Employee.class); //定义三个劳动者 张三[实习生]、李四[试用期员工]、王五[正式员工] Worker zhansan = new Intern("张三"); Worker lisi = new Probationer("李四"); Worker wangwu = new Employee("王五"); //查看目前收入 System.out.println("\n来看看 张三、李四、王五目前的月收入:"); zhansan.printItem(); lisi.printItem(); wangwu.printItem(); //经过努力~~张三转成试用期员工了,李四转成正式员工了~ System.out.println("\n\n3个月过去了,张三转成试用期员工了,李四转成正式员工了......"); Transformer transProbationer = new TransProbationer(); Transformer transEmployee = new TransEmployee(); zhansan = (Worker) transProbationer.transform(zhansan); lisi = (Worker) transEmployee.transform(lisi); //查看目前收入 System.out.println("\n来看看 张三、李四、王五目前的月收入:"); zhansan.printItem(); lisi.printItem(); wangwu.printItem(); //公司项目取得良好的成就,因此规定凡是试用期员工发补贴1500元,正式员工发奖金5000元 System.out.println("\n\n目前公司取得很好的成绩,因此凡是试用期员工发补贴1500元,正式员工发奖金5000元"); Map<Predicate , Closure> map = new HashMap<Predicate, Closure>(); Closure allowanceClosure = new AddAllowanceClosure(); Closure gonusClose = new AddGonusClosure(); //如果是试用期员工,则发补贴 map.put(isProbationerPredicate, allowanceClosure); //如果是正式员工,则发奖金 map.put(isEmployeePredicate, gonusClose); //SwitchClosure是实现了Switch的闭包 Closure rewards = SwitchClosure.getInstance(map); rewards.execute(zhansan); rewards.execute(lisi); rewards.execute(wangwu); System.out.println("\n来看看 张三、李四、王五目前的月收入:"); zhansan.printItem(); lisi.printItem(); wangwu.printItem(); } }
运行结果:
来看看 张三、李四、王五目前的月收入: 张三[实习生]当月收入总收入为 [薪水800元]=[800]元 李四[试用期员工]当月收入总收入为 [薪水2000元]+[补贴0]=[2000]元 王五[正式员工]当月收入总收入为 [薪水3000元]+[奖金0]=[3000]元 3个月过去了,张三转成试用期员工了,李四转成正式员工了...... 来看看 张三、李四、王五目前的月收入: 张三[试用期员工]当月收入总收入为 [薪水2000元]+[补贴0]=[2000]元 李四[正式员工]当月收入总收入为 [薪水3000元]+[奖金0]=[3000]元 王五[正式员工]当月收入总收入为 [薪水3000元]+[奖金0]=[3000]元 目前公司取得很好的成绩,因此凡是试用期员工发补贴1500元,正式员工发奖金5000元 来看看 张三、李四、王五目前的月收入: 张三[试用期员工]当月收入总收入为 [薪水2000元]+[补贴1500]=[3500]元 李四[正式员工]当月收入总收入为 [薪水3000元]+[奖金5000]=[8000]元 王五[正式员工]当月收入总收入为 [薪水3000元]+[奖金5000]=[8000]元
可以发现,使用函子可以把逻辑判断、对象转换、对象操作分离的很开,可以任意的自由的组合,通过组合达到所要的目的,代码上可能是多了点,但是对于抗击需求的变化是很好的,可以很好的扩展,可以任意的扩展对象操作,逻辑判断等。继续研究ing~~
Commons Collections之Predicates学习
今天无聊没事做,看到Commons Collections的东西,对Predicates接口和它下面挂着的几个类做了些研究,其实看了源代码之后,就知道很简单了。总结刚才的学习结果:
补充一下一个概念,函子(functor):执行操作或功能的部件,Predicates下面挂着的实现类就是一个函子,执行了各种逻辑运算和判断,你也可以根据自己的需要,实现Predicates类,实现evaluate方法,根据自己定义的算法来实现某一特定判断。
先看,Predicates的几个实现类,清单如下:
EqualPredicate IdentityPredicate NotPredicate InstanceofPredicate NullIsTruePredicate NullIsFalsePredicate NotNullPredicate TruePredicate FalsePredicate UniquePredicate AndPredicate OrPredicate AllPredicate AnyPredicate OnePredicate |
并写了一个Demo程序,将几个Predicates的区别写在了程序的注释中,这是我的习惯。呵呵~~
public void testPredicate(){ //相当于调用equals对比 Predicate equal = new EqualPredicate("cst"); boolean resultEqual = equal.evaluate("cst"); System.out.println("EqualPredicate:"+resultEqual); //相当于调用 == 对比 Predicate identity = new IdentityPredicate(new String("cst")); boolean resultIdentity = identity.evaluate(new String("cst")); System.out.println("IdentityPredicate:"+resultIdentity); //装饰给定的Predicate指定对象想比,并返回相反的值 Predicate not = new NotPredicate(equal); boolean resultNot = not.evaluate("cst"); System.out.println("NotPredicate:"+resultNot); //相当于instanceof 对比 Predicate instanceOf = new InstanceofPredicate(String.class); boolean resultInstanceof = instanceOf.evaluate("cst"); System.out.println("InstanceofPredicate:"+resultInstanceof); // 装饰给定的Predicate //如果对象为null则返回true,否则返回给定Predicate的判定值 Predicate nullIsTrue = new NullIsTruePredicate(equal); boolean resultNullIsTrue = nullIsTrue.evaluate(null); System.out.println("NullIsTruePredicate:"+resultNullIsTrue); // 装饰给定的Predicate // 如果对象为null则返回false,否则返回给定Predicate的判定值 Predicate nullIsFalse = new NullIsFalsePredicate(equal); boolean resultNullIsFalse = nullIsFalse.evaluate(null); System.out.println("NullIsFalsePredicate:"+resultNullIsFalse); //当对象不为null时返回true Predicate notNull = NotNullPredicate.getInstance(); boolean resultNotNull = notNull.evaluate(null); System.out.println("NotNullPredicate:"+resultNotNull); // 总是返回true Predicate truep = TruePredicate.getInstance(); boolean resultTrue = truep.evaluate("cst"); System.out.println("TruePredicate:"+resultTrue); // 总是返回false Predicate falsep = FalsePredicate.getInstance(); boolean resultFalse = falsep.evaluate("cst"); System.out.println("FalsePredicate:"+resultFalse); // 首次evaluate判定对象总是返回true。 // 其内部维护一个HashSet,每次调用evaluate(obj) //将会调用HashSet的add方法。该类常用于Collections过滤重复的对象。 UniquePredicate unique = new UniquePredicate(); boolean resultUnique1 = unique.evaluate("cst"); boolean resultUnique2 = unique.evaluate("cst"); System.out.println("UniquePredicate1:"+resultUnique1); System.out.println("UniquePredicate2:"+resultUnique2); ///////////////////以下是实现复杂的逻辑///////////////////////// //装饰两个Predicate 判断返回两个Predicate和指定对象比较后and的结果 Predicate and = new AndPredicate(equal, identity); boolean resultAnd = and.evaluate("cst"); System.out.println("AndPredicate:"+resultAnd); //装饰两个Predicate 判断返回两个Predicate和指定对象比较后or的结果 Predicate or = new OrPredicate(equal, identity); boolean resultOr = or.evaluate("cst"); System.out.println("OrPredicate:"+resultOr); //多个Predicate指定对象比较后多个and的结果 Predicate [] predicates = new Predicate[]{equal,identity,not}; Predicate all = new AllPredicate(predicates); boolean resultAll = all.evaluate("cst"); System.out.println("AllPredicate:"+resultAll); //多个Predicate指定对象比较后多个or的结果 Predicate any = new AnyPredicate(predicates); boolean resultAny = any.evaluate("cst"); System.out.println("AnyPredicate:"+resultAny); //多个Predicate指定对象比较后,只要有一个结果为true就为true Predicate one = new OnePredicate(predicates); boolean resultOne = one.evaluate("cst"); System.out.println("OnePredicate:"+resultOne); }
运行结果:
EqualPredicate:true IdentityPredicate:false NotPredicate:false InstanceofPredicate:true NullIsTruePredicate:true NullIsFalsePredicate:false NotNullPredicate:false TruePredicate:true FalsePredicate:false UniquePredicate1:true UniquePredicate2:false AndPredicate:false OrPredicate:true AllPredicate:false AnyPredicate:true OnePredicate:tru
继续学习Commons Collections的其他东东~~了解下,方便日后少写人家已经实现过的代码。