简体   繁体   English

哪种Java设计模式适合以下情况?

[英]What java design pattern is appropriate for the situation described below?

I am working on a chemistry package and I have a class which lists all the elements in the periodic table. 我正在研究化学包装,并且有一个列出了周期表中所有元素的类。 Ideally the elements will be part of a Java enum. 理想情况下,元素应该是Java枚举的一部分。 Unfortunately however I need one more element which is to serve as a wildcard : every other element should equal that element. 但是不幸的是,我还需要一个用作通配符的元素:每个其他元素都应等于该元素。 Java does not allow to override the equals() method for enums otherwise I would have done that. Java不允许为枚举覆盖equals()方法,否则我会这样做。 Would anyone be able to suggest a reasonable design pattern for the situation that I have just described? 有人能针对我刚才描述的情况提出合理的设计模式吗?

EDIT: Thank you for your contributions. 编辑:谢谢您的贡献。 I indeed failed to observe the transitive property required by equals() . 我确实没有观察到equals()所需的传递属性。

The elements of the periodic table will be assigned to different nodes on a graph structure(in mathematical sense). 元素周期表的元素将分配给图结构上的不同节点(在数学意义上)。 Given this graph structure I then look for all embeddings of a particular subgraph structure in the original graph (subgraph isomorphism problem). 给定这种图结构,然后我会在原始图中查找特定子图结构的所有嵌入(子图同构问题)。 A desired property of the subgraph structure is to have certain nodes to which a wildcard is assigned so that I can map those nodes to any node in the original graph regardless of the element assigned to it. 子图结构的理想属性是为某些节点分配通配符,这样我就可以将那些节点映射到原始图中的任何节点,而与分配给它的元素无关。 That is why I am looking for a non-transitive relation such that a wildcard may equal two different elements without implying that the elements themselves are equal. 这就是为什么我要寻找一种非传递关系,以便通配符可以等于两个不同的元素,而不意味着这些元素本身是相等的。 My current algorithm makes use of generics and calls equals() to check if elements in the two nodes are equal. 我当前的算法利用泛型并调用equals()来检查两个节点中的元素是否相等。

As mystarrocks pointed out, The big problem with your design is that it violates the equals contract . 正如mystarrocks指出的那样,您设计的最大问题是违反了平等合同 Specifically, as per the spec in class Object , the equals method should: 具体来说,按照Object类中的规范,equals方法应:

The equals method implements an equivalence relation on non-null object references: equals方法对非null对象引用实现对等关系:

  • It is reflexive: for any non-null reference value x, x.equals(x) should return true. 这是自反的:对于任何非空参考值x,x.equals(x)应该返回true。
  • It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true. 它是对称的:对于任何非空参考值x和y,当且仅当y.equals(x)返回true时,x.equals(y)才应返回true。
  • It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true. 它是可传递的:对于x,y和z的任何非空引用值,如果x.equals(y)返回true,而y.equals(z)返回true,则x.equals(z)应该返回true。
  • It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified. 这是一致的:对于任何非空引用值x和y,只要未修改对象的equals比较中使用的信息,对x.equals(y)的多次调用将始终返回true或始终返回false。
  • For any non-null reference value x, x.equals(null) should return false. 对于任何非null参考值x,x.equals(null)应该返回false。

(Source) (资源)

Your design would violate the transitive property. 您的设计会侵犯传递属性。 If sodium equals wildcard, and wildcard equals potassium, then sodium must equal potassium. 如果钠等于通配符,而通配符等于钾,那么钠必须等于钾。

A better way is to create a helper equals method for when you want to see if two elements can be considered equal (which is different than being equal). 更好的方法是创建一个辅助的equals方法,因为当你想看看两个元素可以被认为是相等的(这是比相等不同)。 Wildcard is only truly equal to wildcard, but it can be considered equal to any element. 通配符仅真正等于通配符,但可以认为它等于任何元素。

public enum Element {
  HYDROGEN,
  HELIUM,
  SODIUM,
  //.....
  URANIUM,
  WILD_CARD;

  public boolean consideredEqual(Object other) {
    if (other == null || ! (other instanceof Element)) return false;

    Element e = (Element) other;
    if (this.equals(Element.WILD_CARD) || e.equals(Element.WILD_CARD)) return true;
    return equals(other);
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM