12

Here are some arguments for properties and my counter-arguments:

Easier to use than writing getter and setter methods

Getter and setter method pairs are a code smell. Making it easier to write these is like making it easier to fail a math test by using a Scantron form and filling in all 'C's. Objects that contain only state, for persistence, shouldn't be using getters/setters and should be creating immutable objects at the time of persistence.

What is important to a consumer of an object is what it does, not how it does it. Its behavior is what it does; its state is how it does it. If you find yourself caring about an object's state (except for persistence, though this also breaks OO), you're simply not doing OOP and losing out on its advantages.

They give a rough indication of performance to consumers

This is something that could change in the future, for any given property. Suppose in release 1.0, accessing PropertyX simply returns a field. In release 1.5, if the field is null, PropertyX uses the Null Object pattern to create a new null object. In release 2.0, the field is getting further validated by the getter method in PropertyX.

As the property gets more and more complex, the performance indication of using a property seems less and less truthful.

They're better than public fields

This is true. But so are methods.

They represent a fundamentally different aspect of an object than a method, and all consumers of the object should care about this

Are you sure that both of the above statements are true?

They're easier to type, man

Sure, typing myObject.Length is easier than typing myObject.Length(), but couldn't that be fixed with a little syntactic sugar?


Why use methods instead of properties?

  • No performance guarantees. The API will remain truthful even if the method gets more complex. The consumer will need to profile their code if they are running in to performance issues, and not rely on word-of-API.

  • Less for the consumer to think about. Does this property have a setter? A method sure doesn't.

  • The consumer is thinking from a proper OOP mindset. As a consumer of an API, I am interested in interacting with an object's behavior. When I see properties in the API, it looks a lot like state. In fact, if the properties do too much, they shouldn't even be properties, so really, properties in an API ARE state as they appear to consumers.

  • The programmer of the API will think more deeply about methods with return values, and avoid modifying the object's state in such methods, if possible. Separation of commands from queries should be enforced wherever possible.


So I ask you, why use properties instead of methods? Most of the points on MSDN are code smells in and of themselves, and don't belong in either properties or methods.

(These thoughts came to me after thinking about CQS.)

