智能引用代理:
示例类关系图:
示例源码:
public interface Searcher {
/**声明一个抽象方法*/
String doSearch(String userId, String searchType);
}
public class RealSearcher implements Searcher{
/**真实的查询工作在这里发生*/
@Override
public String doSearch(String userId, String searchType) {
String sql = "SELECT * FROM data_table WHERE key_col = keyValue";
//execute this SQL Statement and concatenate a result string
return "result set";
}
}
/**
* 从这里可以看到, 代理角色不是单纯的将调用传递给具体主题角色,
* 而是进行了委派前的权限查询和委派后的次数记录。
*/
public class Proxy implements Searcher {
private RealSearcher searcher;
private UsageLogger usageLogger;
private AccessValidator accessValidator;
public Proxy(){
searcher = new RealSearcher();
}
/**实现查询操作*/
@Override
public String doSearch(String userId, String searchType) {
if(checkAccess(userId)){
String result = searcher.doSearch(null, searchType);
logUsage(userId);
return result;
}
return null;
}
/**查询前的权限操作*/
private boolean checkAccess(String userId){
accessValidator = new AccessValidator();
return accessValidator.vaidateUser(userId);
}
/**查询后的日志操作*/
private void logUsage(String userId){
UsageLogger logger = new UsageLogger();
logger.setUserId(userId);
logger.save();
}
}
public class UsageLogger {
private String userId;
/**用户ID的赋值方法*/
public void setUserId(String userId){
this.userId = userId;
}
/**将这次使用记录加到日志中*/
public void save(){
String sql = "INSERT INTO USAGE_TABLE(user_id) Values(userId))";
//execute this SQL statement
}
/**将这次使用记录加到日志中*/
public void save(String userId){
this.userId = userId;
save();
}
}
public class AccessValidator {
/**用户权限检查发生在这里*/
public boolean vaidateUser(String userId){
if(userId.equals("Admin"))
{
return true;
}else{
return false;
}
}
}
public class Client {
//声明一个静态类型为Searcher的静态变量
private static Searcher searcher;
public static void main(String[] args) {
//此静态变量的真实类型为Proxy
searcher = new Proxy();
String userId = "Admin";
String searchType = "SEARCH_BY_ACCOUNT_NUMBER";
String result = searcher.doSearch(userId, searchType);
System.out.println(result);
}
}
虚拟代理:
虚拟代理模式的应用:
当一个真实主题对象的加载需要耗费资源时,一个虚拟代理对象可以代替真实对象接受请求。一旦接到请求,代理对象马上打出一段“正在加载”的信息,并在适当的时候加载真实主题对象,也就是模块或者图像。
下面的示例演示了如何利用代理模式实现图像加载时会遇到的加载延缓处理。在实际系统中,加载延缓往往是针对较大型的软件模块,而不仅仅是一张图像。但实际的做法是一样的:利用虚拟代理对象接受加载请求,并将真实主题的加载延缓到真正需要的时候。
import java.awt.Graphics;
import java.awt.Insets;
import javax.swing.Icon;
import javax.swing.JFrame;
public class Client extends JFrame {
private static int IMAGE_WIDTH = 270;
private static int IMAGE_HEIGHT = 380;
private Icon imageIconProxy = null;
public Client(){
super("Virtual Proxy Client");
imageIconProxy = new ImageIconProxy("c:/bgbody.jpg", IMAGE_WIDTH, IMAGE_HEIGHT);
setBounds(100, 100, IMAGE_WIDTH + 10, IMAGE_HEIGHT + 30);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
/**置换掉java.awt.Container的方法*/
public void paint(Graphics g){
super.paint(g);
Insets insets = getInsets();
imageIconProxy.paintIcon(this, g, insets.left, insets.top);
}
static public void main(String[] args){
Client app = new Client();
app.show();
}
}
import java.awt.Component;
import java.awt.Graphics;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.SwingUtilities;
public class ImageIconProxy implements Icon{
private ImageIcon realIcon = null;
private String imageName;
private int width;
private int height;
boolean isIconCreated = false;
public ImageIconProxy(String imageName, int width, int height){
this.imageName = imageName;
this.width = width;
this.height = height;
}
@Override
public int getIconHeight() {
return realIcon.getIconHeight();
}
@Override
public int getIconWidth() {
return realIcon.getIconWidth();
}
@Override
public void paintIcon(final Component c, Graphics g, int x, int y) {
if(isIconCreated){
realIcon.paintIcon(c, g, x, y);
g.drawString("我的小艳艳", x + 20, y + 370);
}else{
g.drawRect(x, y, width - 1, height - 1);
g.drawString("Loading yaner's photo...", x + 20, y + 20);
synchronized(this){
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
try {
//减缓图像的加载过程
Thread.currentThread().sleep(2000);
//将图像加载
realIcon = new ImageIcon(imageName);
isIconCreated = true;
} catch (InterruptedException e) {
e.printStackTrace();
}
//当图像被加载后,重新描绘视窗构件
c.repaint();
}});
}
}
}
}