代理模式:英雄的普攻和技能伤害值统计

本文通过代理模式实现对英雄攻击和技能伤害的统计,无需修改原有代码,展示了代理模式在不侵入业务代码的前提下进行功能增强的应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、模式定义

  • 代理模式为另一个对象提供一个替身或占位符以控制对这个对象的访问。
  • 相关组件
  1. Subject:Proxy和RealSubject都实现这个接口,以供客户端可以像处理RealSubject一样处理Proxy。
  2. RealSubject:真正做事的对象,Proxy会控制对RealSubject的访问。
  3. Proxy:代理类,持有Subject的引用,必要时可将请求转发给Subject。另外,创建RealSubject对象,通常由Proxy负责。
  • 三种代理控制方式:
    a. 远程代理控制访问远程对象。
    b. 虚拟代理控制访问创建开销大的资源。
    c. 保护代理基于权限控制对资源的访问。(动态代理就是这种方式)

二、举例说明

  • 场景:在不侵入业务代码的情况下,需要做一些统一的操作时使用代理模式。如搜集操作日志、事务开启与提交等。
  • 需求:每个英雄有普攻、技能两种对地方造成伤害的方式,现在需要在不影响已有代码的情况下,分别统计两种方式造成的总伤害值。

三、代码实现

  1. 定义公共接口
public interface Hero {
    void attack(Integer num);
    void skill(Integer num);
}
  1. 实际类
public class RealHero implements Hero {
    @Override
    public void attack(Integer damage) {
        System.out.println("使用普攻,对敌人造成伤害值:" + damage);
    }

    @Override
    public void skill(Integer damage) {
        System.out.println("使用技能,对敌人造成伤害值:" + damage);
    }
}
  1. 代理类
public class HeroInvocationHandler implements InvocationHandler {
    private Hero hero;
    private Integer attackDamage = 0;
    private Integer skillDamage = 0;

    public HeroInvocationHandler(Hero hero) {
        this.hero = hero;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object invoke = method.invoke(hero, args);
        if("attack".equals(method.getName())){
            attackDamage += (Integer) args[0];
        }
        if("skill".equals(method.getName())){
            skillDamage += (Integer) args[0];
        }
        System.out.println("--------------------该英雄普攻共造成总伤害:" + attackDamage);
        System.out.println("--------------------该英雄技能共造成总伤害:" + skillDamage);
        return invoke;
    }

    public Hero getProxyHero(){
        ClassLoader classLoader = hero.getClass().getClassLoader();
        Class<?>[] interfaces = hero.getClass().getInterfaces();
        return (Hero) Proxy.newProxyInstance(classLoader, interfaces, this);
    }
}
  1. 客户端执行
public class RealHeroClient {
    public static void main(String[] args) {
        // 1.创建英雄实例
        RealHero realHero = new RealHero();
        // 2.获取英雄实例的代理对象
        HeroInvocationHandler heroInvocationHandler = new HeroInvocationHandler(realHero);
        Hero proxyHero = heroInvocationHandler.getProxyHero();

        // 调用代理的普攻、技能方法
        proxyHero.attack(new Double(Math.random() * 100).intValue());
        proxyHero.skill(new Double(Math.random() * 100).intValue());
        proxyHero.attack(new Double(Math.random() * 100).intValue());
        proxyHero.skill(new Double(Math.random() * 100).intValue());
    }
}

执行结果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值