xofz
  • 345
  • 2
  • 10
  • 5
    +1. Properties are methods with the syntax of fields and that just doesn't make sense. – Nemanja Trifunovic Mar 26 '11 at 22:20
  • 23
    @Nemanja Trifunovic: It makes perfect sense if you have written `type GetFoo() void SetFoo()` ten thousand times. In all my time writing C# code I have never been confused by a property. – Ed S. Mar 26 '11 at 22:35
  • 23
    Sounds to me like you've already made up your mind. What's the question? – Dean Harding Mar 27 '11 at 07:11
  • @Ed S.: Getters and setters are generally bad (with few exceptions). I don't think it is reasonable to make them easier to implement, especially if it leads to confusing syntax. And it is confusing - have you never heard of cases of stack overflows due to calling properties from within themselves by mistake? – Nemanja Trifunovic Mar 27 '11 at 20:56
  • 9
    @Nemanja Trifunovic: *"Getters and setters are generally bad"* You can repeat that as many times as you like, but it won't make it true. How about explaining why you think they are bad? As far as SO crashes due to typing the property name instead of the underlying variable name, that is an impossible to miss error considering it will crash you program as soon as you call the property and it is pretty rare. When it does happen I know exactly what I did to cause it and I have it fixed in two seconds. I don't see the problem. – Ed S. Mar 27 '11 at 21:35
  • @Dean Harding. Initially, it was something like, "why would I use properties if I am doing object-oriented programming?" Maybe even, "how would I use properties if I am doing object-oriented programming?" – xofz Mar 27 '11 at 22:22
  • 2
    @ Ed S.: I don't really feel I should explain a point that is very widely known and mostly accepted. For instance, read this: [Why getter and setter methods are evil](http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html?). As for the stack overflow issue, you may find it in a couple of seconds (or your customer can if you don't) but I find questions about that problems constantly asked on various programming forums. – Nemanja Trifunovic Mar 27 '11 at 22:30
  • 1
    @Dean Harding I guess he's brought some arguments for his opinion and is looking for good counterarguments. He could have left them out, but then there'd appear in the answers, so he's already done part of the work. Unfortunately, some people think it deserves downvotes. – maaartinus Aug 06 '11 at 14:36
  • I agree that getters and setters are usually not the best interface for an object. However, that's no excuse for making them harder to use when they are the best. As for performance, I except my getters and setters to be fast as well. No difference from properties there. – Winston Ewert Sep 29 '11 at 22:39
  • @Winston Ewert, could you clarify? Excepting your first sentence, what you said made no sense. – xofz Sep 30 '11 at 00:58
  • 3
    Just passing by to point out to @NemanjaTrifunovic that that *Why getter and setter methods are evil* article is quite **old**, is about **java** and **underlines a java weakness**: the weakness of **not having properties**. (hence showing off too many implementation details) …biting our tail here. (it should be titled *getters and setters are bad in java, cause we have no goddam well thought standard about those*) – ZJR Sep 30 '11 at 01:22
  • 1
    @SamPearson, properties are getters and setters with a nicer interface i.e syntactic sugar. The OP objects to properties because they encourage people to use the equivalents of getters and setters. But I maintain that the fact that people will abuse getter/setters/properties is not reason enough to make implementing and using them more difficult than neccessary. – Winston Ewert Sep 30 '11 at 01:45
  • @SamPearson, as for the performance comment. The OP objects to properties because it means that something that looks fast, like `foo.bar` may actually be very slow since bar could invoke an arbitrarily complex algorithm. But I maintain the same is true for foo.GetBar(). I'm going to assume that foo.GetBar() is also very fast. So there is no advantage of avoiding properties there. – Winston Ewert Sep 30 '11 at 01:47
  • 1
    @ZJR, see http://programmers.stackexchange.com/questions/21802/when-are-getters-and-setters-justified for discussion of the question of getters and setters. It is *not* a concern restricted simply to broken languages like Java. (to be clear, getters and setters aren't always wrong, but they are massively overused) – Winston Ewert Sep 30 '11 at 01:49
  • 1
    Despite all the dogma, there is no design advantage of `public Type Property { get; set; }` over `public Type Property;`, since the latter can transparently be changed to the former. Both are equally bad because, like globals, any piece of code can change the value of Property, affecting all users of Property. Much preferable are immutable objects, setting the values of properties at the time of construction. – Jim Balter Jul 27 '15 at 20:59
  • 1
    @ZJR Agree with Winston Ewert here, my impression of the article was the same as his; it is not only a Java problem. – IntelliData Jan 20 '17 at 15:12

10 Answers10

46

Why is it "methods against properties"? A method does something. A property is, well, a member of an object. They're totally different things, although two kinds of methods commonly written - getters and setters - correspond to properties. Since comparing properties with methods in general is not meaningful, I'll assume you meant to talk about getters/setters.

Getter and setter method pairs are a code smell.

Not necessarily, I'd argue, but either way this isn't a matter of getters/setters vs. properties but a matter of whether either should be used. Also note that you can e.g. leave out the setX part just like you can make read-only properties.

What is important to a consumer of an object is what it does, not how it does it. Its behavior is what it does; its state is how it does it. If you find yourself caring about an object's state (except for persistence, though this also breaks OO), you're simply not doing OOP and losing out on its advantages.

A highly questionable attitude. If the GUI wants to output data held by a DataStuffManagerImpl, it needs to get that number from it somehow (and no, cramming half of the application into the widget class is not an option).

As the property gets more and more complex, the performance indication of using a property seems less and less truthful.

[Methods have] No performance guarantees. The API will remain truthful even if the method gets more complex. The consumer will need to profile their code if they are running in to performance issues, and not rely on word-of-API.

In almost all cases, all the validation logic etc. is still effectively O(1), or otherwise negible in cost. If not, perhaps you've gone too far and it's time for a change. And a getX() method is usually treated as cheap as well!

Sure, typing myObject.Length is easier than typing myObject.Length(), but couldn't that be fixed with a little syntactic sugar?

Properties are that syntactic sugar.

Less for the consumer to think about. Does this property have a setter? A method sure doesn't.

"Is there a setter for this getter?" Same difference.

The programmer of the API will think more deeply about methods with return values, and avoid modifying the object's state in such methods, if possible. Separation of commands from queries should be enforced wherever possible.

