427 design standard
(→Nouns) |
|||
(6 intermediate revisions by 4 users not shown) | |||
Line 4: | Line 4: | ||
* Always make fields have ''protected'' access. | * Always make fields have ''protected'' access. | ||
* Always write a getter, but minimize access. | * Always write a getter, but minimize access. | ||
− | * Always call getter, even in same object. | + | * Always call getter, even in same object (except in the constructor). |
This standard was influenced by the [[Getters and setters]] and [[Encapsulation boundary]] ideas. | This standard was influenced by the [[Getters and setters]] and [[Encapsulation boundary]] ideas. | ||
Line 17: | Line 17: | ||
:::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. --[[User:Johannes Pagwiwoko|Jojo]] 02:48, 30 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. --[[User:Johannes Pagwiwoko|Jojo]] 02:48, 30 July 2008 (UTC) | ||
+ | |||
+ | ::: "Only write getters and setters as needed" concurs with the "[[You ain't gonna need it]]"-principle as stated by [http://www.xprogramming.com/Practices/PracNotNeed.html Ron Jeffries] --[[User:Dominic Winkler|Dom]] 04:09, 5 August 2008 (UTC) | ||
+ | |||
+ | :: I would argue that there are merits to both approaches, and my ideal set of guidelines would be: | ||
+ | ::* All fields are ''protected''. | ||
+ | ::* Write a getter only when needed. ("[[You ain't gonna need it]]") | ||
+ | ::* Write setters as needed, but if you need one, seriously consider whether you have a [[Data class smell]], or are disobeying [[Tell, don't ask]] | ||
+ | ::* External: Access to fields with getters and setters | ||
+ | ::* Internal: Access to fields directly, if in same object (see above) | ||
+ | ::* Getters should be read-only | ||
+ | :::--[[User:Lukas Korsika|Lukas Korsika]] 00:16, 21 October 2010 (UTC) | ||
== Nouns == | == Nouns == | ||
Line 26: | Line 37: | ||
:::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)? --[[User:Johannes Pagwiwoko|Jojo]] 05:59, 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)? --[[User:Johannes Pagwiwoko|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. --[[User:Yugan Yugaraja|Yugan]] 03:14, 29 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. --[[User:Yugan Yugaraja|Yugan]] 03:14, 29 July 2008 (UTC) | ||
+ | ::::How about ICanMove ;-) --[[User:Lukas Korsika|Lukas Korsika]] 00:17, 21 October 2010 (UTC) | ||
==The .Equals(...) Method== | ==The .Equals(...) Method== | ||
Line 75: | Line 87: | ||
Points to consider: | Points to consider: | ||
*Hiding or overriding the Object.Equals method is only necessary if a lower level equivalence measure is required. | *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. | + | *The designer must make it clear to the client to what level an equivalence measure is made. Naïve use of an .Equals method could cause the client much grief. |
− | *Enforcing a measure of equivalence down to the value type level will require that all | + | *Enforcing a measure of equivalence down to the value type level will require that all fields in the class also override the .Equals method, lest the [[Law of Demeter|Law of demeter]] be broken. |
Latest revision as of 00:17, 21 October 2010
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 (except in the constructor).
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)
- "Only write getters and setters as needed" concurs with the "You ain't gonna need it"-principle as stated by Ron Jeffries --Dom 04:09, 5 August 2008 (UTC)
- I would argue that there are merits to both approaches, and my ideal set of guidelines would be:
- All fields are protected.
- Write a getter only when needed. ("You ain't gonna need it")
- Write setters as needed, but if you need one, seriously consider whether you have a Data class smell, or are disobeying Tell, don't ask
- External: Access to fields with getters and setters
- Internal: Access to fields directly, if in same object (see above)
- Getters should be read-only
- --Lukas Korsika 00:16, 21 October 2010 (UTC)
- I would argue that there are merits to both approaches, and my ideal set of guidelines would be:
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)
- How about ICanMove ;-) --Lukas Korsika 00:17, 21 October 2010 (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. Naïve use of an .Equals method could cause the client much grief.
- Enforcing a measure of equivalence down to the value type level will require that all fields in the class also override the .Equals method, lest the Law of demeter be broken.