Talk:Getter and setter policy

From CSSEMediaWiki
(Difference between revisions)
Jump to: navigation, search
(Long winded explanation of why I think Get and Set are the devil.)
Line 18: Line 18:
  
 
Maybe getters/setters should be treated with a [[DBC]]-like perspective. By this, I mean that getters and setters are allowed as long as you make it explicit what they are there for. E.g. if you hava a getName() method, this should have accompanying comments to say that this will get a String in format X that should only be got by classes in particular packages, or should be avoided or something. --[[User:Matthew Harward|Matthew Harward]] 00:30, 29 July 2009 (UTC)
 
Maybe getters/setters should be treated with a [[DBC]]-like perspective. By this, I mean that getters and setters are allowed as long as you make it explicit what they are there for. E.g. if you hava a getName() method, this should have accompanying comments to say that this will get a String in format X that should only be got by classes in particular packages, or should be avoided or something. --[[User:Matthew Harward|Matthew Harward]] 00:30, 29 July 2009 (UTC)
 +
 +
I should probably justify my position a bit further, for those that don't read Allen Holub's article [http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html?page=1] and so others have more avenues to hurl abuse at me. Granted, there are likely to be situations where get/set methods are unavoidable, or where redesigning the class to remove them will introduce excessive complexity that is not easily justified, indeed that would go against [[Keep it simple]]. Treating them in a design by contract fashion seems like a reasonable way to limit the negative effects, provided all other developers adhere to their limitations, but we all know how likely that is going to be when the pressure is on. Ideally, (there is that word again) they should be avoided wherever possible. The get and set methods expose the implementation of the class to other classes. This goes against the [[Law of Demeter]] (minimum knowledge) and encapsulation principles, though I will concede that it depends on the [[Encapsulation boundary]] to some extent. We should all by now understand the maintenance/modification problems that come with exposing internal specifications of objects, remember those countless hours spent chasing bugs around a 325 project just because you wanted a string instead of an int. At the basic level get and set methods merely make a private field public, it is the same as locking your front door then entirely removing the back door and installing a large neon sign pointing to the rear of the house saying "entrance here". Certainly you could include validation in your setter method to control modification, in fact to be safe you probably should as well as including a boolean return and/or try-catch. However, that starts (in my opinnon) to blur the setter method into something that is closer to completely dealing with whatever task it is connected to anyway, so then why wouldn't you just have that task being managed in that class? Hence, [[Tell, Don't Ask]]. 'Get' could be argued as being reasonably safe, since it is not modifying the data, but it is still exposing the implementation. The favoured course of action seems to be to use an Interface object to raise the level of abstraction away from the class, allowing any modification you like. Presumably this approach also has drawbacks. I think the concept of each object knowing how to do its job and only its job, rather than having other objects do the work for it, fits well with OO. Mind you, last week I thought get and set were reasonably valid too. Perhaps I am just easily swayed. Holy crap this is a long statement. --[[User:Douglas Wall|Douglas]] 02:13, 29 July 2009 (UTC)

Revision as of 02:13, 29 July 2009

Don't tell me everyone agrees where is the fun in that?

I just have to completely agree with the first paragraph. I also try to always use this->FunctionName() to make the difference between internal and external function calls clear. Python, for instance, enforces such a syntax ( self.FunctionName() ). --TobiW

Very nice little style guide there, I would back that 100% --AlexGee 02:09, 28 July 2009 (UTC)

If the object has to call its getters and settings to change its own variables then changes to the variables internally would be subjected to the same constraints as calls through the public interface. This also would mean that internal calls would always have the same constraints as public calls. Would you want this? I mean might there be exceptions to this rule? --BenMcDonald 06:44, 28 July 2009 (UTC)

Sure there would be exceptions for example dealing with a collection. Thus I used 'ideally' --AlexGee 09:45, 28 July 2009 (UTC)

I know it would not be very nice design, but there is nothing stopping a developer from adding additional functionality to a getter/setter. If we want to stop that from happening, possibly this should also be included in the policy. Related to Command query separation. --Matthew Harward 21:04, 28 July 2009 (UTC)

After some research, my current opinion is: -"Objects should store all their data in private variables": Yes, this maintains encapsulation. -"Getter and setter methods should be produced for any variable you might have been tempted to declare public": HELL NO. This is wrong. Getter and setter = BAD. This breaks the concept of Tell, Don't Ask, the Law of Demeter, encapsulation and possibly (as Matthew has indicated) Command query separation in certain situations. Read this document: [1] to gain a better understanding of why it is wrong to use getter and setter methods. -"Classes should ideally call their own getter and setters when accessing their internal data": Yes, but only when you can't avoid using the Satanic getters and setters in the first place. Also, the get/set methods should comply with Command query separation. -- Douglas

Ok, having read the article, it does make a good point. However, please consider, the suggestions made by you and in the article may break the Behavioral completeness maxim. This may be an acceptable compromise. --Matthew Harward 00:26, 29 July 2009 (UTC)
I am not sure that it breaks the Behavioural completeness maxim, from my understanding it would actually support it. To use the truck suspension example, the wheel object can pass the force data to the axle object by saying: "here are some forces, deal with them", which places the responsibility for the behaviour task with the axle, which in real life (when massively simplified) is what happens. If I have misunderstood this principle please correct me. --Douglas 01:55, 29 July 2009 (UTC)

Maybe getters/setters should be treated with a DBC-like perspective. By this, I mean that getters and setters are allowed as long as you make it explicit what they are there for. E.g. if you hava a getName() method, this should have accompanying comments to say that this will get a String in format X that should only be got by classes in particular packages, or should be avoided or something. --Matthew Harward 00:30, 29 July 2009 (UTC)

I should probably justify my position a bit further, for those that don't read Allen Holub's article [2] and so others have more avenues to hurl abuse at me. Granted, there are likely to be situations where get/set methods are unavoidable, or where redesigning the class to remove them will introduce excessive complexity that is not easily justified, indeed that would go against Keep it simple. Treating them in a design by contract fashion seems like a reasonable way to limit the negative effects, provided all other developers adhere to their limitations, but we all know how likely that is going to be when the pressure is on. Ideally, (there is that word again) they should be avoided wherever possible. The get and set methods expose the implementation of the class to other classes. This goes against the Law of Demeter (minimum knowledge) and encapsulation principles, though I will concede that it depends on the Encapsulation boundary to some extent. We should all by now understand the maintenance/modification problems that come with exposing internal specifications of objects, remember those countless hours spent chasing bugs around a 325 project just because you wanted a string instead of an int. At the basic level get and set methods merely make a private field public, it is the same as locking your front door then entirely removing the back door and installing a large neon sign pointing to the rear of the house saying "entrance here". Certainly you could include validation in your setter method to control modification, in fact to be safe you probably should as well as including a boolean return and/or try-catch. However, that starts (in my opinnon) to blur the setter method into something that is closer to completely dealing with whatever task it is connected to anyway, so then why wouldn't you just have that task being managed in that class? Hence, Tell, Don't Ask. 'Get' could be argued as being reasonably safe, since it is not modifying the data, but it is still exposing the implementation. The favoured course of action seems to be to use an Interface object to raise the level of abstraction away from the class, allowing any modification you like. Presumably this approach also has drawbacks. I think the concept of each object knowing how to do its job and only its job, rather than having other objects do the work for it, fits well with OO. Mind you, last week I thought get and set were reasonably valid too. Perhaps I am just easily swayed. Holy crap this is a long statement. --Douglas 02:13, 29 July 2009 (UTC)

Personal tools