1.代理模式(Proxy Pattern):给某一个对象提供一个代理或占位符,并由代理对象来控制对原对象的访问。

(1)Subject(抽象主题角色):它声明了真实主题和代理主题的共同接口,这样一来在任何使用真实主题的地方都可以使用代理主题,客户端通常需要针对抽象主题角色进行编程。

(2)Proxy(代理主题角色):它包含了对真实主题的引用,从而可以在任何时候操作真实主题对象;代理主题角色还可以控制对真实主题的使用,负责在需要的时候创建和删除真实主题对象,并对真实主题对象的使用加以约束。通常,在代理主题角色的客户端在调用真实主题操作前或之后还需要执行其他操作,而不仅仅是单纯地调用真实主题对象的操作。

(3)RealSubject(真实主题角色):它定义了代理角色所代表的真实对象,在真实主题角色中实现了真实的业务操作,客户端可以通过代理主题角色间接调用真实主题角色中定义的操作。

/**抽象主题类*/
public abstract class Subject{
    public abstract void request();
}
/**真实主题类*/
public class RealSubject extends Subject{
    public void request(){
        //实现业务方法的具体代码
    }
}
/**代理类*/
public class Proxy extends Subject{
    private RealSubject realSubject = new RealSubject();//维持一个对真实主题对象的引用
    public void preRequest(){```}
    public void request(){
        preRequest();
        realSubject.request();//调用真实主题对象的方法
        postRequest();
    }
    public void postRequest(){```}
}

2.代理模式实例描述及代码:一家游戏公司创建了孙悟空这个角色,第一版本孙悟空这个角色可以登录游戏,并能学习七十二变技能。第二版本,游戏公司想给孙悟空这个角色新加可以学习筋斗云和火眼金睛的技能。在不改变之前类和方法的前提下,游戏公司可以利用代理设计模式来解决这个问题。

/**筋斗云技能类(业务类),它提供了jindou()方法来学习筋斗云技能*/
public class JindouSkill {
    //模拟实现学习筋斗云技能方法
    public boolean jindou(String userId) {
        System.out.println(userId + "学会了筋斗云。");
        return true;
    }
}
/**火眼金睛技能类(业务类),它提供eye()方法来学习技能*/
public class EyeSkill {
    //模拟学习技能的方法
    public void eye(String userId) {
        System.out.println(userId + "学会了火眼金睛。");
    }
}
/**抽象查询类,充当抽象主题角色*/
public interface Skill {
    public String doSkill(String userId, String keyword);
}
/**具体角色技能类,充当真实主题角色*/
public class RealSkill implements Skill {
    //模拟角色登录和技能学习
    public String doSkill(String userId, String keyword) {
        System.out.println("在数据库中验证用户'" + userId + "'是否为合法用户?");
        if (userId.equalsIgnoreCase("孙悟空") && keyword.equalsIgnoreCase("孙行者")) {
            System.out.println("'" + userId + "'登录成功");
            System.out.println(userId + "学会了七十二变。");
        } else {
            System.out.println("'" + userId + "'登录失败");
        }
        return "角色信息";
    }
}
/**代理技能类,充当代理主题角色*/
public class ProxySkill implements Skill {
    private RealSkill realskill = new RealSkill();//维持一个对真实主题的引用
    private JindouSkill jindouSkill;
    private EyeSkill eyeSkill;

    public String doSkill(String userId, String keyword) {
        String result = realskill.doSkill(userId, keyword);//调用真实主题对象的学习技能方法
        this.jindou(userId);//学习筋斗云技能
        this.eye(userId);//学习火眼金睛技能
        return result;
    }

    //创建学习筋斗云技能对象并调用其jindou()方法学习筋斗云技能
    public boolean jindou(String userId) {
        jindouSkill = new JindouSkill();
        return jindouSkill.jindou(userId);
    }

    //创建学习火眼金睛技能对象并调用其eye()方法学习火眼金睛技能
    public void eye(String userId) {
        eyeSkill = new EyeSkill();
        eyeSkill.eye(userId);
    }
}
/**客户端测试类*/
public class Client{
    public static void main(String args[]){
        Skill skill;//针对抽象编程,客户端无需分辨真实主题类和代理
        skill = new ProxySkill();
        String result = skill.doSkill("孙悟空", "孙行者");
    }
}

3.代码运行结果

更多推荐

Java设计模式用孙悟空打开代理模式(附实例代码)每天一学设计模式