427 design standard
(→Define Equals) |
|||
Line 38: | Line 38: | ||
#contain, way down in their bowls, equivalent value types. | #contain, way down in their bowls, equivalent value types. | ||
− | + | ====How do the big players define .Equals?==== | |
− | ====Java SE 6==== | + | =====Java SE 6===== |
From [http://java.sun.com/javase/6/docs/api/ Sun]: | From [http://java.sun.com/javase/6/docs/api/ Sun]: | ||
Line 61: | Line 61: | ||
</blockquote> | </blockquote> | ||
− | ====.NET 3.5==== | + | =====.NET 3.5===== |
From [http://msdn.microsoft.com/en-us/library/bsc2ak47.aspx Microsoft]: | From [http://msdn.microsoft.com/en-us/library/bsc2ak47.aspx Microsoft]: | ||
<blockquote> | <blockquote> | ||
Line 67: | Line 67: | ||
</blockquote> | </blockquote> | ||
− | ==== | + | ====How should we define .Equals?==== |
Both the Java SE 6 and .NET 3.5 APIs have already taken care of the "are the same object" case. Any .Equals methods we implement must therefore hide or override this, and should provide an equivalence measure at lower levels of the object. | Both the Java SE 6 and .NET 3.5 APIs have already taken care of the "are the same object" case. Any .Equals methods we implement must therefore hide or override this, and should provide an equivalence measure at lower levels of the object. | ||
Line 74: | Line 74: | ||
Points to consider: | Points to consider: | ||
− | * | + | *Hiding or overriding the Object.Equals method is only necessary if a lower level equivalence measure is required. |
*The designer must make it clear to the client to what level an equivalence measure is made. Naive use of an .Equals method could be the cause of much grief. | *The designer must make it clear to the client to what level an equivalence measure is made. Naive use of an .Equals method could be the cause of much grief. | ||
− | *Enforcing a measure of equivalence down to the value type level will require that all a class' fields also override the .Equals method, lest the [[Law of Demeter|Law of demeter]] be broken. | + | *Enforcing a measure of equivalence down to the value type level will require that all a class's fields also override the .Equals method, lest the [[Law of Demeter|Law of demeter]] be broken. |
Revision as of 05:33, 4 August 2008
What rules do we all agree on? Let's write them here so everybody can follow them in their design study.
Contents |
Getters and setters
- Always make fields have protected access.
- Always write a getter, but minimize access.
- Always call getter, even in same object.
This standard was influenced by the Getters and setters and Encapsulation boundary ideas.
- Here's an alternative set of guidelines our group came up with:
- Always make fields have private access.
- Only write getters and setters as needed.
- External: access to fields using getters and setters.
- Internal: access to fields directly, but only if it's the same object. Use getter and setters if same class, but different objects.
- Getters should be read-only (i.e. Collections should be returned as unmodifiable Collections)
- --Yugan 06:09, 23 July 2008 (UTC)
- Agreed, I prefer private access to instance variables, One's private bit is private, though it is protected, it is still private. Also, we have agreed to minimize access so private is the most minimum access for one's private bit. --Jojo 02:48, 30 July 2008 (UTC)
Nouns
When discussing the Frogs design we came up with a new principle/heuristic in class: Class names should be nouns. Do we (collectively as a class) want to make this a principle? --Yugan 04:14, 23 July 2008 (UTC)
- Yup, I'm cool with it...Hmm do we think this is more of a coding/design standards? --Jojo 04:23, 23 July 2008 (UTC)
- What about interfaces? Should we make them nouns as well? But I have seen many cases (including this one) where interfaces represent behavior, so is it still a good idea? --Yugan 04:57, 23 July 2008 (UTC)
- Yea, I think nouns generally would be a good idea. As for that case, you can name it in a "verb+able" format which conveys capability (eg: Move+able = Movable), sweet no? =D --Jojo 05:42, 23 July 2008 (UTC)
- Or we can use C# convention of having 'I+noun' or 'I+whatever' format, ahaha, I have no idea now. But now when I think about it...Movable gives a sense that the Frog can be moved which doesnt really what we want. Maybe...MoveAbility (or IMoveAbility)? --Jojo 05:59, 23 July 2008 (UTC)
- I think the C# convention of using 'I' prefix for interface names is a good idea too (e.g. IComparable). But I think interfaces could be verbs too, where classes should only be nouns. --Yugan 03:14, 29 July 2008 (UTC)
- What about interfaces? Should we make them nouns as well? But I have seen many cases (including this one) where interfaces represent behavior, so is it still a good idea? --Yugan 04:57, 23 July 2008 (UTC)
The .Equals(...) Method
A policy on the implementation of .Equals methods.
Define Equals
How should we define equivalence?
Two objects can be equal if they either
- are the same object (i.e. reference the same block(s) of data in physical memory),
- contain the same references (i.e. are “shallow copies” of each other), or
- contain, way down in their bowls, equivalent value types.
How do the big players define .Equals?
Java SE 6
From Sun:
[The .Equals method] indicates whether some other object is "equal to" this one.
The equals method implements an equivalence relation on non-null object references:
- It is reflexive: for any non-null reference value x, x.equals(x) should return 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.
- 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.
- 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.
- For any non-null reference value x, x.equals(null) should return false.
The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true).
Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.
.NET 3.5
From Microsoft:
The default implementation of Equals supports reference equality for reference types, and bitwise equality for value types. Reference equality means the object references that are compared refer to the same object. Bitwise equality means the objects that are compared have the same binary representation.
How should we define .Equals?
Both the Java SE 6 and .NET 3.5 APIs have already taken care of the "are the same object" case. Any .Equals methods we implement must therefore hide or override this, and should provide an equivalence measure at lower levels of the object.
Our Policy
Points to consider:
- Hiding or overriding the Object.Equals method is only necessary if a lower level equivalence measure is required.
- The designer must make it clear to the client to what level an equivalence measure is made. Naive use of an .Equals method could be the cause of much grief.
- Enforcing a measure of equivalence down to the value type level will require that all a class's fields also override the .Equals method, lest the Law of demeter be broken.