I'm not sure what you're trying to tell us here. For properties, there's an even stronger unwritten law not to cause side effects.

  • 3
    +1, And its not an unwritten law. Property usage guidelines on MSDN has it written with many others. I think OP should go through them to make himself clear of many doubts. And I can't post a link here since I am writing this from my phone, but guidelines should be easy to find. – decyclone Mar 27 '11 at 10:05
  • http://msdn.microsoft.com/en-us/library/bzwdh01d.aspx or http://msdn.microsoft.com/en-us/library/fzcth91k.aspx – Jesse C. Slicer Sep 30 '11 at 01:39
  • @delnan: Properties are not that syntactic sugar. Properties can be treated like fields (they can be used as an assignment target, if they have a setter). Methods cannot. – xofz Sep 30 '11 at 20:11
  • 1
    @SamPearson: `obj.x = y` maps to `obj.setX(y)` and `obj.x` maps to `obj.getX()`. How's that different? –  Sep 30 '11 at 23:09
  • @delnan: there is something fundamentally flawed with typing obj.x = y. My argument is that if properties *were* that syntactic sugar, obj.x would be a method, not a property. Methods cannot be assignment targets. *Even though* obj.x = y *doesn't* change the actual *behavior* of the setter, the "syntactic sugar" sure makes it look like that. I asked for some syntactic sugar; properties gave me syntactic vinegar. – xofz Oct 01 '11 at 00:41
  • @SamPearson: Then what's the syntactic sugar you talk about? Does it only apply to getters, but not to setters? Properties seem to do exactly what you asked for: Make getter/setter method calls "sweeter" by providing lightweight syntax (attribute access/assignment) for them. And `obj.x = y` sure doesn't look like changing a setter, at least to me. It looks like setting an attribute. Which is precisely what it does if you ignore the *implementation detail* that there's a method call happening. –  Oct 01 '11 at 11:29
  • @delnan: can you provide a convincing argument for "setting an attribute," in which such an action is neither necessarily a state change or a behavior change? This is interesting to me. – xofz Oct 03 '11 at 19:29
  • 1
    @SamPearson you can change the visibility of a property setter and getter independent of each other. I use this all the time with my Entity Framework objects: my setters are protected (so only the framework can set a value). So it's perfectly viable to say int length=myObject.Length without allowing myObject.Length=10 – Michael Brown Mar 14 '12 at 20:13
19

Getter and setter method pairs are a code smell.

That is a faulty assumption and completely incorrect. Get/Set methods are a way to encapsulate a data member and are in no way a "code smell". I really hate the way some people throw around the term "code smell", but anyway...

This is something that could change in the future, for any given property. Suppose in release 1.0, accessing PropertyX simply returns a field. In release 1.5, if the field is null, PropertyX uses the Null Object pattern to create a new null object. In release 2.0, the field is getting further validated by the getter method in PropertyX.

As the property gets more and more complex, the performance indication of using a property seems less and less truthful.

Sounds like a poorly designed API, I don't see how that is the fault of property syntax.

Properties in C# were simply syntactic sugar for a very common pattern that made our lives as programmers a bit easier. However, these days, if you want to use data binding you "must" use properties, so they are now a bit more than syntactic sugar. I guess I really just don't agree with any of your points at all and I don't understand why you dislike a language feature that directly supports a common pattern.

Ed S.
  • 2,758
  • 2
  • 21
  • 24
  • 1
    I'm going to give a bounty to come up with a better term than code smell. Just read a book on refactoring where it is used about a thousand times. It's like fingernails on a chalkboard. – JeffO Mar 26 '11 at 22:33
  • 1
    @Jeff O: Yeah, I find that the people who seem to throw that term around the most typically don't have a lot of experience. – Ed S. Mar 26 '11 at 22:36
  • 6
    @Jeff O and @Ed S: IME, "code smell" has become the go-to term that people use when they really mean "I don't like it, but I don't actually have a reason" – Steven Evers Mar 26 '11 at 23:18
  • 3
    @SnOrfus: Yep, or when they hold "religious" views that often make little sense in practice, like *"a method should never have more than X number of lines"*, which in turn is usually just a repetition of something they read somewhere. – Ed S. Mar 26 '11 at 23:49
  • Jeff O: Kent Beck came up with the term, and it had a particular meaning - "this code offends my design aesthetic" or, more colloquially, "this code sucks a bit". So when a book on refactoring - on cleaning up sucky code - uses it a lot, well, it's to be expected. Otherwise, SnOrfus nails it - it's turned into "I don't like this code (even though I know very little about proper design)". – Frank Shearar Mar 27 '11 at 09:28
  • 1
    The *inappropriate* use of getter/setter methods is a code smell, but so too should be the inappropriate use of *anything*. Even when things have narrow use cases, employing such things for those use cases should not be considered a code smell. The creation of setters for everything shouldn't be a blind habit, but one shouldn't be afraid to include them when appropriate. What's necessary is to balance the usefulness to clients of being able to change state, versus being able to find out in future what the state was earlier (easy if state is immutable). Both are useful, but code must pick one. – supercat Feb 24 '14 at 16:47
  • @JeffO Can you share the title of that book please, and if possible, if you have a better suggestion for the same topic? – Honinbo Shusaku Nov 02 '16 at 12:50
