我正试图想出一个问题的解决方案,在这个问题中,我希望以某种方式存储方法引用,以便在需要时调用它们,并在我的方法列表中不需要它们时移除它们。
这里的基本目标是这样的:
我有个人课:
public class Person {
private String ref, name;
private String fatherRef; // can be reference string (such as "#1#") or a literal text (such as "the guy next door")
public Person(String ref, String name) {
this.ref = ref;
this.name = name;
}
public String getFatherRef() {return fatherRef;}
public void setFatherRef(String ref) {
fatherRef = ref;
}
...
}
我创建了两个父和子的实例,并使用setFatherRef方法将父的ref设置为子的fatherRef。 我把他们两个都列在单子上。 现在假设父亲的对象从系统中删除,并且他的引用对另一个人可用。 为了确保在其父被删除后,其子的对象中不会引用其父,我想出了这样的方法:
我创建了一个接口IRefSetter{public void setRef(String ref);}
,并使用它创建了一个ArrayList< IRefSetter>
方法(例如SetFatherRef
或SetMotherRef
等),并使用父级的引用将该列表映射到一个HashMap
上,这样,每当我摆脱任何一个人时,我都可以查看他们的引用,并查看它是否映射到一个方法列表上,我可以使用该列表将
在本例中,映射将只有一个父引用到列表的映射,该列表包含引用Person
类中的SetFatherRef
的单个方法。 这样就可以很好地工作了,但是假设我将fatherRef设置为其他人的ref,并以与原始father相同的方式为该新人添加方法引用。 但是现在剩下的是一个hashmap
,它包含在原始父亲的ref下的一个列表,其中存储了一个方法,用于在原始父亲被删除时重置儿子的fatherRef。 但这不再是必要的,因为儿子现在有一个不同的父集合,具有不同的裁判。
我找不到一种简单的方法来识别列表中的哪个方法是Son::SetFatherRef
,因为每次引用该方法时创建的lambda函数都是不同的。
从那时起,我开始研究一种非常难看的解决方案,它不是存储与我的原始iRefSetter
接口匹配的lambda函数,而是存储对儿子的Person
实例的Object
引用以及作为String
的方法名,并尝试手动将正确的方法与我的iRefSetter
接口匹配(使用Class
和method
类)。 但这是一个非常丑陋的解决方案,它会产生运行时错误,而不是编译器错误,这是我不喜欢的,整个事情在我看来不是非常OOP。
我是不是错过了一个更好的解决方案?
更好的解决办法是:
public class Person {
private String ref, name;
private Person father;
private List<Person> children;
... a lot of obvious stuff here ...
}
现在,当您删除一个人
时,您可以查看该人的父亲
,然后从子
的父亲列表中删除该人
,还可以查看已删除人的子
,并将每个人的父亲
设置为NULL。 如果您想知道父亲的引用,只需执行father.ref
或getFather().getRef()
即可。
我感觉到你不想这样做出于某种原因,比如它很脏或者不是OOP之类的东西。 但这是最好地利用语言和运行库功能的解决方案。
其他的解决方案往往是更复杂的方法。 在您的示例中,没有使用childress
成员,而是创建了单独的hashmap
,其中键是父引用,值是setter方法数组,但是您可以看到这是一样的:对于每个子-父关系,列表中都有一个条目与父关联。
如果您坚持使用setter策略,那么避免意外清除不再指向要删除的人员的父
问题的一个简单方法就是检查父
字段是否仍然指向该人员。 setter方法仍然在列表中,并且仍然会被调用,但是它不会造成任何损害。