基于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;
}
}
}
Rust编程语言群 1036955113
java新手自学群 626070845
java/springboot/hadoop/JVM 群 4915800
Hadoop/mongodb(搭建/开发/运维)Q群481975850
GOLang Q1群:6848027
GOLang Q2群:450509103
GOLang Q3群:436173132
GOLang Q4群:141984758
GOLang Q5群:215535604
C/C++/QT群 1414577
单片机嵌入式/电子电路入门群群 306312845
MUD/LIB/交流群 391486684
Electron/koa/Nodejs/express 214737701
大前端群vue/js/ts 165150391
操作系统研发群:15375777
汇编/辅助/破解新手群:755783453
大数据 elasticsearch 群 481975850
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
java新手自学群 626070845
java/springboot/hadoop/JVM 群 4915800
Hadoop/mongodb(搭建/开发/运维)Q群481975850
GOLang Q1群:6848027
GOLang Q2群:450509103
GOLang Q3群:436173132
GOLang Q4群:141984758
GOLang Q5群:215535604
C/C++/QT群 1414577
单片机嵌入式/电子电路入门群群 306312845
MUD/LIB/交流群 391486684
Electron/koa/Nodejs/express 214737701
大前端群vue/js/ts 165150391
操作系统研发群:15375777
汇编/辅助/破解新手群:755783453
大数据 elasticsearch 群 481975850
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。