定义:为另一个对象提供一个替身或者战位符以范围这个对象。
要点:
1。代理模式为另外一个对象提供代表,以便控制客户对对象的访问,管理访问的方式有许多种。
2。远程带来管理客户和远程对象之间的交会。
3。虚拟代理控制访问实例化开销大的对象。
4。保护代理基于调用者控制对对象方法的访问。
5。代理模式有许多变体,例如:缓存代理,同步代理,防火墙代理和写入时复制代理。
6。代理在结构上类似装饰者,但是目的不同。
7。装饰者模式为对象加上行为,而代理则是控制访问。
8。java内置的代理支持,可以根据需要将来动态代理,并将所有调用分配到所选的处理器。
9。就合其他的包装者一样,代理会造成你的设计中类的数目增加。
//虚拟代理
package pattern;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Enumeration;
import java.util.Hashtable;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
public class ImageProxyTestDrive {
ImageComponent imageComponent;
JFrame frame = new JFrame("CD Cover viewer");
JMenuBar menuBar;
JMenu menu;
Hashtable cds = new Hashtable();
public static void main(String[] args) throws Exception {
ImageProxyTestDrive testDrive = new ImageProxyTestDrive();
// TODO Auto-generated method stub
}
public ImageProxyTestDrive() throws Exception {
cds.put("Ambient: Music for Airports", "http://image.club.china.com/3212956/2008/3/27/0.jpg");
cds.put("Ima","http://image.club.china.com/3934/2008/3/22/0.jpg");
cds.put("Selected Ambient Works,Vol.2", "http://image.club.china.com/3934/2008/1/22/2.jpg");
URL initialURL = new URL((String) cds.get("Ima"));
menuBar = new JMenuBar();
menu = new JMenu("Favorite CDs");
menuBar.add(menu);
frame.setJMenuBar(menuBar);
for (Enumeration e = cds.keys(); e.hasMoreElements();) {
String name = (String) e.nextElement();
JMenuItem menuItem = new JMenuItem(name);
menu.add(menuItem);
menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
imageComponent.setIcon(new ImageProxy(getCDUrl(event
.getActionCommand())));
frame.repaint();
}
});
}
Icon icon = new ImageProxy(initialURL);
imageComponent = new ImageComponent(icon);
frame.getContentPane().add(imageComponent);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800, 600);
frame.setVisible(true);
}
URL getCDUrl(String name) {
try {
return new URL((String) cds.get(name));
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
}
}
}
interface Icon {
int getIconWidth();
int getIconHeight();
void paintIcon(final Component c, Graphics g, int x, int y);
}
class ImageProxy implements Icon {
ImageIcon imageIcon;
URL imageURL;
Thread retrievalThread;
boolean retrieving = false;
public ImageProxy(URL url) {
imageURL = url;
}
public int getIconWidth() {
if (imageIcon != null) {
return imageIcon.getIconWidth();
} else
return 500;
}
public int getIconHeight() {
if (imageIcon != null) {
return imageIcon.getIconHeight();
} else
return 400;
}
public void paintIcon(final Component c, Graphics g, int x, int y) {
if (imageIcon != null) {
imageIcon.paintIcon(c, g, x, y);
} else {
g.drawString("Loading CD cover,please wait...", x + 40, y + 40);
if (!retrieving) {
retrieving = true;
retrievalThread = new Thread(new Runnable() {
public void run() {
try {
imageIcon = new ImageIcon(imageURL, "CD Cover");
c.repaint();
} catch (Exception e) {
e.printStackTrace();
}
}
});
retrievalThread.start();
}
}
}
}
class ImageComponent extends JComponent {
private Icon icon;
public ImageComponent(Icon icon) {
this.icon = icon;
}
public void setIcon(Icon icon) {
this.icon = icon;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
int w = icon.getIconWidth();
int h = icon.getIconHeight();
int x = (800 - w) / 2;
int y = (600 - h) / 2;
this.icon.paintIcon(this, g, x, y);
}
}
//动态代理 和安全代理
package pattern;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MatchMakingTestDrive {
/**
* @param args
*/
public static void main(String[] args) {
MatchMakingTestDrive test=new MatchMakingTestDrive();
test.drive();
}
public MatchMakingTestDrive(){
//initializeDatabase();
}
public void drive(){
PersonBean joe=new PersonBeanImpl("Joe Javabean");
PersonBean ownerProxy=getOwnerProxy(joe);
System.out.println("Name is " + ownerProxy.getName());
ownerProxy.setInterests("bowling, GO");
try{
ownerProxy.setHotOrNotRating(10);
}catch(Exception e){
System.out.println("Can't set rating from owner proxy");
}
System.out.println("Rating is"+ ownerProxy.getHotOrNotRating());
PersonBean nonOwnerProxy=getNoOwnerProxy(joe);
System.out.println("Name is "+ nonOwnerProxy.getName());
try{
nonOwnerProxy.setInterests("bowling, Go");
}catch(Exception e){
System.out.println("Can't set interests from non owner proxy");
}
nonOwnerProxy.setHotOrNotRating(3);
System.out.println("Rating set from non owner proxy");
System.out.println("Rating is "+ nonOwnerProxy.getHotOrNotRating());
}
PersonBean getOwnerProxy(PersonBean person){
return (PersonBean)Proxy.newProxyInstance(person.getClass().getClassLoader(),person.getClass().getInterfaces(),new OwnerInvocationHandler(person));
}
PersonBean getNoOwnerProxy(PersonBean person){
return (PersonBean)Proxy.newProxyInstance(person.getClass().getClassLoader(),person.getClass().getInterfaces(),new NoOwnerInvocationHandler(person));
}
}
interface PersonBean {
String getName();
String getGender();
String getInterests();
int getHotOrNotRating();
void setName(String name);
void setGender(String gender);
void setInterests(String interests);
void setHotOrNotRating(int rating);
}
class PersonBeanImpl implements PersonBean{
String name;
String gender;
String interests;
int rating;
int ratingCount=0;
public PersonBeanImpl(String name){
name=name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public int getHotOrNotRating(){
if(ratingCount==0)return 0;
return (rating/ratingCount);
}
public void setGender(String gender) {
this.gender = gender;
}
public String getInterests() {
return interests;
}
public void setInterests(String interests) {
this.interests = interests;
}
public void setHotOrNotRating(int rating){
this.rating+=rating;
ratingCount++;
}
}
class OwnerInvocationHandler implements InvocationHandler{
PersonBean person;
public OwnerInvocationHandler(PersonBean person){
this.person=person;
}
public Object invoke(Object proxy,Method method,Object[] args) throws IllegalAccessException{
try{
if(method.getName().startsWith("get")){
return method.invoke(person, args);
}else if(method.getName().equals("setHotOrNotRating")){
throw new IllegalAccessException();
}else if(method.getName().startsWith("set")){
return method.invoke(person, args);
}
}catch(InvocationTargetException e){
e.printStackTrace();
}
return null;
}
}
class NoOwnerInvocationHandler implements InvocationHandler{
PersonBean person;
public NoOwnerInvocationHandler(PersonBean person){
this.person=person;
}
public Object invoke(Object proxy,Method method,Object[] args) throws IllegalAccessException{
try{
if(method.getName().startsWith("get")){
return method.invoke(person, args);
}else if(method.getName().equals("setHotOrNotRating")){
return method.invoke(person, args);
}else if(method.getName().startsWith("set")){
throw new IllegalAccessException();
}
}catch(InvocationTargetException e){
e.printStackTrace();
}
return null;
}
}