Talk:Hall of fame
BenMcDonald (Talk | contribs) |
|||
(24 intermediate revisions by 5 users not shown) | |||
Line 5: | Line 5: | ||
:Because information hiding is the foundation to reuse if someone using your class needs to know it's internal workings not just the interface then the class does not have [[Behavioral_completeness|behavioural completeness]]. --[[User:AlexGee|AlexGee]] 03:32, 24 July 2009 (UTC) | :Because information hiding is the foundation to reuse if someone using your class needs to know it's internal workings not just the interface then the class does not have [[Behavioral_completeness|behavioural completeness]]. --[[User:AlexGee|AlexGee]] 03:32, 24 July 2009 (UTC) | ||
− | :Of course you can always break the laws, even the inviolable ones. You can use gotos, but it is ''considered harmful''. I think the same applies to information hiding: you can make all your attributes public, but I'd consider that harmful too. Maybe it's clearer when you replace 'inviolable' with 'not justifiable'? | + | :Of course you can always break the laws, even the inviolable ones. You can use gotos, but it is ''considered harmful''. I think the same applies to information hiding: you can make all your attributes public, but I'd consider that harmful too. Maybe it's clearer when you replace 'inviolable' with 'not justifiable'? --[[User:TobiW|TobiW]] |
+ | |||
+ | :There is an old joke, a man comes up to a stop light, but instead of fully stopping he keeps driving. I passing cop sees his antics and pulls him over. The cop explains to the man that he needed to stop, but the man claimed, "but I slowed right down." To this, the cop asked the man to get out of the car, he pulls out his truncheon and begins beating the man. The cop then asks the man: "Would you like me to slow down or stop?" I think that this sort of analogy applies in this situation. The term inviolable is equivalent to forbidden, not ''considered harmful''. I would agree that [[Information hiding]] is very important, but it is not unquestionable. Maxims such as [[You ain't gonna need it]], [[Premature optimization]] and [[Once and only once]] have the potential to be violated by this concept. In essence, I draw your attention to [[No silver bullet]]. Sure, IH is very important, but there are times when other factors may conspire to make it the logically less attractive choice... Or am I just shaking the coconut palm? --[[User:Matthew Harward|Matthew Harward]] 10:48, 28 July 2009 (UTC) | ||
+ | |||
+ | :Hmm, I think that information hiding is probably better of in the "most excellent ideas section" rather than the inviolable laws section as well. I see your point Matthew about how some other principles could potentially conflict with information hiding but I think that information hiding is hugely fundamental because following it provides a large number of related benefits (e.g. lower coupling, better modifiability) that I think it would still be logically highly attractive even when looking at the other maxims you brought up. --[[User:Janina Voigt|Janina]] | ||
+ | |||
+ | ---- | ||
+ | |||
+ | [[Command query separation ]] - I’ve added Command query separation to ‘Most excellent ideas’ to sit beside Design by contract. An exception would be a stack. -[[User:BenMcDonald|BenMcDonald]] 12:01, 28 July 2009 (UTC) | ||
+ | |||
+ | : Sounds good to me! --[[User:Matthew Harward|Matthew Harward]] 20:57, 28 July 2009 (UTC) | ||
+ | |||
+ | : I changed my mind and moved [[Command query separation ]] to Inviolable laws. I think a stack should have a query to look at the top object, even if another method(command) removes and retrieves it. This is because if you have an immutable object, like a returned attribute of an object, then you can only perform queries on it. If queries have not been separated then immutable objects become useless and immutable object should be very useful not useless. Which segways into my next maxim placement of Don't expose mutable attributes as an Inviolable laws. --[[User:BenMcDonald|BenMcDonald]] 12:30, 6 October 2009 (UTC) | ||
+ | |||
+ | : I agree that this law is important, but as I read it, this law applies to any command/query applied to an object. This law seems to suggest that, as command and query are separate, that either the calling object should be responsible for keeping the object in a valid state or the we are going to duplicate functionality, breaking DRY. For example, | ||
+ | String theString; | ||
+ | boolean isValid(String testString) { //<--Query | ||
+ | return list.contains(testString); | ||
+ | } | ||
+ | |||
+ | boolean void setString(String newString) { //<-- Command | ||
+ | if (isValid(newString)) // We want a class to control its data | ||
+ | theString = newString; | ||
+ | } | ||
+ | |||
+ | :We have followed the CQS... Yet when we call this it seems counter intuitive... as our calling would proceed as follows... | ||
+ | |||
+ | if(obj.isValid(myString)) //We want to be able to discover if an operation will/has worked... | ||
+ | obj.setString(myString); | ||
+ | |||
+ | :We seem to be repeating ourselves. What am I missing? I know this a VERY contrived example. --[[User:Matthew Harward|Matthew Harward]] 04:22, 8 October 2009 (UTC) | ||
+ | |||
+ | |||
+ | :Well I went back over what I said and CQS is more rigorous than I thought it was. I was advocating “always having an object queryable”, like the peek() method in a stack, which is not quite CQS. It turns out that Martin Fowler has said what I wanted to say and better http://martinfowler.com/bliki/CommandQuerySeparation.html. | ||
+ | |||
+ | :He muses on the idea of a language enforcing this and then remembers C++ “The only case I've really come across it is the const modifier in C++. Since I haven't used C++ for many years it's hard for me to assess how useful it is in practice. My sense is that C++ers use const a lot and like it.” | ||
+ | |||
+ | :Yes and yes, a const modifier is very helpful. | ||
+ | |||
+ | :“This is because you can use queries in many situations with much more confidence, introducing them anywhere, changing their order. You have to be more careful with modifiers.” | ||
+ | |||
+ | :But I was thinking more about immutability. | ||
+ | |||
+ | :I think in your code examples you are getting more into DBC and so my answer is 'I have no idea'. | ||
+ | |||
+ | :--[[User:BenMcDonald|BenMcDonald]] 00:58, 9 October 2009 (UTC) | ||
+ | |||
+ | ---- | ||
+ | |||
+ | [[Behavioral completeness]] - The article [http://heim.ifi.uio.no/~trygver/2009/dci_vision.html A New Vision of Object-Oriented Programming] reminded me of behaviour completeness when it talked about objects being about human understanding. Software quickly becomes very complex and maintaining an understanding of the software is important. I find behaviour completeness of objects is always important when trying to get my head around code. | ||
+ | It is easy, although, to find tempting departures from this rule. Like the example in class where a 'Frog' can save itself in XML. --[[User:BenMcDonald|BenMcDonald]] 15:54, 25 August 2009 (UTC) | ||
+ | |||
+ | :So just to clarify, the frog having the ability to save itself to XML is ''not'' behaviourally complete, right? --[[User:Matthew Harward|Matthew Harward]] 02:29, 26 August 2009 (UTC) | ||
+ | |||
+ | :Yeah. That was an example of an object not being behaviourally complete. I don't know if it's justified. We also discussed in class changing the design to include a visitor pattern so that the Frog object could retain behavioural completeness. --[[User:BenMcDonald|BenMcDonald]] 03:24, 26 August 2009 (UTC) | ||
+ | |||
+ | ---- | ||
+ | |||
+ | [[Keep it simple]] is conceptually very similar to [[Don't repeat yourself]]... Maybe their should be a closer in terms of status on this page? --[[User:Matthew Harward|Matthew Harward]] 02:29, 10 September 2009 (UTC) | ||
+ | |||
+ | :The interesting thing about DRY as an inviolable law is that this is a really strict rule to follow. As the authors of the rule say, it's not just code but things such as data schemas. So to have a single authority on each piece of data requires "code generation tools, automatic build systems, and scripting languages". Maybe we need to be this strict and do this but I know that I currently don't. --[[User:BenMcDonald|BenMcDonald]] 12:49, 6 October 2009 (UTC) | ||
+ | |||
+ | : That is fair enough. I would say that DRY should be an ultimate goal, but [[Keep it simple]] really should trump it. I would say that my belief on the importance of DRY is probably something related to Shannon's information theory, if we repeat ourselves then we are duplicating data. The other part, oc, is that DRY means that a change in one place is the only change needed, hence vastly improving maintainability --[[User:Matthew Harward|Matthew Harward]] 04:00, 8 October 2009 (UTC) | ||
+ | |||
+ | :Yes, DRY should be an ultimate goal so that data are maintainable and in sync. Better programming tools will help with this. --[[User:BenMcDonald|BenMcDonald]] 03:12, 9 October 2009 (UTC) | ||
+ | |||
+ | ---- | ||
+ | |||
+ | I think [[Don't expose mutable attributes]] should be moved from "Inviolable laws" to "Most excellent ideas" or even "Helpful ideas". Suppose a class contains a collection of ''Foo'' objects and wants to allow its clients to be able to access items in it. It could create a getter that makes an immutable copy of the collection, but this could be problematic in performance sensitive contexts (this could easily turn an O(n) algorithm into an O(n^2) algorithm, for example - but beware [[Premature optimization]]). Alternatively it could provide additional methods for various functions, such as ''getFooAtIndex(int index)'', ''getIndexOfFoo(Foo f)'', etc. However this adds [[Avoid_interface_pollution|interface clutter]] and violates [[One key abstraction]] and [[Keep it simple]]. Other considerations are frameworks such as Cocoa where a mutable array is a subclass of a standard (immutable) array. Is it then OK to return a mutable array in a getter provided the return type is the immutable superclass? Finally, there's a blurry line about what exactly is defined as an attribute. Suppose you have a ''Window'' class which contains a ''View'' object representing the root view in the window's view hierarchy. Does this count as an attribute? If not, what makes it different from a ''Collection'' attribute? If so, should clients have to go through methods in the ''Window'' object to modify the ''View'' object? --[[User:Stephen Fitchett|Stephen Fitchett]] 07:41, 10 October 2009 (UTC) | ||
+ | |||
+ | :The performance sensitive context would be dependent on the limits of the language but in general immutability and other variations like the const keyword not only localise errors but are used to optimise compliers. Of course compiler optimisation does nothing for time complexity but if a language didn’t let you specify immutably without deep coping the object then you would have a problem. I can also point out that some even think that deep coping is worth the cost as in Google’s new language they are proposing enforcing deep coping as “Proper object oriented programming must isolate and protect state” http://code.google.com/p/noop/wiki/ProposalForSafeDeepCopy. | ||
+ | |||
+ | :An attribute defines an object’s state. The point of the rule is to enforce what Riel says here [[Do not change the state of an object without going through its public interface]]. If an object returns mutable access to one of its attributes, a definer of its state, then the object gives away control over its own state. | ||
+ | |||
+ | :In the case of the collection, it would not help much to limit control to the objects inside as without deep copying there is mutable access from whatever scope they were passed in from in the beginning. It could be argued that changing the objects in a collection does not change that collection’s state. All the collection knows is that it has x objects of y type and that will not change except through its public interface. | ||
+ | |||
+ | :In your post you seemed to have missed any advantage that there is in limiting mutable access to attributes and there are many and it’s too big of a topic to cover. I cannot image all the implications of this rule and if we do find exceptions then an alternative should at least be “''Attempt'' to not change the state of an object without going through its public interface”. --[[User:BenMcDonald|BenMcDonald]] 21:32, 10 October 2009 (UTC) | ||
+ | |||
+ | ::I'm definitely not arguing that the maxim is a bad idea; it's a great idea which should be used whenever possible. I'm just pointing out that there are some cases where it might conflict with other ideas and that's it's not inviolable. If it's just a matter of marking something as ''const'', that's simple enough, but if you have a language like Java and you've written your own state classes, then you typically have a choice of a) adding extra public methods to the owner class to access the state object's properties, b) having a way to create a read-only wrapper object (like Collections.unmodifiableList in Java) which shares the same interface as the original and therefore has potential [[Design by contract]] issues or c) having a way to create a read-only wrapper object with a different interface (ie a subset of the original) which leads to a larger class hierarchy that makes the system harder to understand (especially if there are a lot of different state classes). In these cases the disadvantages of these approaches need to be balanced against the benefits of the maxim. --[[User:Stephen Fitchett|Stephen Fitchett]] 02:05, 11 October 2009 (UTC) | ||
+ | ::I've moved it to "Most excellent ideas" pending further discussion. --[[User:Stephen Fitchett|Stephen Fitchett]] 23:36, 13 October 2009 (UTC) | ||
+ | |||
+ | ::: That's fine with me. The only thing I have to add is that the hall of fame should be logically consistent. What maxims imply(=>) what other maxims. Does [[Design by contract]] => [[Do not change the state of an object without going through its public interface]] => [[Don't expose mutable attributes]]? If that is the case then DBC could not be any more favoured than any maxims that it implies. --[[User:BenMcDonald|BenMcDonald]] |
Latest revision as of 02:16, 14 October 2009
What is the rationale of Information hiding being an inviolable law? Why can there NEVER be a case when this can be broken? --Matthew Harward 09:37, 23 July 2009 (UTC)
- Oooo that's a really interesting question. How important is info hiding anyway? What was it about info hiding that led to its nomination as inviolable? --Wal 00:32, 24 July 2009 (UTC)
- Because information hiding is the foundation to reuse if someone using your class needs to know it's internal workings not just the interface then the class does not have behavioural completeness. --AlexGee 03:32, 24 July 2009 (UTC)
- Of course you can always break the laws, even the inviolable ones. You can use gotos, but it is considered harmful. I think the same applies to information hiding: you can make all your attributes public, but I'd consider that harmful too. Maybe it's clearer when you replace 'inviolable' with 'not justifiable'? --TobiW
- There is an old joke, a man comes up to a stop light, but instead of fully stopping he keeps driving. I passing cop sees his antics and pulls him over. The cop explains to the man that he needed to stop, but the man claimed, "but I slowed right down." To this, the cop asked the man to get out of the car, he pulls out his truncheon and begins beating the man. The cop then asks the man: "Would you like me to slow down or stop?" I think that this sort of analogy applies in this situation. The term inviolable is equivalent to forbidden, not considered harmful. I would agree that Information hiding is very important, but it is not unquestionable. Maxims such as You ain't gonna need it, Premature optimization and Once and only once have the potential to be violated by this concept. In essence, I draw your attention to No silver bullet. Sure, IH is very important, but there are times when other factors may conspire to make it the logically less attractive choice... Or am I just shaking the coconut palm? --Matthew Harward 10:48, 28 July 2009 (UTC)
- Hmm, I think that information hiding is probably better of in the "most excellent ideas section" rather than the inviolable laws section as well. I see your point Matthew about how some other principles could potentially conflict with information hiding but I think that information hiding is hugely fundamental because following it provides a large number of related benefits (e.g. lower coupling, better modifiability) that I think it would still be logically highly attractive even when looking at the other maxims you brought up. --Janina
Command query separation - I’ve added Command query separation to ‘Most excellent ideas’ to sit beside Design by contract. An exception would be a stack. -BenMcDonald 12:01, 28 July 2009 (UTC)
- Sounds good to me! --Matthew Harward 20:57, 28 July 2009 (UTC)
- I changed my mind and moved Command query separation to Inviolable laws. I think a stack should have a query to look at the top object, even if another method(command) removes and retrieves it. This is because if you have an immutable object, like a returned attribute of an object, then you can only perform queries on it. If queries have not been separated then immutable objects become useless and immutable object should be very useful not useless. Which segways into my next maxim placement of Don't expose mutable attributes as an Inviolable laws. --BenMcDonald 12:30, 6 October 2009 (UTC)
- I agree that this law is important, but as I read it, this law applies to any command/query applied to an object. This law seems to suggest that, as command and query are separate, that either the calling object should be responsible for keeping the object in a valid state or the we are going to duplicate functionality, breaking DRY. For example,
String theString; boolean isValid(String testString) { //<--Query return list.contains(testString); } boolean void setString(String newString) { //<-- Command if (isValid(newString)) // We want a class to control its data theString = newString; }
- We have followed the CQS... Yet when we call this it seems counter intuitive... as our calling would proceed as follows...
if(obj.isValid(myString)) //We want to be able to discover if an operation will/has worked... obj.setString(myString);
- We seem to be repeating ourselves. What am I missing? I know this a VERY contrived example. --Matthew Harward 04:22, 8 October 2009 (UTC)
- Well I went back over what I said and CQS is more rigorous than I thought it was. I was advocating “always having an object queryable”, like the peek() method in a stack, which is not quite CQS. It turns out that Martin Fowler has said what I wanted to say and better http://martinfowler.com/bliki/CommandQuerySeparation.html.
- He muses on the idea of a language enforcing this and then remembers C++ “The only case I've really come across it is the const modifier in C++. Since I haven't used C++ for many years it's hard for me to assess how useful it is in practice. My sense is that C++ers use const a lot and like it.”
- Yes and yes, a const modifier is very helpful.
- “This is because you can use queries in many situations with much more confidence, introducing them anywhere, changing their order. You have to be more careful with modifiers.”
- But I was thinking more about immutability.
- I think in your code examples you are getting more into DBC and so my answer is 'I have no idea'.
- --BenMcDonald 00:58, 9 October 2009 (UTC)
Behavioral completeness - The article A New Vision of Object-Oriented Programming reminded me of behaviour completeness when it talked about objects being about human understanding. Software quickly becomes very complex and maintaining an understanding of the software is important. I find behaviour completeness of objects is always important when trying to get my head around code. It is easy, although, to find tempting departures from this rule. Like the example in class where a 'Frog' can save itself in XML. --BenMcDonald 15:54, 25 August 2009 (UTC)
- So just to clarify, the frog having the ability to save itself to XML is not behaviourally complete, right? --Matthew Harward 02:29, 26 August 2009 (UTC)
- Yeah. That was an example of an object not being behaviourally complete. I don't know if it's justified. We also discussed in class changing the design to include a visitor pattern so that the Frog object could retain behavioural completeness. --BenMcDonald 03:24, 26 August 2009 (UTC)
Keep it simple is conceptually very similar to Don't repeat yourself... Maybe their should be a closer in terms of status on this page? --Matthew Harward 02:29, 10 September 2009 (UTC)
- The interesting thing about DRY as an inviolable law is that this is a really strict rule to follow. As the authors of the rule say, it's not just code but things such as data schemas. So to have a single authority on each piece of data requires "code generation tools, automatic build systems, and scripting languages". Maybe we need to be this strict and do this but I know that I currently don't. --BenMcDonald 12:49, 6 October 2009 (UTC)
- That is fair enough. I would say that DRY should be an ultimate goal, but Keep it simple really should trump it. I would say that my belief on the importance of DRY is probably something related to Shannon's information theory, if we repeat ourselves then we are duplicating data. The other part, oc, is that DRY means that a change in one place is the only change needed, hence vastly improving maintainability --Matthew Harward 04:00, 8 October 2009 (UTC)
- Yes, DRY should be an ultimate goal so that data are maintainable and in sync. Better programming tools will help with this. --BenMcDonald 03:12, 9 October 2009 (UTC)
I think Don't expose mutable attributes should be moved from "Inviolable laws" to "Most excellent ideas" or even "Helpful ideas". Suppose a class contains a collection of Foo objects and wants to allow its clients to be able to access items in it. It could create a getter that makes an immutable copy of the collection, but this could be problematic in performance sensitive contexts (this could easily turn an O(n) algorithm into an O(n^2) algorithm, for example - but beware Premature optimization). Alternatively it could provide additional methods for various functions, such as getFooAtIndex(int index), getIndexOfFoo(Foo f), etc. However this adds interface clutter and violates One key abstraction and Keep it simple. Other considerations are frameworks such as Cocoa where a mutable array is a subclass of a standard (immutable) array. Is it then OK to return a mutable array in a getter provided the return type is the immutable superclass? Finally, there's a blurry line about what exactly is defined as an attribute. Suppose you have a Window class which contains a View object representing the root view in the window's view hierarchy. Does this count as an attribute? If not, what makes it different from a Collection attribute? If so, should clients have to go through methods in the Window object to modify the View object? --Stephen Fitchett 07:41, 10 October 2009 (UTC)
- The performance sensitive context would be dependent on the limits of the language but in general immutability and other variations like the const keyword not only localise errors but are used to optimise compliers. Of course compiler optimisation does nothing for time complexity but if a language didn’t let you specify immutably without deep coping the object then you would have a problem. I can also point out that some even think that deep coping is worth the cost as in Google’s new language they are proposing enforcing deep coping as “Proper object oriented programming must isolate and protect state” http://code.google.com/p/noop/wiki/ProposalForSafeDeepCopy.
- An attribute defines an object’s state. The point of the rule is to enforce what Riel says here Do not change the state of an object without going through its public interface. If an object returns mutable access to one of its attributes, a definer of its state, then the object gives away control over its own state.
- In the case of the collection, it would not help much to limit control to the objects inside as without deep copying there is mutable access from whatever scope they were passed in from in the beginning. It could be argued that changing the objects in a collection does not change that collection’s state. All the collection knows is that it has x objects of y type and that will not change except through its public interface.
- In your post you seemed to have missed any advantage that there is in limiting mutable access to attributes and there are many and it’s too big of a topic to cover. I cannot image all the implications of this rule and if we do find exceptions then an alternative should at least be “Attempt to not change the state of an object without going through its public interface”. --BenMcDonald 21:32, 10 October 2009 (UTC)
- I'm definitely not arguing that the maxim is a bad idea; it's a great idea which should be used whenever possible. I'm just pointing out that there are some cases where it might conflict with other ideas and that's it's not inviolable. If it's just a matter of marking something as const, that's simple enough, but if you have a language like Java and you've written your own state classes, then you typically have a choice of a) adding extra public methods to the owner class to access the state object's properties, b) having a way to create a read-only wrapper object (like Collections.unmodifiableList in Java) which shares the same interface as the original and therefore has potential Design by contract issues or c) having a way to create a read-only wrapper object with a different interface (ie a subset of the original) which leads to a larger class hierarchy that makes the system harder to understand (especially if there are a lot of different state classes). In these cases the disadvantages of these approaches need to be balanced against the benefits of the maxim. --Stephen Fitchett 02:05, 11 October 2009 (UTC)
- I've moved it to "Most excellent ideas" pending further discussion. --Stephen Fitchett 23:36, 13 October 2009 (UTC)
- That's fine with me. The only thing I have to add is that the hall of fame should be logically consistent. What maxims imply(=>) what other maxims. Does Design by contract => Do not change the state of an object without going through its public interface => Don't expose mutable attributes? If that is the case then DBC could not be any more favoured than any maxims that it implies. --BenMcDonald