Java Tutorial/Design Pattern/Proxy Pattern

Материал из Java эксперт
Перейти к: навигация, поиск

Dynamic Proxies

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface MyClass {
  void methodA(String s);
  void methodB(int i);
  String methodC(int i, String s);
}
public class DynamicProxyDemo {
  public static void main(String[] clargs) {
    MyClass prox = (MyClass) Proxy.newProxyInstance(MyClass.class.getClassLoader(), new Class[] { MyClass.class },
        new InvocationHandler() {
          public Object invoke(Object proxy, Method method, Object[] args) {
            System.out.println("Method = " + method);
            if (args != null) {
              System.out.println("args = ");
              for (int i = 0; i < args.length; i++)
                System.out.println("\t" + args[i]);
            }
            return null;
          }
        });
    System.out.println("about to call methodA");
    prox.methodA("hello");
    System.out.println("finish calling methodA");
    prox.methodB(47);
    prox.methodC(47, "hello");
  }
}





Proxy: fronting for another object

interface ProxyBase {
  void taskOne();
  void taskTwo();
  void taskThree();
}
class Implementation implements ProxyBase {
  public void taskOne() {
    System.out.println("Implementation.f()");
  }
  public void taskTwo() {
    System.out.println("Implementation.g()");
  }
  public void taskThree() {
    System.out.println("Implementation.h()");
  }
}
class Proxy implements ProxyBase {
  private ProxyBase implementation;
  public Proxy() {
    implementation = new Implementation();
  }
  public void taskOne() {
    implementation.taskOne();
  }
  public void taskTwo() {
    implementation.taskTwo();
  }
  public void taskThree() {
    implementation.taskThree();
  }
}

public class ProxyDemo {
  public static void main(String args[]) {
    Proxy p = new Proxy();
    p.taskOne();
    p.taskTwo();
    p.taskThree();
  }
}





The PoolManager using Proxy

import java.util.ArrayList;
class PoolItem {
  boolean inUse = false;
  Object item;
  PoolItem(Object item) {
    this.item = item;
  }
}
class ReleasableReference { // Used to build the proxy
  private PoolItem reference;
  private boolean released = false;
  public ReleasableReference(PoolItem reference) {
    this.reference = reference;
  }
  public Object getReference() {
    if (released)
      throw new RuntimeException("Tried to use reference after it was released");
    return reference.item;
  }
  public void release() {
    released = true;
    reference.inUse = false;
  }
}
class PoolManager {
  private ArrayList<PoolItem> items = new ArrayList<PoolItem>();
  public void add(Object item) {
    items.add(new PoolItem(item));
  }
  public static class EmptyPoolItem {
  }
  public ReleasableReference get() {
    for (int i = 0; i < items.size(); i++) {
      PoolItem pitem = (PoolItem) items.get(i);
      if (pitem.inUse == false) {
        pitem.inUse = true;
        return new ReleasableReference(pitem);
      }
    }
    return null;
  }
}
interface Connection {
  Object get();
  void set(Object x);
  void release();
}
class ConnectionImplementation implements Connection {
  public Object get() {
    return null;
  }
  public void set(Object s) {
  }
  public void release() {
  }
}
class ConnectionPool { // A singleton
  private static PoolManager pool = new PoolManager();
  private ConnectionPool() {
  }
  public static void addConnections(int number) {
    for (int i = 0; i < number; i++)
      pool.add(new ConnectionImplementation());
  }
  public static Connection getConnection() {
    ReleasableReference rr = (ReleasableReference) pool.get();
    if (rr == null)
      return null;
    return new ConnectionProxy(rr);
  }
}
class ConnectionProxy implements Connection {
  private ReleasableReference implementation;
  public ConnectionProxy(ReleasableReference rr) {
    implementation = rr;
  }
  public Object get() {
    return ((Connection) implementation.getReference()).get();
  }
  public void set(Object x) {
    ((Connection) implementation.getReference()).set(x);
  }
  public void release() {
    implementation.release();
  }
}
public class ConnectionPoolProxyDemo {
  public static void main(String args[]) {
    try {
      ConnectionPool.addConnections(5);
      Connection c = ConnectionPool.getConnection();
      c.set(new Object());
      c.get();
      c.release();
      c = ConnectionPool.getConnection();
      c.set(new Object());
      c.get();
      c.release();
      c.get();
    } catch (Exception e) {
      System.out.println(e.getMessage());
    }
  }
}