I\'m reading the book \"Clean Code\" and am struggling with a concept. When discussing Objects and Data Structures, it states the following:
While public properties are not an immediate code smell, consider this article:
Coding with Reason by Yechiel Kimchi (from the book 97 Things Every Programmer Should Know)
"...don't ask an object for information to work with. Instead, ask the object to do the work with the information it already has."
This doesn't come into play all the time (for example, Data Transfer Objects). What I watch out for is Inappropriate Intimacy.
Like other posts in this thread I'll point out that properties in C# are just special cases of accessor functions that you mention. In fact you can fine the get_Property and set_Property methods in the IL on your object that have a flag that indicates they are properties, the same is true for events which implement add_ and remove_ prefixed methods.
One important distinction when dealing with abstractions is whether setting the property is going to act on the object other than just updating the internal state or throwing a PropertyChanged exception.
If you look at a lot of the internal BCL objects, the properties are implemented in such a way that you can set all the properties in any order to configure the object. If any complex processing is done, then usually a method that describes what is going to happen is a better choice.
Properties are in fact methods.
The compiler compiles properties to get/set MIL methods.
It is mostly another definition of the term "property". A property in C# is not what most other languages think of as properties.
Example:
A C++ public property is:
class foo
{
public:
int x;
};
The corresponding term in C# would be a public field:
class foo
{
public int x;
}
What we name in C# as properties would be setters and getters in other languages:
C#:
class foo
{
public int X { get; set; }
}
corresponding C++:
class foo
{
private:
int x;
public:
void setX(int newX) { this->x = newX; }
int getX() { return this->x; }
}
In short:
C# properties are totally fine, just don't blindly default them to get and set and don't make every datafield in your class a public property, think about what users of your class really need to know/change.
The book is trying describe the theory that an object should not expose how the class is actually implemented. In more complicated objects many of the internal variables don't necessarily convey the right information from an outside perspective and should just have methods that act on them.
However, making this a hard and fast rule falls apart when you have simple objects. In the case of a rectangle, height and width are basic properties that the user will want to know. And since the implementation of this is straight forward, not using get and set will just make your code more complicated than it needs to be.
When you are finished Clean Code I would recommend you read Bob Martin's other book:
Agile Principles Patterns and Practices In C#
In this book the vast ammount of the book discusses a case study and in it, Bob applies the principles discussed in Clean Code. I read Clean Code first but in retrospect I think "Agile Patterns.." should be read first as Clean Code is more of a day to day handbook or manual of good SW principles.
For example, in "Agile patterns..." the following code is used:
public class OrderData
{
public string customerId;
public int orderId;
public OrderData() {}
...
}
The following validation of the use of Public data deals with your question:
Don't be offended by the use of public data members. This is not an object in the true sense. It is simply a container for data. It has no interesting behavior that needs to be encapsulated. Making the data variables private, and providing getters and setters would be a waste of time. I could have used a struct instead of a class, but I want the OrderData to be passed by reference rather than by value.
Aside:
Personally, I have to say that Robert Martin has made a massive contribution to the SW developer community (along with Martin Fowler, Michael Feathers..) with these books. I think they are must read.