反射(攻击小兵)

目录

 

小兵-规则匹配

小兵表 

规则表

条件表


小兵-规则匹配

package org.geekbang.time.spark.Reflect;

import org.springframework.beans.BeanUtils;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class ReflectTest {
    public static void main(String[] args) {
        // 获取场景对应规则
        Rule rule = getRuleByScene("someScene");
        // 获取小兵
        Batman batman = getBatman();
        // 获取规则对应的条件列表
        List<Condition> conditionList = rule.getConditionList();
        // 小兵-规则匹配
        boolean matchRule = false;
        switch (RuleTypeEnum.getByCode(rule.getRuleType())) {
            case SIMPLE:
                Condition condition = conditionList.get(0);
                matchRule = isMeetCondition(condition, Batman.class, batman);
                break;
            case AND:
                matchRule = conditionList.stream().allMatch(con -> isMeetCondition(con, Batman.class, batman));
                break;
            case OR:
                matchRule = conditionList.stream().anyMatch(con -> isMeetCondition(con, Batman.class, batman));
                break;
            case EXPRESSION:
                // 解析expression
                break;
        }
        if (matchRule) {
            // 向小兵发送 biu biu biu ~
        }
    }

    /**
     * 通过反射获取object的指定属性【condition.getPropertyKey()】的值
     * 与condition的属性值做比较
     * 即:小兵的属性是否与规则中条件的属性一致
     */
    private static <T> boolean isMeetCondition(Condition condition, Class<T> tClass, T object) {
        return locateObject(object, tClass, condition.getPropertyKey(), condition.getPropertyValue());
    }

    /**
     * 定位服务,如果目标小兵<T object>通过反射获取的实际属性与
     * 目标属性targetPropertyValue一致,
     * 则该小兵为目标小兵
     */
    public static <T> boolean locateObject(T object, Class<T> tClass,
                                           String propertyKey, Object targetPropertyValue) {
        boolean match = false;
//        Object realPropertyValue = getRealPropertyValue(object,tClass);
        String methodName = "get" + propertyKey.substring(0, 1).toUpperCase()
                + propertyKey.substring(1);
        try {
            //
            /**
             * 常规获取Method方式
             * 通过getDeclaredMethod反射获取Method较为消耗性能,每次调用都要重新进行一次类加载
             */
//            Method method = tClass.getDeclaredMethod(methodName, null);
            /**
             * 使用BeanUtils增加缓存机制进行优化
             */
            PropertyDescriptor descriptor = BeanUtils.getPropertyDescriptor(tClass, propertyKey);
            Method method = descriptor.getReadMethod();

            // 让object对象调用自己的method方法,返回方法处理结果
            Object realPropertyValue = method.invoke(object);
            match = Objects.equals(targetPropertyValue, realPropertyValue);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return match;
    }

    private static Method getRealMethod(Class tClass, String propertyKey) throws NoSuchMethodException {
        String methodName = "get" + propertyKey.substring(0, 1).toUpperCase()
                + propertyKey.substring(1);
        return tClass.getDeclaredMethod(methodName, null);
    }

    /**
     * Mock 规则
     */
    private static Rule getRuleByScene(String someScene) {
        List<Condition> conditionList = new ArrayList<>();
        Condition condition1 = new Condition(1, "有红Buff", "rune", "red");
        Condition condition2 = new Condition(2, "有魔抗", "armor", "magic-defend");
        conditionList.add(condition1);
        conditionList.add(condition2);

        Rule rule = new Rule();
        rule.setRuleType("and");
        rule.setConditionList(conditionList);
        return rule;
    }

    /**
     * Mock 小兵
     */
    private static Batman getBatman() {
        Batman batman = new Batman();
        batman.setRune("red");// 有红Buff
        batman.setArmor("magic-defend");// 有魔抗
        return batman;
    }

    enum RuleTypeEnum {
        SIMPLE("simple"),// 单一条件
        AND("and"),// 多条件同时满足
        OR("or"),// 多条件满足任一条
        EXPRESSION("expression");// 条件匹配表达式

        private String code;

        RuleTypeEnum(String code) {
            this.code = code;
        }

        public String getCode() {
            return code;
        }

        public static RuleTypeEnum getByCode(String code) {
            for (RuleTypeEnum typeEnum : values()) {
                if (code.equals(typeEnum.getCode())) {
                    return typeEnum;
                }
            }
            return null;
        }
    }
}

小兵表 

package org.geekbang.time.spark.Reflect;

import java.util.Map;

public class Batman {
    private long id;
    private String rune;//符文
    private String armor;//盔甲
    private String shovel;//铲子
    private Map<String,String> magicArts;//法术
   // get/set
}

规则表

package org.geekbang.time.spark.Reflect;

import java.util.List;

/**
 * 规则表
 */
public class Rule {
    // 规则类型:simple/and/or/expression
    private String ruleType;
    // 条件列表
    private List<Condition> conditionList;
    // get/set
}

条件表

package org.geekbang.time.spark.Reflect;

/**
 * 条件表
 */
public class Condition {
    private Integer id;
    private String name;
    private String propertyKey;
    private String propertyValue;

    public Condition(Integer id, String name, String propertyKey, String propertyValue) {
        this.id = id;
        this.name = name;
        this.propertyKey = propertyKey;
        this.propertyValue = propertyValue;
    }

    //get/set
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值