10

Your premise is wrong.

Properties are in no way a contract to performance or internal implementation or whatever.
Properties are special methods pairs, that semantically represent an attribute, if you will. And thus the only contract is, that a property behave as you would expect an attribute to behave.
If I ask for an object's color, I don't make assumtions whether it is obtained by a plain field access, or whether it is calculated just in time.
The whole point is, to have the ability to expose the behaviour of an attribute by using methods, while it is transparent to the consumer of the interface, whether you're using a field or accessors.

Having attributes (and actually hiding their implementation, as properties do opposed to fields) is a powerful declarative feature, that is the basis for having visual object inspectors and other automatic view generation, for data binding and many other useful things. And most importantly, it clearly transports this information for your fellow programmers as well.

back2dos
  • 29,980
  • 3
  • 73
  • 114
6

Another important reason in my book for using properties is that they can increase readability greatly.

account.setBalance(Account.getBalance()+deposit);

is plainly much less readable than

account.Balance += deposit;
apoorv020
  • 666
  • 5
  • 11
  • 6
    Except that Balance shouldn't be a property because there is sure to be significant business logic associated with changing it (check for overdraft; charge service charge; record transaction, etc.) Your readability point is completely valid if applied to a different example (Temperature, BackgroundColour etc.) – Kate Gregory Mar 27 '11 at 18:28
  • 9
    Why not account.Deposit(amount)? – xofz Mar 27 '11 at 22:15
  • 4
    @Sam Pearson: +1. A perfect example of why getters/setters often indicate poor design. – Nemanja Trifunovic Mar 27 '11 at 22:42
6

The consumer is thinking from a proper OOP mindset. As a consumer of an API, I am interested in interacting with an object's behavior. When I see properties in the API, it looks a lot like state. In fact, if the properties do too much, they shouldn't even be properties, so really, properties in an API ARE state as they appear to consumers.

A property is supposed to be a state. If the underlying setter or getter code changes to add significantly to processing required to set or get the state then really it's no longer a property and you should replace it with methods. This is up to you as developer of the code.

Putting too much (how much is too much depends) code in a setter or getter is wrong, but just because it's possible is not a reason to throw out the pattern in all cases.

ChrisF
  • 38,878
  • 11
  • 125
  • 168
6

One thing you are missing, and I don't know if this is due to ignorance or if you're intentionally overlooking this detail, is that properties ARE methods.

When you use C#'s property syntax, the compiler quietly creates getter and setter methods with metadata that tells languages that understand properties as a first-class syntactical feature to treat them as such. That is, in fact, the syntactic sugar you're asking for. A few languages that can be run on the CLR don't completely hide this detail from you (Boo, if memory serves me, and some Lisp implementations), and you can call the getters and setters explicitly.

Properties occasionally have side-effects, like triggering change notification events (INotifyPropertyChanged, for example) or marking an instance of a class as dirty. This is where they have their real value, though creating them is a little more work (except in Boo, which has syntax-savvy macros).

Now, the broader question is whether getter and setter methods are, in fact, A Good Thing. There are clearly tradeoffs; if you have mutator methods, your code is inherently less parallelizable, because you now have to deal with thread synchronization issues. And it's quite possible that you'll risk violating the Law of Demeter using mutator methods (whether called properties or getter/setter methods; they are equivalent), because it's so darned convenient to do so.

