Well, anyway, don't use Get:
class Bar { public: const Foo &foo() const { return myFoo; } void setFoo( const Foo &foo ) { myFoo = foo; } private: Foo myFoo; };The accessor does not need "get". It should not have it, either, because we might not be "getting" the result from an instance variable, we might be calculating it on the fly or reading it from somewhere else. Notice that "foo()" is the same length as "myFoo" so even lazy programmers might as well use the function.
The modifier has a "set" to make it stand out. I find modifiers are far less commonly called than accessors so the extra verbaige is rarely incurred. The set function does not return a value. Why should it? If you need it you can call the accessor; a return value would be redundant. And confusing. Does it return the old value or the new? Or "this", as in Smalltalk?
[It was suggested that Set just return a reference and use an Observer to veto changes...]
Using Observer to prevent changes has many problems. One is that it will be called even when the value hasn't changed, if the foo() is called as an accessor on a non-const object. Another is that it acts too late - the value has already changed. To then try to change it back leads to uncertainty and state-changes ricocheting around the program.
[Lastly it can be chained - x.foo().bar().bletch() - which induces violations of the LawOfDemeter]
Discussion:
Day 1: The following may not belong on this page. It maybe should be deleted. I guess that will become clear when (if) the questions it raises get discussed.
Day 2: Well the questions got answered lots of times thanx one and all. I will try to add some of my comments on the comments below.
Day 22-100: Watch this space. I will be back. In hindsight I ahve realised that this was at least partly an experiment to determine the level of religious fervor that is aroused when sacred cows are challenged. I will be back with a whole bunch of challenges to traditional wisdom. CategoryHeretical?.
The earlier version of this page was about what the methods should be called, rather than whether they should be present at all. Suggestions such as TomStambaugh's use of overloading were considered and rejected. During the course of the discussion, people changed their mind and a consensus was achieved. The page was refactored to reflect the consensus. A text-book example of Wiki success!
I think it's clear that too much got deleted. The purpose of the page has been lost, and Tom's proposal has to be considered all over again. Probably, as you suspect, the discussion about whether they are needed at all should be moved elsewhere (actually I'm sure it already exists on Wiki somewhere). I have taken my name off the opening statement because it is communual property; the original refactorer probably felt he ought to give me credit but I should have removed it before. -- DaveHarris
Perhaps This is just Flame bait but I do really want to know. Perhaps I have some kind of hat on but I do just really want to know.
Given the code above what have we really gained by hiding the foo as a private?
Yeah Yeah yeah I know I did the course too.
Give me an example of what can now be changed that cannot be achieved with myFoo as a public variable. Gasp Horror Shock!!!
I will try a few changes for myself.
Change 1. It was said that perhaps we computed foo on the fly rather than just getting it from a member. If this is to be so where is the object that we returned the reference to and who is responsible for its deletion.
Change 2. Perhaps we want to do some semantic checking on foo when set is called? This could be done by deriving a class from Foo called Sematicallycheckedfoo and then over riding its assignment operator. (This argument is probably wooly)
Change 3. We could want to separate the memory footprint of myFoo from the class that it used to be a member of, perhaps myFoo is now to be common to many such objects. Ok so this change would be easier with the interface above unless of course there was possibility of the internal pointer to the shared myFoo being null in which case the foo() function would have trouble returning a valid reference.
Change 4. We could want to have multiple myFoo like objects in say a linked List. They could be for instance the List of strings that we are grepping this file for. The foo() interface will still be a problem because which myFoo will it return? and what will set now do that is semantically similar enough to the old setFoo() that we will not have to go and inspect all uses of setFoo() to check if they are now broken.
So even if Change 2 really is easier with the variable hidden behind functions. Isn't this a violation of DoTheSimplestThingThatCouldPossiblyWork and YouArentGonnaNeedIt
My two dogmatic cents on the above comment: First, DoTheSimplestThingThatCouldPossiblyWork is always relative to the developer's instincts. There are certain habits that have been developed through sheer Pavlovianism: I used public object variables, and it hurt, and I did again, and it hurt again, so now I'm going to stop doing it. Thus, the simplest way to get a dropped object out of a flame might be to just stick in my hand, but I'm going to instinctively drop that out of the list of Things I Might Want To Do, or at least below first dumping a bucket of water on the fuel. Instances of times where this hurt in my own experience include many cases where once stored values become computed-on-the-fly, and where once computed-first variables became lazily-evaluated.
Secondly, to me, the ability to "directly" access the member variables of an object is syntactic sugar provided by many languages, but completely orthogonal to any necessary definition of object-oriented programming. As a matter of fact, when one gets into COM, or RubyLanguage, one finds that one does just fine without this ability to auto-define a simplistic set of accessors sugarly written such as Java's "obj.data = 3". This fact does not alone argue for defining accessor methods, but casts the question in a different focus in my mind.
-- DavidSaff
The change by DavidSaff popped this back onto RecentChanges, and I realize that I've begun to take a third way. I still find getFoo and setFoo abysmal. Thanks to the Chandler project (in Python, I think!), I've found a convention that I really like: use "_" the same way SmalltalkLanguage uses a ":". So, instead of "getFoo()" and "setFoo", use "foo()" (the read accessor) and "foo_(aValue)" (the write accessor).
A JavaLanguage giant will have to tell me whether this convention is acceptable to the JavaLanguage compiler. It works in JavaScript and PythonLanguage, and that's good enough for me for now. It also lets me follow most of the Smalltalk naming rules, which I really like.
I wonder if it might be worth revisiting my exchanges with DaveHarris from this new perspective.
-- TomStambaugh
This is a good point just because direct variable access has the simplest looking syntactic sugar makes it in no way special. You could create a language in which obj.data was an auto predefined function that could be over ridden and that the only way to avoid that and actually reference a member variable was something else... or perhaps as in the case of ruby and com there is no external way to directly access a member that cannot be over ridden. -- AlanChristiansen
Aren't public attributes are acceptable when creating a private class which serves only to group data together, a.k.a. the DataHolder object? But, the risk is that what you assumed was mere data should in fact have been a separate class, which is often the case.
In the spirit of YouArentGonnaNeedIt, I created a dumb Java "struct" - no methods, just a few public member variables. Later, I needed it to have a toString() so I added it. Later still, I needed to make it a ValueObject, so I created a constructor that set the values, added accessors, and made the member variables private. Then I found the calling code and fixed it. The total cost to make this change, including changing and testing all of the code that referenced the "struc" class? About 15 minutes.
I wouldn't have done it without unit tests. Or at least, I wouldn't have done it so fearlessly. But with unit tests, it just wasn't a problem to start out with a dumb struct and later change it to a smart object.
I am not a Real X programmer and don't use Real XP. I do it my Way.... I however have similar experiences. If Everything else about how I code is right I do not get burned by having SOME public members. I do have some because it is the simplest thing that can possibly work but I never had articulated the reason before. I also find that even if it is expensive to refactor when some of the members were public, hiding them behind accessors would rarely have helped, see my examples above and the problems with setX and setY elsewhere on this page.
The trick I find is to see (See pages of form Grok*) the problem well enough and understand the domain well enough that setXY looked like a good diea in the first place.
There is the anti XP practice of BigDesignUpFront I do not do this, can not do this (future employers take note: but also believe no one else can either), what I do do is BigUnderstandingOfProblemUpFront?.
-- AlanChristiansen.
I'm in the habit of declaring instance variables to be private so that when I reparent the class, I don't have to worry (as much) about colliding with an inherited instance variable of the same name and different semantics. For example, suppose the variable is named "owner" and declared to be of some dull type like "Object" or "Model". If it is declared to be private, then my class will use a (private) copy, and my methods will reference my private copy, regardless of what happens in my ancestor.
I've never been able to keep track of the magic that happens in this situation with raw variable accesses, and so I never try: I always use accessor methods.
Finally, I also agree - DontUseGetAndSet. Read accessors shouldn't distinguish between local and remote or static and dynamic state. Write accessors should return void. In Smalltalk, the ":" makes the write selector easy to distinguish. In CeePlusPlus and JavaLanguage, the write accessor has a different signature and function overloading works just as expected.
Hence, my preference (in Java) is:
class Bar { public Foo foo() { return myFoo; } public void foo(Foo aFoo) { myFoo = aFoo; } private Foo myFoo; };-- TomStambaugh
"In CeePlusPlus and JavaLanguage, the write accessor has a different signature and function overloading works just as expected."
Not true in C++ because of the "hiding problem"... overloading is based on the method name rather than the method signature. For example, the following code is an error in C++:
class Base { public: virtual int foo() { return myFoo; } virtual void foo( int aFoo) { myFoo = aFoo; } private: int myFoo; }; class Derived : public Base { public: virtual void foo( int aFoo) { Base::foo( aFoo ); } }; Derived d; int n = d.foo();The last line is an error because void Derived::foo has hidden int Base::foo.
[ of course this is easily fixed by adding "using Base::foo;" to Derived ]
I have hijacked the original thread of this page and humbly apologise I suspect I(or someone else) should heavily refactor the page into two. I think the topics are
DontUseGetAndSet(Original topic) some_members_can_be_public (New topicMy excuse for hijacking is that I did not know what the topic was precisely so I did not make a new page with a bad name that cannot be refactored.
On the original topicWhat I dont understand is what is the problem with getFoo(); What does getFoo() mean? To me it is a contract
The function foo() where foo is typically a noun like word conveys to me no meaning (unless by convention we give it one :).
Suppose I'm interested in the current balance of my account. And suppose I write a method that calculates and returns it. My intuition (from Smalltalk) is to name the method "currentBalance". So its signature would be:''
public Money currentBalance();Now, suppose I determine, later, that it takes a long time to compute the currentBalance, and that I would like to cache the result of the computation in an instance variable. I would then give the instance variable the name currentBalance and change the implementation of my currentBalance method to return its value.
If I use the get... and set... accessor method convention, then I have a choice -- I must either name the original method "getCurrentBalance()", change currentBalance() to return the result of getCurrentBalance(), or change every sender of the "currentBalance()" method to now send "getCurrentBalance()" instead.
I argue that none of these alternatives is as good as avoiding the use of "get" and "set" prefixes. In my view, a function that has no arguments and is called for its return value (instead of its side effects) should be indistinguishable from an accessor method for an instance variable that caches the value returned from that function. This is because I view an instance variable as an implementation detail that should have no effect on the external view of a class. I don't want to prepend "get" to every function that I use (doing so would merely add noise the source code), and so I choose not to use it anywhere.
-- TomStambaugh
The anti-accessor example I usually use is a Point class:
class Point { private: double x,y; public: double getX(); void setX(double); double getY(); void setY(double); }For some calculations in your application, you find polar coordinates more useful, so you add methods to get them:
... double getAngle(); double getRadius(); }(These methods call Trigonometric functions to compute the attributes from x and y.)
Later, you find polar coordinates so useful that you decide to change the internal representation of the class from "x,y" to "angle,radius". Now you're in trouble! Sure, you can compute x and y (for getX & getY) from angle & radius, but the attribute setting functions for x and y cause lots of problems: What order must you call them in? Does the class store intermediate data between the two calls, to ensure that the end result is what's expected?
Here's a more appropriate interface definition:
{ public: void setXY(double x, double y); void setPolar(double radius, double angle); }Now the class can be implemented either way, and the client can't tell the difference (except for performance).
Contributors: JeffGrigg
This precisely the place where I get burnt. Having the variable public wasnt the problem it was providing independent contracts to modify two parts of what was really one object. If we had exposed as a public Member the object Coordinate which had accessor functions getXY and setXY then there would be no problem.
My rule: I only expose members when I know that they are so intrinsically rooted in the problem domain that if I need to mess with them then we might as well be changing and air traffic control system into a luggage handling system (after they both just track objects :)
Real Example. I have a general purpose tokeniser, that use over and over again. It has a public member variable called token it is a string like object. Its interface will have an accessor c_str() returns a const char *.
If it ever stops having a string that is semantically representable as the concept token then I think I should call it something else and start again meanwhile the simplest thing that has worked many many times is apublic member variable called token.
The most serious violators I see are classes that return their internal collections. Even if they return a 'const' object, they're still revealing the kind of collection they're using, causing clients to break whenever you change the implementation. Typically, it's better to return an iterator. -- JeffGrigg
Typically I find it is best to minimise the size of the contract at any point where I have any doubt what the contract should be. In other words when I am not yet certain what is required try to avoid encoding my inaccurate knowledge into the interface.
Example The other day I was writing code to search for wildcard named files on a PC it has been years since I last wrote this functionality and long names etc have all been added since then. I was at this stage quite unsure how it would be implemented thus I tried reall hard to abstract the concept of searching for files to a model that I believed I could probably support anywhere anytime.
In this vein at times for certain members, see Tokeniser previously described I have no problem making the contract as immutable as public member variables are.
Formatting note: Usually when someone inserts a comment into the middle of a long note, it is enough to insert an extra signature line before it to make the change in voice clear. In this case we also have replies to replies, effectively 2 threads from different times intermingled, and the original note doesn't make sense unless you ignore the interpolations. Thus I have left the original note unindented and indented the additions. This is an extreme measure. Hopefully the indented threads can simply follow linearly; it is not my intention that further additions be indented a second level.
Obviously it would be better rewritten from scratch (perhaps in DialecticMode), but I wanted to see what this looked like, and we haven't yet reached consensus.
Tom wrote:
public Foo foo() { return myFoo; } public void foo(Foo aFoo) { myFoo = aFoo; }I like calling the accessor "foo", but to me giving the same name to the modifier is an abuse of overloading. They do very different things - one changes the object's state and the other doesn't. I prefer methods which change state to have names which make that clear - if not "set", then "update" or whatever makes sense. This is because state changes are a big deal to me. -- DaveHarris
aDog.leg( 1 );Is this an accessor or a modifier? -- DaveHarris
public void foo() { myFoo = 0; }-- DaveHarris
public int myFoo() { return myFoo; } public void myFoo(int aFooValue) { myFoo = aFooValue; }
public int myFooPreset() { return 0; }
myFoo(myFooPreset());
aDog.legAt( 1 );
From the top:
The accessor does not need "get". It should not have it, either, because we might not be "getting" the result from an instance variable, we might be calculating it on the fly or reading it from somewhere else. Notice that "foo()" is the same length as "myFoo" so even lazy programmers might as well use the function.
I don't get it. What's wrong with the word "Get"? Whatever the function actually does under the hood, and wherever the value is ultimately coming from, you're still "getting" the value from the object, on the face of it, in the most basic sense possible.
In my own practice, I look at any "GetThisItem?" function as something which obtains me a value, and may get hold of it or calculate it or do any of a number of possible things to serve it up to me. That is, in code that uses this code, I never assume it is only grabbing a pre-existing, stored value.
If I have an object I think will required lots of Getting and Putting, why then I will most likely turn it into an all-public struct-with-helper-functions instead of a closed class.
Or, I will use something like the following:
template <typename T> class Attribute { public: Attribute(T val = T()) : m_value(val) { } operator const T& (void) const { return m_value; } void operator = (T val) { m_value = val; } private: Tm_value; Attribute* operator & (void); // disabled / disallowed const Attribute* operator & (void) const; }; class Beaver { public: Beaver() : raisin(1), oatmeal(2), bacon(3) { } int Chortle(void) { return raisin + oatmeal + bacon; } Attribute<int>raisin; Attribute<int>oatmeal; Attribute<int>bacon; private: // nothing at the moment }; void main(void) { Beaver a; Beaver b; a.raisin = 55; a.bacon = a.raisin + a.oatmeal; b.bacon = a.Chortle(); int i = b.Chortle(); }
Don't Use Set, but Get may be necessary
Sometimes it is necessary to break encapsulation. Just for ease of programming and avoiding intermediate temporary variables, it is best to extract data elements individually. For reinserting values into an object, though, it is best to do them as a group. As a somewhat trivial example, suppose I have a Name class and it contains a First Name, a Middle Name, and a Last Name. I want to provide a GUI interface to allow the user to enter or change the name. I need to pull out the individual name elements and put them into individual text boxes. I also want to enforce some business rules. All three name fields may be blank. The Last Name may have a value, but the First and Middle names are blank. The Last Name and First Name may have a value, but the Middle Name is blank. The First, Middle, and Last names may all have values. To enforce the rules, I need to apply all 3 name fields simultaneously. This would lead to the following pseudo-code:
myFirstNameTextBox.Value = myName.First myMiddleNameTextBox.Value = myName.Middle myLastNameTextBox.Value = myName.Last myName.Update(myFirstNameTextBox.Value, myMiddleNameTextBox.Value, myLastNameTextBox.Value)Note the use of Get accessors on the Name class (myName object), but no Set accessors, rather an aggregate Update method.
Pythonic Get/Set Overloading Wishful Thinking
I think PythonLanguage has the right idea by providing __getattr__ and __setattr__ overloading so that you can treat members as if they're public, but make sure the getters and setters are called properly. Of course, operator overloading in CeePlusPlus has a bit too much boilerplate to make this sort of idiom especially useful, but it's a nice touch regardless.
Maybe I'll just go ahead and drop a soft Python layer on top of my CeePlusPlus library using the BoostPythonLibrary and get the best of both worlds! -- Chris Bonhage
Why not use Python's built-in property() function instead of __getattr__ & __setattr__?
It's standard in Java, but it does help in areas other than bean reflection. I find when using code completion in the IDE, if I know the method I want is a 'getter', I type 'get', and the autocompletion will narrow down my list of choices so I can quickly look for what I want.
However when I'm doing C++, I drop the 'get' altogether as the original author describes.
In Java, getX and setX are standard, which makes your code more readable. It makes sense to follow the standards unless there's a good reason not to.
get... and set... are naming conventions in Java that were introduced for JavaBeans. The beans framework relies on this naming convention. It doesn't matter if you like it or not, if you implement a Java class as a bean, and if one of the attributes should have an accessor and/or manipulator you have to follow that convention. Otherwise you don't get a bean.
In fact, that's not true, you get a bean also by declaring your xyz method as a getter. It does not matter anymore if you named it xyz.