• 基于DDD模型的思考,泛型如何获取真实类型的实例对象


    在这几天的探索和交流中,已找到一些解决方案,抛砖引玉,坐等更好的方案

    问题

    如何在使用泛型形参数的方法中,获取到泛型参数的实际类型的实例?

    interface IChar{
      public <T extends IChar > void kill(T victim);
    }
    
    class A implements IChar{
      
        List<Arrow> arrows;
      
        public <T extends IChar > void kill(T victim) {
          
        }
    
    
    }
    
    class B implements IChar{
      
        List<Trun> truns;
        public <T extends IChar > void kill(T victim) {
          
        }
      
    }
    

    A、B类都有自己的个性化字段的同时实现了IChar接口,整个系统方法传递时,都是按照IChar接口将A B的实例到处传递.

    下面的kill方法中 如何在不使用反射,类型强转特的情况下,获取到victim的实际类型的实例,从而拿到该实例的个性化字段<truns|arrows>?

        @Override
        public <T extends IChar > int kill(T victim) {
            return 0;
        }
    

    有朋友说可以思考DDD充血模型
    像这样

    public <T extends IChar > int kill(T victim) {
            victim.kill(this);
            return 0;
        }
    
    

    实际上这样传过去也是按IChar类型,如果在victim的kill中想要拿到参数的实例类型,再拿出个性化字段,也是无解的。

    上面的问题,源自游戏架构设计时 遇到的问题, 塔可以攻击,人也可以攻击。
    塔、人都可以相互攻击,在战斗逻辑中,除了必要的战斗参数需要拿出来运算,还可能会取出个性化字段进行逻辑上的处理,比如人是玩家操作的,他的字段可以有isvip是否是vip。。。 塔在攻击人时,如果人是vip,可以削弱一波塔的攻击力。。。

    解决办法

    package com.far.game.xiuzhen.gs.mgr;
    
    
    import com.far.game.xiuzhen.common.database.entity.Partner;
    import com.far.game.xiuzhen.gs.inherit.PartnerImpl;
    import com.far.game.xiuzhen.gs.inherit.Userx;
    import com.far.game.xiuzhen.gs.inherit.base.PartnerBase;
    
    import io.netty.util.internal.InternalThreadLocalMap;
    import org.apache.tomcat.jni.Thread;
    
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.stream.Stream;
    
    @FunctionalInterface
    interface CallFunc3<X, Y, Z> {
        boolean apply(X x, Y y, Z z);
    }
    
    @FunctionalInterface
    interface CallFunc1<T> {
        void apply(T e);
    
    }
    
    @FunctionalInterface
    interface CallFunc0<T> {
        T apply();
    
    }
    
    @FunctionalInterface
    interface CallFunc0NotR {
        void apply();
    
    }
    
    
    interface IChar {
        void kill(IChar victim);
    }
    
    interface IObject {
        String getId();
    
        void setVal(IChar obj);
    
    
    }
    
    /**
     * Callable 会吧所有的用到的类型都设置为字段
     * 比如 A B 类都是 他的字段
     */
    public class Callable {
    
    
        private A a;
        private B b;
    
        private Object me;
    
    
        public Object getMe() {
            return me;
        }
    
        public void setMe(Object me) {
            this.me = me;
        }
    
        public A getA() {
            return a;
        }
    
        public void setA(A a) {
            this.a = a;
        }
    
        public B getB() {
            return b;
        }
    
        public void setB(B b) {
            this.b = b;
        }
    
    
        //为了方便 把A B 写成了内部类,本质都是单独的文件
        public static class A implements IChar, IObject {
    
            private String id = "a";
            //个性化字段
            private List<String> partner;
    
    
            public List<String> getPartner() {
                return partner;
            }
    
            public void setPartner(List<String> partner) {
                this.partner = partner;
            }
    
            @Override
            public void kill(IChar victim) {
    
            }
    
            @Override
            public String getId() {
                return id;
            }
    
            @Override
            public void setVal(IChar obj) {
    
    
                Callable callable = new Callable();
                callable.setA(this);
                callable.setMe(this);
                vals.put(this.id, callable);
            }
    
    
        }
    
        public static class B implements IChar, IObject {
    
            private String id = "b";
            //个性化字段
            private Map<String, Object> userx;
    
            public Map<String, Object> getUserx() {
                return userx;
            }
    
            public void setUserx(Map<String, Object> userx) {
                this.userx = userx;
            }
    
            @Override
            public void kill(IChar victim) {
    
            }
    
            @Override
            public String getId() {
                return id;
            }
    
            @Override
            public void setVal(IChar obj) {
                Callable callable = new Callable();
                callable.setB(this);
                callable.setMe(this);
                vals.put(this.id, callable);
            }
    
    
        }
    
        /**
         * @param killer
         * @param victim
         * @description: 战斗逻辑处理类
         * @return: void
         * @author mike/Fang.J/Q184377367
         * @date: 2022/8/3 1:03
         */
        public static <T extends IChar & IObject> void combat(T killer, T victim) {
            //killerSd 是killer的映射 killerSd内字段值的变化 影响 killer , victim同理
            Callable killerSd = vals.get(killer.getId());
            Callable victimSd = vals.get(victim.getId());
    
            //在该方法中实际依然不知道 killerSd victimSd的具体类型,演示中仅仅是 A B 类,实际上 C D E F .... 都会被传入
            //到该方法,所以还需要其他帮助方法 更简单的完成killer victim的类型判断和取出个性化字段
    
    
            //此处这样设计的问题:如果有几百个类都会参与到该方法 会写到手软...
            /*
                A a11 = if( A.class, victimSd.getMe,victimSd.getA)
    
                IF 方法 可以 简化下面这种猥琐写法
                if ( x instanof ClassA){
                    ClassA aaa = (ClassA)x
                }
                ClassA aaa = IF(ClassA.class,x);
    
            */
    
    //        IF(A.class, victimSd::getMe, victimSd::getA, (e) -> {
    //            //如果victime是A执行特殊处理
    //            //此处 参数e 已经是A类的实例
    //            System.out.println("执行1");
    //        });
    //
    //        IF(A.class, killerSd::getMe, killerSd::getA, (e) -> {
    //            //如果killer是A执行特殊处理
    //            //此处 参数e 已经是A类的实例
    //            System.out.println("执行2");
    //        });
    
            Compare.IF(A.class, killerSd::getMe, killerSd::getA, (e) -> {
                System.out.println("执行2");
            }).ELSE(() -> {
                System.out.println("不是");
            });
    
    
            Compare.IF(A.class, victimSd::getMe, victimSd::getA, (e) -> {
                System.out.println("执行2");
            }).ELSE(() -> {
                System.out.println("不是");
            });
    
    
            //上面的代码简化此处的判断
            if (victimSd.getMe() instanceof A) {
                String s = victimSd.getA().partner.get(0);
                int x = 1;
            } else {
                System.out.println("3");
                int b = 2;
            }
    
    
        }
    
        //代理方法
        public static <T extends IChar & IObject> void proxyCombat(T killer, T victim) {
            killer.setVal(killer);
            victim.setVal(victim);
            combat(killer, victim);
        }
    
    
        public static Map<String, Callable> vals = new HashMap<>();
    
        public static void main(String[] args) {
            proxyCombat(new A(), new B());
        }
    
        public static <T> void IF(Class<?> clz, CallFunc0<Object> a, CallFunc0<T> b, CallFunc1<T> func) {
            if (a.apply().getClass().getSimpleName().equals(clz.getSimpleName())) {
                func.apply(b.apply());
            }
        }
    
    
        public static class Compare<T> {
    
            Class<?> clz;
            CallFunc0<Object> a;
            CallFunc0<T> b;
            CallFunc1<T> trueCall;
    
    
            public void ELSE(CallFunc0NotR elCall) {
                //先执行If
                if (a.apply().getClass().getSimpleName().equals(clz.getSimpleName())) {
                    trueCall.apply(b.apply());
                } else {
                    elCall.apply();
                }
            }
    
    
            public static <T> Compare<T> IF(Class<?> clz, CallFunc0<Object> a, CallFunc0<T> b, CallFunc1<T> func) {
                Compare<T> ifStm = new Compare<>();
                ifStm.clz = clz;
                ifStm.a = a;
                ifStm.b = b;
                ifStm.trueCall = func;
                return ifStm;
            }
    
        }
    
    
    }
    
    
  • 相关阅读:
    CSS
    版权动态日记页脚 JS
    smoothscroll
    JavaScript String
    JavaScript Document对象
    【网易官方】极客战记(codecombat)攻略-森林-漫漫长路long-road
    【网易官方】极客战记(codecombat)攻略-森林-看门狗guard-dog
    【网易官方】极客战记(codecombat)攻略-森林-去拿过来go-fetch
    【网易官方】极客战记(codecombat)攻略-森林-宠物小测试pet-quiz
    【网易官方】极客战记(codecombat)攻略-森林-博士猫咪phd-kitty
  • 原文地址:https://www.cnblogs.com/cfas/p/16545169.html
Copyright © 2020-2023  润新知