But sometimes it's the right thing to do. Sometimes your problem is to grab data from some source, change it a little, present the updated data to the user, and save the changes. That idiom is well-served by properties. As Allen Holub's article says, just because getters and setters have problems doesn't mean you should never use them. (Parroting abstract Guruspeak considered harmful). Even when you follow the Class/Responsibilities/Collaborators approach, you still end up exposing either information or presentations of information to somebody; the point is to minimize the surface area of entanglement.

The upside of properties is that it's very easy to have another object take advantage of them. The downside of properties is that it's very easy to have another object take advantage of them, and you can't easily prevent that.

Object mutation makes sense at the controller layer, in, for example, an MVC architecture. That's your collaborator. Your view is also a collaborator, but it shouldn't directly be mutating your objects, because it has different responsibilities. Rolling presentation code into your business objects isn't necessarily the right way to avoid getters/setters either.

The equation changes a bit if you use functional, rather than pure OO, abstractions, which generally makes making copies of a "record" object with a couple of changes pretty trivial, though not free. And hey, If you're trying to get performance guarantees, properties are generally more predictable than lazy rebuilding an immutable collection.

JasonTrue
  • 9,001
  • 1
  • 32
  • 49
4

You have almost the opposite religious viewpoint to me :)

When I moved from Delphi to Java the lack of properties was a huge affront to me. I was used to declaring a property and either pointing it directly to a private variable or writing a (protected) getter & setter then "plumbing" them to the property. This encapsulated the property and controlled how it should be accessed in a clear unambiguous way. You could have a read-only property that calculated the total when accessed and call it "Total" not "_getTotal()" or similar ballochs. It also meant that you could restrict access to properties by making them protected in the abstract base class then moving them to public or published in subclasses.

To me, properties are a more natural & expressive way of setting & getting the state of the object. Relying on unenforced coding conventions is more of a "code smell" than anything you're criticizing properties for. Also, as others have said, coming up with a badly designed use of properties and using its failings to try & dismiss the concept of properties in general is extremely bad form. It's possible that you've only seen bad use of properties & assume that's the way it is I suppose but you should do more research before becoming too dogmatic.

mcottle
  • 6,122
  • 2
  • 25
  • 27
  • +1 That indeed a real use of a property. Great answer. "**It also meant that you could restrict access to properties by making them protected in the abstract base class then moving them to public or published in subclasses.**" – Karthik Sreenivasan Jan 23 '12 at 05:43
  • Delphi misuses properties ad nauseam. You don't sort list, you set its `sorted ` property to `true`. So setting it to `false` gives you the original list. :D Or does it shuffle it randomly? :D Or whatever, it's just stupid. Additionally, it's damn slow compared to a proper sorted set. Properties aren't bad, but I've learned to use them very sparingly (till the point of being quite happy with getter and setters; I'm using mostly Java). – maaartinus Jul 30 '17 at 23:13
1

One of the reasons properties were introduced in the Java Beans Framework was to allow integration with an IDE - you can drag those components to the IDE and edit the properties using property editors.

(back then they were only regular getters and setters - and were defined only by the naming convention - and this did indeed smell)

Today there are even more cases where properties are accessed and modified not through regular code - such as while debugging.

Ophir Yoktan
  • 387
  • 1
  • 11
1

One other angle -- they really came from VB. Remember, back in the dark days of the 20th century when .NET was conceived one major emphasis was it was an easy, drop-in replacement for VB so your VB programmers could just drag and drop things onto webforms. VB had properties so you needed to keep that feature for things to translate right.

Wyatt Barnett
  • 20,685
  • 50
  • 69
1

There are at least two purposes for properties:

  • They are conceptually identical to fields even if they're implemented differently. A getter should not change the state of the object and should have no side effects. A setter should only change the state in ways conceptually similar to modifying a field and not have other side effects.

  • They're syntactically identical to public (possibly read-only) fields. This means a public field can be changed to a property without breaking callers at the source level.

dsimcha
  • 17,224
  • 9
  • 64
  • 81
  • Yes, but note the word "should". There is nothing about properties that prevents getters from having side effects and in fact I've seen numerous cases where that was the case. – Nemanja Trifunovic Mar 27 '11 at 20:53
  • 1
    Changing a public field to a property **will** break binary compatibility, the consuming code will have to be recompiled - although not modified which I'm guessing is what you were getting at :) – MattDavey Sep 28 '11 at 15:35
  • @MattDavey: Thanks. That is what I meant. Edited. – dsimcha Sep 29 '11 at 22:07