设计模式学习之代理模式

代理模式的定义:为其他对象提供一种代理以控制这个对象的访问,代理模式也叫做委托模式

代理模式通用类图如下:

Subject抽象主题角色:抽象主题类可以是抽象类或者接口。

RealSubject具体主题角色:叫做被委托对象,被代理对象,是业务逻辑的具体执行者

Proxy代理主题角色:叫做委托类、代理类。负责对真实角色的应用。

抽象角色:

/**
 * @author Lin
 * @Date 2018/1/5.
 */
public interface IGamePlayer {

    /**
     * 登录游戏
     * @param user
     * @param password
     */
    void login(String user,String password);

    /**
     * 杀怪
     */
    void killBoss();

    /**
     * 升级
     */
    void upgrade();
}

被代理类的实现:

/**
 * @author Lin
 * @Date 2018/1/5.
 */
public class GamePlayer implements IGamePlayer {

    private String name = "";

    public GamePlayer(String _name){
        this.name = _name;
    }

    @Override
    public void login(String user, String password) {
        System.out.println("登录名为--" + user + "--的用户" + this.name + "登录成功!");
    }

    @Override
    public void killBoss() {
        System.out.println(this.name + "在打怪!");
    }

    @Override
    public void upgrade() {
        System.out.println(this.name + "又升一级!");
    }
}

代理类:

/**
 * @author Lin
 * @Date 2018/1/5.
 */
public class GamePlayerProxy implements IGamePlayer{

    private IGamePlayer gamePlayer = null;

    /**
     * 构造函数指定对谁进行代练
     * @param _gamePlayer
     */
    public GamePlayerProxy(IGamePlayer _gamePlayer){
        this.gamePlayer = _gamePlayer;
    }

    @Override
    public void login(String user, String password) {
        gamePlayer.login(user,password);
    }

    @Override
    public void killBoss() {
        gamePlayer.killBoss();
    }

    @Override
    public void upgrade() {
        gamePlayer.upgrade();
    }
}

具体场景实现:

import java.util.Date;

/**
 * @author Lin
 * @Date 2018/1/5.
 */
public class Client {

    /**
     * 普通自己玩游戏
     * @param args
     */
 /*   public static void main(String[] args) {

        IGamePlayer player = new GamePlayer("H_Lin");
        System.out.println("开始时间是:" + new Date());
        player.login("User_Lin","123456");
        player.killBoss();
        player.upgrade();
        System.out.println("游戏结束时间:" + new Date());
    }*/

    /**
     * 通过代练玩游戏
     * @param args
     */
    public static void main(String[] args) {
        //定义一个游戏玩家
        IGamePlayer gamePlayer = new GamePlayer("张三");
        //定义一个游戏代练
        IGamePlayer proxy = new GamePlayerProxy(gamePlayer);
        System.out.println("开始时间是:" + new Date());
        proxy.login("zhangSan","123456");
        proxy.killBoss();
        proxy.upgrade();
        System.out.println("游戏结束时间:" + new Date());
    }
}

代理模式的优点:

  1. 职责清晰,真实角色就是实现实际的业务逻辑,不关系其他非本职责的事务,通过后期的代理完成一件事务。
  2. 高扩展性,具体的角色是可以随时变化的,只要它实现了接口,代理类可以在不做任何修改的情况下使用。

讲到代理就就必须提起动态代理了。什么是动态代理?动态代理是在实现阶段不用关心代理谁,而是在运行阶段才指定代理哪一个对象。

具体类图如下:

创建一个动态代理类:

/**
 * @author Lin
 * @Date 2018/1/5.
 */
public class GamePlayerTH implements InvocationHandler{

    /**
     * 被代理的对象
     */
    Object obj = null;

    public GamePlayerTH(Object _obj){
        this.obj = _obj;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = method.invoke(this.obj,args);
        return result;
    }
}

具体实现场景:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Date;

/**
 * @author Lin
 * @Date 2018/1/5.
 */
public class ClientTH {

    public static void main(String[] args) throws Exception{
        //定义一个游戏玩家
        IGamePlayer player = new GamePlayer("张三");
        InvocationHandler handler = new GamePlayerTH(player);
        System.out.println("开始时间是:" + new Date());
        ClassLoader cl = player.getClass().getClassLoader();
        IGamePlayer proxy = (IGamePlayer) Proxy.newProxyInstance(cl,player.getClass().getInterfaces(),handler);
        proxy.login("zhangSan","123456");
        proxy.killBoss();
        proxy.upgrade();
        System.out.println("游戏结束时间:" + new Date());
    }
}

 

posted @ 2018-01-05 15:40  随心-HL  阅读(180)  评论(0编辑  收藏  举报