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.
Imagine you want to get notified about every engine cycle, e.g. to display an RPM measurement to the driver.
Observer pattern: The engine publishes an "engine cycle" event to all observers for each cycle. Create a listener that counts events and updates the RPM display.
Polling: The RPM display asks the engine at regular intervals for an engine cycle counter, and updates the RPM display accordingly.
In this case, the observer pattern would probably loose: the engine cycle is a high-frequency, high-priority process, you don't want to delay or stall that process just to update a display. You also don't want to thrash the thread pool with engine cycle events.
PS:
I also use the polling pattern frequently in distributed programming:
Observer pattern: Process A sends a message to process B that says "each time an event E occurs, send a message to Process A".
Polling pattern: Process A regularly sends a message to process B that says "if you event E occured since the last time I've polled, send me a message now".
The polling pattern produces a bit more network load. But the observer pattern has downsides, too:
- If process A crashes, it will never unsubscribe, and process B will try to send notifications to it for all eternity, unless it can reliably detect remote process failures (not an easy thing to do)
- If event E is very frequent and/or the notifications carry a lot of data, then process A might get more event notifications than it can handle. With the polling pattern, it can just throttle the polling.
- In the observer pattern, high load can cause "ripples" through the whole system. If you use blocking sockets, these ripples can go both ways.
Best Answer
Stop! Go - right now - and fix this.
Of course you're going to run into functions that only use part of your object, when your object is doing everything under the sun. No object needs 50 independent properties. Certainly some of them can be organized into sub-objects. Those three that your function takes are a good candidate set.
In the more general case, it depends. Best practices say to pass in just what you need. Best practices also say to code to an interface (in this case, the signature of the method). So this is one of those cases where you need to weigh the two best practices against the likelihood that they will come into play.
Does the method make sense to take the whole thing (since you might use other parts later)? Does the method make sense to the parts and not care that they are from independent sources?
And the other consideration is similar to the above advice: if you often find yourself taking bits from an object, it is a sign that those bits are their own cohesive object. Consider making them their own sub-object, or otherwise divvying up responsibilities to better align with how you're actually using the stuff.
Also, this answer is specifically about functions. If you're working across communication boundaries, you will often want to/need to cut down your data size. Sending 50 fields across the wire when you only need 3 is more troublesome there.