- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
You could use a data breakpoint.
Admin
I must admit: I am gulty of doing something very simmilar a couple of years back. But hey, we are here to learn.
One thing I did not see mentioned is that in C# it it not possible to use properties as out parameters. WTF? Yeah, right.
I am currently on a project where there are a lot of methods that have a zillion out parameters. I didn't design those interfaces so don't blame me. I just have to grin an bear it.
Usally the out params of such a method are somewhat related to one another so there is a good chance they will end up together in one object. If the class of this object has public fields instead of props you can just use them like that:
you get the drift. It saves me from declaring n local variables, it saves me from assembling the result. So I do it that way.
Admin
OK, guys, help me out here because that's a feature I really want to use. Are we talking Visual Studio? Because whenever I try to create a breakpoint, New->Data Breakpoint is grayed out, and only New->Function Breakpoint is available. So help me out here, because Google comes back with a lot of Microsoft MVPs that says "Data breakpoints are not supported by C# at this time".
Admin
on another note: In an oo world some people think that "Getters and Setters are Evil" (http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html?page=1).
And hiding the access to some private data behind a property is like putting up a sign "Do not enter. You might see stuff that really interests you."
my favorite class gets all of its state in the constructor and offers me methods. I don't want to know how the stuf works.
Admin
Admin
Never ever ever show any raw variable from the inside of an interface. People directly accessing properties makes it difficult to change those properties later, and makes it impossible to override the properties with a new class that inherits from the old class.
And you will be 100% stuck with the implementation if you ever published this interface as a library that outside people use.
It is idiotic that object oriented languages don't insist that every interface be completely opaque.
I even make all my C interfaces completely opaque. When you make a new string in my c classes you get a handle that you have to use accessors on in order to access the data.
What if later you need to retrieve that property from a database instead of a integer? What if you change how you are storing the value? What if you want to override the accessor functions in a new class? What if you want to send additional messages when that field changes?
An example of this was a string class I had to work with a few years ago. The class exposed the members of the struct outside the interface. So when I changed the way memory was allocated in the string class I had to track down everywhere that let code mess with the inside of the class and pull the data processing of that class member back inside the class.
A properly opaque interface would have enforced the need to make sure that all the string processing that was happening was going on side the string class and not spread out in 200 places. Yes, string processing was literally being done in different 200 places, with code that was subtly different in every place.
Admin
In modern Perl, you use Moose to handle properties. For example, this declares an integer property called "x" that's readable and writable:
Admin
Also if you leave it with semantics equivalent to a public field, you have explicitly exposed the internal member. So when someone looks at the code later, they can infer that the original coder intended to expose it that way.
Admin
That is just asinine, every time you code something like that, its one more thing the programmer has to remember when they use the class. As the project gets larger and larger, there will be more and more things to keep track of.
Preventing people from doing stupid things is a secondary effect of data hiding; the primary effect is to help manage complexity.
your "we're all adults here" philosophy is off. Adults should be responsible. In this case it means making your code robust, and knowing your limitations. I.e. trusting that people not to do stupid things, doesn't help is someone makes a mistake, people can and will fuck up.
Admin
Admin
{/n#^.9/\a.#2/[]1.v&^.@[/.z]*6.};
Admin
Sorry, but there are just too many irresponsible programmers out there. Those who are responsible need to protect the product as much as we are able.
Admin
amen!
Every character in the source code should be there for a good reason and the source code should be readable. Build good code for the present, never code for a nebulous future and never code for the past.
One good reason for getters/setters may be so that you can grep through it and quickly find the meaningful fields of a class. I tend not to prefer them, but it helps to know your audience.
Admin
OK, guys, help me out here because that's a feature I really want to use. Are we talking Visual Studio? Because whenever I try to create a breakpoint, New->Data Breakpoint is grayed out, and only New->Function Breakpoint is available. So help me out here, because Google comes back with a lot of Microsoft MVPs that says "Data breakpoints are not supported by C# at this time".</quote> I did it by clicking on the border are to the left of the member var which created the breakpoint; then right clicking on the breakpoint itself to edit properties. This was in VS 2005 SP1.
Admin
Admin
Getter and setter in perl? Put this in a base class and perl has getters and setters automatically. Its dangerous, because it would work with mispellings, but life isn't a safe thing.
sub AUTOLOAD { my $self = shift; my $sub_call = $AUTOLOAD; if( $sub_call =~ /^get_(.)/ ) { my $field = $1; return $self->{$field}; } elsif( $sub_call =~ /^set_(.)/ ) { my $val = shift; $self->{$field} = $val; } }
Admin
Admin
Eh, while they have their place, I've often seen use of get/set functions as a form of over design or premature generalization. Making code more complex under the theory that said complexity will make other changes simpler IF they get requested later on. On the other hand, the increased complexity can be a problem for the whole lifespan of the project. You've just replaced a single line of code with nearly a dozen lines. That is 12 times as many places where a typo or a cut/copy/paste error can creep in, 12 times as much screen space used up making the class harder to visually scan.
Admin
Oh dear, what a load of nonsense. I might forgive you for using CString as the string type rather than std::string - there can sometimes be good reasons to use CString. And I might forgive you for making the function name begin with an uppercase letter as that is style.
The other issues are more problematic.
Firstly you did not make the Get function const. This means that other const-correct problems will occur later on in the code, for example, if someone has a const reference or pointer to your class they cannot call GetName() which means they'll probably fix it by using a non-const reference or pointer (I have enough experience to know they'll do that). Which will cause other lack of const-correctness all over the project.
Secondly your GetName() returns by value not const reference. In this case where it is inlined and where m_name appears clearly in the header, there is no reason to not use the more efficient option.
By the way, if you think it might upset calling code if a subsequent implementation change caused you to change it to return by value, it would not. If the calling function binds it to a const reference that is fine as you can do that with a temporary.
Finally your nonsensical comment about someone changing the implementation by inheriting from it... sorry but your Get and Set functions are non-virtual. I assume that the person who inherits from your class is not going to change your own header.
There are reasons outlined in the responses already why having the methods is advantageous - particularly the Set() method, and then only if you want users to be able to set the value directly. And there is no way to make a member externally readable but not writable. (Actually there is but it's a bit of a hack. Make it a const reference to a private member!).
As for actual encapsulation, that is best done (in C++) with a pImpl or abstract base classes, not with private data members (other than a private pImpl). (And in Java use interfaces for encapsulation).
Admin
Ok, the real WTF: doing anything (use of getters and setters, refusal to use getters and setters) because that's the way you've always done it is the problem.
And the reason why you've always done it that way is that you were taught by someone who thinks that C is the ultimate language and never became comfortable with objects as anything other than a good old C struct holding a bunch of data that's used by code in a dozen different places.
People who do this are the same ones who try to write functional code with mutable data and bolt static typing onto duck-typed languages. It never works, but they keep on trying to do things the way they've always done it, no matter how different the language may be.
This also explains why we need static typing and compilers - if you change the data type of a "property", you then get code in 50 different classes and only the compiler can hope to catch most of the bugs that will be introduced, and even then implicit casting will let a few get through. And unless you understand that Python is very very different to C, your efforts to write C code in Python will end in tears.
Admin
Admin
Admin
So... apart from Shambo and Jason, nobody has a problem with the "jump-to-another-page inside a property-get" design?
And you guys look down on PHP coders. Hmm.....
Admin
I've a sneaky feeling the .Net compiler converts all properties into function calls for compatibility with (potential) .Net languages that can't directly handle properties. MyProp { get; set } is made available as a property called MyProp and two functions called "getMyProp() and setMyProp()".
That's another reason to use properties to avoid refactoring afetr introducing them.
Admin
languages without implicit accessors/mutators, which allow you to create your own explicit accessors/mutators later, without any refactoring, suck.
Admin
Oh joy, the timeless getter setter debate.
After many arguments with myself, I have concluded that have public getters for every field is bad if it doesn't let you hide the type of the member. If you have a property called ID, declared as an int, and later you change it to long, the change ripples out to whomever is using that property. Either encapsulate ID into its own class, with behavior, or have the getter return a string.
As far as setters, setters are OK if, again, you can hide the type, and the property you are setting can change alone during the lifecycle of the object. Anything else should be via constructors.
That said, following these guidelines can still allow procedural OO to be written, where the work that should be done by the class itself is done outside of it. This is the real problem with Eclipse's "Generate Getters and Setters" option. It is a people problem that can't be solved by any language. However I think these guidelines make it harder for people to make the mistake.
Admin
In Perl, there's always more than one way to give only one answer. So here goes:
(1) The Way Of Ancient Wisdom. Use Tie. This is the simplest way yet found to implement self-harm in a programming language. (2) The Junior Space Cadet Way. Use Class::Accessor. I guess if you got your design wrong the first time, or in other words you're writing programs in Perl, then this is the way to go. (3) The Senior Space Cadet Way. Use Class::Data::Accessor. Naturally, this incorporates the Junior Space Cadet Way, but it adds inheritance. Jamie Z's aphorism is applicable throughout Perl. (4) The Tin Foil Hat Way (as mentioned above). Use one of Perl's many "Oh fuck it ain't there" mechanisms. Personally I prefer a naked random redirect to a new page, which might at least be constructed in a language that isn't Perl. (5) ... Well, five. I can do no better than to repeat the Canonical Perl Way Of Oneness:
And then there's (6) There is No Sixth One Way.Except in Perl, where (6) is the Pink Fairy Way. Just forget about accessors entirely. My language specifically invites you to touch my privates. But if you try to do so, I know where you live. I'll come round and rip yours off.
That's the Spirit of Free Software, in a nut. Or two, if you're not Hitler.
Admin
First ever post and captcha is saluto
Part of OO I was taught is to tell don't ask. Compare fields internally within methods/derived properties rather then reference public properties as code is more extensible that way
Admin
Don't try the pontifex on us, matey. Actual facts and/or logic belong on sites like www.dummies-guide-to-partial-template-template-instantiation-programming.com, or at least in colleges that don't teach CompSci in hawk spit Java. (I wonder if they still teach J2EE? Maybe that's just in Metaphysics 101.)
No, here we just deal in Pointless Vilification and Bad Humor. ("Hello, Ma'am; I'm the Bad Humor Man. May I shit on your doorstep today?") We'd also like Sex and Drugs, but, frankly, who would give them to us?
BTW I agreed with everything you said.
Admin
Obviously you didn't get the point of encapsulation - it's futureproofing the interface of the class. So you can change the internal implementation of the class (data structures, validation, etc) without breaking the interface.
It's really freaking handy if you want to do something like switch to lazy initialisation of variables without worrying about the impact on someone else's code directly meddling with the internal state of the classes.
Admin
Thats exactly what it does. Each of those little get/set delegates is already a function. The 'get' even requires a return statement. How cute.
If you don't want to 'promote' a field to a property at a later date and risk breaking all external assemblies which depend on that code, you should encapsulate your fields in properties.
If the dependant assembly was written in C#, or another language supporting properties, it would just need to be recompiled. If it was written in J# or MSC++, some major refactoring would need to take place. Whoops!
Admin
Hey, wait now. There's a difference between "expose variables that legitimately make up part of the external interface as public rather than use getters and setters" and "expose the internal workings of the class as public variables".
If for some reason I was creating my own String class, legitimate parts of the external interface would include the length of the string and some way to get the individual characters in and out. Anything related to how memory is allocated and how the string is stored internally are implementation details that should be invisible to callers. So even as an advocate of the "feel free to use public fields" school, I'd think the only legitimate public field in a String class would be the length. The contents of the string should be accessed through functions because the method of storing them is an implementation detail. Any other data should be completely invisible to the outside world because it's all implementation detail.
I think this is an example of a little rule of thumb I have: The fact that somebody used X to do something stupid does not of itself make X a bad thing. The question is not, Is it possible to hurt yourself if you abuse this tool? The question is, Is it possible to help yourself if you use this tool properly? Yes, some tools have higher potential for abuse, and so should be used carefully and avoided when better alternatives are available. But just because some idiot tried to use his electric sander to scratch his poison ivy and injured himself, doesn't mean that I believe that electric sanders should be banned.
Admin
^ ^
#1 reason
This article made me feugiat what I was going to do next.
Admin
Admin
If I unterstand you correctly, you do essentially this:
How is that any better than this:
Or perhaps you meant the new "automagic" getter and setter overloaders:
But once again, how is that any better than:
If I understood correctly, and you use the variation of "A_Color", I believe you have fallen for a "Anti-Pattern".
The obvious drawbacks of variation "A_Color":
But then again, maybe I interpreted your comment entirely wrong and you meant something else ;-)
Admin
They're talking out of their arses. You can't do that with C#. If they didn't have reading comprehension problems, they would have gleaned that already from my previous comments. :)
Admin
Oh, and by "they" I mean the dicks who think they know how to use Visual Studio to set conditional breakpoints when debugging Visual C#.
Admin
And yes, I'm Mr Grumpy today. ;)
Admin
C-C-C-COMBOBREAKER'ing your monolog ;-P
Admin
And you are sure changing the type of a filed won't break any code that uses it?
Other reason for get/set :
Admin
Never, ever do this.
Admin
Admin
Admin
Admin
Thought it would never come up ;)
+1
Admin
Many comments here say that the setter allows the module to protect itself from that stupid other programmer. Let me add that the stupid other programmer is ME, two years down the road when I forgot the detailed restrictions on the field.
Admin
at last, someone pointed out TRWTF. public get and set are most of time not necessary and they break encapsulation as well.
You should tell the object to do something and ask information about the object to do something with it.
As a exercise left to the readers : try to right your next project without public get and set in your API (you can use protected get/set method).
Admin
Well, if other people are going to be using your code/class, then the general approach to public fields should be that once you 'publish' a field, then it might be very hard for you to change any usage afterwards.
In effect, you should make it a public field only if you really are 99% sure that it will not change; since there could (and very often will be) some code that you don't see that uses this public field, and that this change will break.
Although the change there will be trivial to you, it won't be trivial to them, they will only see that the compile fails, and not care - so, instead of changing their code, they'll just stick to the previous version that worked. And of course, some time later some bugs will be fixed in your version of the class, but still remain in the version that is used in their code... A WTF-scenario, but such things really do happen. So just do NOT ever make public any fields/features if you are not commited to make this as 'carved-in-stone agreed interface that will stay that way'.
Think of stuff like windows-3.11 compatibility function calls that still somehow persist in windows Vista...
Admin
You can, and you should but you need to make sure that you have a worst case scenario covered and that you know what you're doing.
If you are using a thirst part framework or someone else's code, the worst thing you can do is to trust it not to scr*w you over. You need to look into it to make sure it doesn't do something stupid like issue a redirect. Or that you allow people to write code that access DB code straight from the JSP. It makes thing flexible, but it makes it unmanageable.
Admin
For anyone who uses getters/setters and doesn't know why:
The reason people had been taught to use getters and setters instead of public variables is because, at the time, that was necessary to provide a stable unchanging API in case later on you wanted to change the getting/setting to do something more than just trivial member access. But with modern languages that support accessors, that practice has (for the most part) become rendered an ugly and unnecessary kludge, since you can now add extra processing while maintaining variable-access syntax (which is a far more sensible syntax for "setting" and "getting" values anyway).
The only snag though is that this can sometimes cause problems when the value being accessed is a non-trivial value type:
Of course, even this snag could be avoided if the language allows return-by-reference (like in D).
The moral of the story: Question everything. Conditions change and reasoning/advice that was once valid may no longer apply.