Java设计模式之四

来源:互联网 发布:雅虎股票数据 编辑:程序博客网 时间:2024/05/24 07:12

1,迭代模式(Interator)

迭代模式是在不暴露其内部的同时统一了遍历的方式,除了在集合中用到,其他地方用到的不多,对于理解JDK的Iterator到有帮助,模拟JDK的Iterator的例子
接口Collection

package com.remote3c.iterator;public interface Collection {public Iterator iterator();}

接口Iterator

package com.remote3c.iterator;public interface Iterator {boolean hasNext();Object  next();void remove();}
关键的ArrayList

package com.remote3c.iterator;public class ArrayList implements Collection {Object[] objects = new Object[10];int index =0;public void add(Object o){if(index==objects.length){Object[] newObjects = new Object[objects.length*2];System.arraycopy(objects, 0, newObjects, 0, objects.length);objects=newObjects;}objects[index]=o;index++;}public int size(){return index;}@Overridepublic Iterator iterator() {return new creatArrayListIteratro();}/** * 内部类 * @author zhangyoushuai *  2016-9-14 */private class creatArrayListIteratro implements Iterator {private int currentIndex=0;@Overridepublic boolean hasNext() {if(currentIndex>=index){return false;}else{return true;}}@Overridepublic Object next() {Object o= objects[currentIndex];currentIndex ++;return o;}@Overridepublic void remove() {// TODO Auto-generated method stubobjects[currentIndex-1]=null;}}}
测试类
package com.remote3c.iterator;public class Test {/** * @author zhangyoushuai * @date 2016-9-14   * @version 1.0.0  * @param args */public static void main(String[] args) {ArrayList list = new ArrayList();list.add("asdf1");list.add("asdf2");list.add("asdf3");Iterator itr=list.iterator();while(itr.hasNext()){System.out.println(itr.next());}}}

结果
asdf1asdf2asdf3

2,代理模式(Proxy)


2.1静态代理

代理主要是在被代理对象方法执行前后,再添加执行方法,关键是实现统一接口,代理类持有被代理类的对象。

例子如下:

接口

package com.remote3c.inter;public interface Moveable {public void move();}

被代理类

package com.remote3c.main;import com.remote3c.inter.Moveable;public class Tank implements Moveable {@Overridepublic void move() {System.out.println("Tank moving.....");}}
两个代理类
package com.remote3c.main;import com.remote3c.inter.Moveable;public class TankLogProxy implements Moveable { public TankLogProxy(Moveable l) {this.l = l;}public Moveable l;@Overridepublic void move() {System.out.println("Tank moving start");l.move();System.out.println("Tank moving end");}}
package com.remote3c.main;import java.util.Random;import com.remote3c.inter.Moveable;public class TankTimeProxy implements Moveable {/** * @param m */public TankTimeProxy(Moveable m) {this.t = m;}public Moveable t;@Overridepublic void move() {long start = System.currentTimeMillis();System.out.println("time start");t.move(); try {Thread.sleep(new Random().nextInt(10000));} catch (InterruptedException e) {e.printStackTrace();}long end = System.currentTimeMillis();System.out.println("time end");System.out.println("time"+(end -start));}}

测试类
package com.remote3c.main;public class Test {/** * @author zhangyoushuai * @date 2016-9-14   * @version 1.0.0  * @param args */public static void main(String[] args) {Tank t = new Tank();//t.move();TankLogProxy tlp=new TankLogProxy(t);TankTimeProxy ttp= new TankTimeProxy(tlp);ttp.move();}}

结果
time startTank moving startTank moving.....Tank moving endtime endtime3278


2.1动态代理

        如果像上面那样会存在一个问题:如果我们像Tank这样的类很多,那么,我们是不是要去写很多个TankLogProxy,TankTimeProxy这样的类呢。其实也是一种很麻烦的事。在jdk1.3以后,jdk跟我们提供了一个API java.lang.reflect.InvocationHandler的类, 这个类可以让我们在JVM调用某个类的方法时动态的为些方法做些什么事。下面我们就来实现动态代理的实现。动态代理实现主要是实现InvocationHandler,并且将目标对象注入到代理对象中,利用反射机制来执行目标对象的方法。

首先创建一个用户登录的接口

public interface UserLogin {  public void login(String userName);}

接着创建实现这个接口的实现类

package com.remote3c.main;public class UserLoginImpl implements UserLogin {public void login(String userName) {System.out.println("欢迎"+userName+"登录系统");}}
最关键的是创建一个自己的处理类 实现InvocationHandler 接口

package com.remote3c.main;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class MyHandler implements InvocationHandler {    private Object obj;    public MyHandler(Object obj) {        this.obj = obj;    }public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {beforeLogin(); // 登录前处理,更具自己需要来写Object res= method.invoke(obj, args);afterLogin(); // 登录后处理,更具自己需要来写return res;}public void beforeLogin() {        System.out.println("登录前处理");    }    public void afterLogin() {        System.out.println("登录后处理");    }}

最后是测试程序

package com.remote3c.main;import java.lang.reflect.Proxy;public class ProxyText {/** * @param args */public static void main(String[] args) {// 得到实例对象UserLoginImpl user= new UserLoginImpl();// 将对象传入自己的代理类中MyHandler myHandler = new MyHandler(user);// 得到代理对象UserLogin proxy =(UserLogin)Proxy.newProxyInstance(user.getClass().getClassLoader(), user.getClass().getInterfaces(), myHandler);// 代理调用login方法proxy.login("张小三");}}

运行结果:

登录前处理欢迎张小三登录系统登录后处理

这样一个完成的动态代理的小例子就完成了,比如我现在想在另外一个类前后加上同样的方法,就可以直接把上面测试程序中的实例换成这个类的实例即可。


其实上面的例子还可以简化,直接在Myhandler中添加bind()如下:

package com.remote3c.main;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class MyHandler implements InvocationHandler {    private Object obj;    public Object bind(Object obj) {        this.obj = obj;        return Proxy.newProxyInstance(this.obj.getClass().getClassLoader(), this.obj.getClass().getInterfaces(), this);    }public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {beforeLogin(); // 登录前处理,更具自己需要来写Object res= method.invoke(obj, args);afterLogin(); // 登录后处理,更具自己需要来写return res;}public void beforeLogin() {        System.out.println("登录前处理");    }    public void afterLogin() {        System.out.println("登录后处理");    }}

然后在测试类中就可以这样调用

package com.remote3c.main;import java.lang.reflect.Proxy;public class ProxyText {/** * @param args */public static void main(String[] args) {// 得到实例对象UserLoginImpl user= new UserLoginImpl();// 将对象传入自己的代理类中//MyHandler myHandler = new MyHandler(user);// 得到代理对象//UserLogin proxy =(UserLogin)Proxy.newProxyInstance(user.getClass().getClassLoader(), user.getClass().getInterfaces(), myHandler);                UserLogin proxy =(UserLogin) new MyHandler().bind(user);// 代理调用login方法proxy.login("张小三");}}
这样显得简便很多。动态代理主要是创建实现了InvocationHandler的代理类。



0 0
原创粉丝点击