• 12
• 12
• 9
• 10
• 13

# breaking encapsulation ?

This topic is 3894 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

this is more of a justification for encasulation more than anything else ive always made all my members private and all my functions to get/set them public if you want my members use my functions i have some members in an object some members are used all the time others would be very rarely used, if ever many of these get/sets are very simple though.. just setting a new int or return a double why should i not just make these values public and more easily modified? someone told me...because its breaks encapsulation... well if thats the case its a practice that needs to die because its silly i can understand doing it this for more complicated members like other objects where it can be a multi step process... if i have the class booger and it has members int a, b; double c, d; and string e, f; should i or should i not just make these members public

##### Share on other sites
Generally speaking, if your class has a lot of "get" and "set" members and it is not a POD type, the data isn't where it is supposed to be anyway.

Take a look at what is calling all those "get" and "set" members, and think about whether it would be smarter to move the data into that class.

##### Share on other sites
Only reason to have get/set functions instead of modifying the variables themselves is to make it harder to modify them by accident.

##### Share on other sites
Heavily practiced in Java (somewhat less in C# due to get/set), it's a recommended technique.

Personally, I prefer to use functional approach where possible.

Let class keep its members private, but let it expose *functions*.

Consider something like this:
class Person {public:  // A whole bunch of getters/settersprivate:  std::string firstName;  std::string middleName;  std::string lastName;  int yearOfBirth;  int monthOfBirth;  int dayIfBirth;};

Why should anyone who cares about person know about these fields? This isn't encapsulation! It's grouping, a naming convention, an obsoleted paradigm.

What do I want my class to do? I don't want it to sit there and look pretty.

What will a Person do? Let's say we want to store it to database, print it on a label, display it, and do a few more things.

class Person {public:  // No more getters/setters  void persist( Database *db ) {    db->insert( Person, firstName, middleName, lastName, ... );  }    std::string fullName() {    return firstName + " " + middleName + " " + lastName;  }  void print( PrinterCanvas *page )   {    page->drawText(0, 0, fullName() );  }  // for std::cout or other streams.  friend std::ostream &operator( std::ostream &os, const Person &person );private:  std::string firstName;  std::string middleName;  std::string lastName;  int yearOfBirth;  int monthOfBirth;  int dayIfBirth;};

Here is where encapsulation comes in. I can change internal representation of date, of name, use different structures, omit them - it doesn't change the public interface.

By using get/set for every private property, you not only don't encapsulate anything - you make a future mess, since the getters and setters will become entangled in the rest of your code.

If you're using getters and setters - might as well not. It's not encapsulation, it doesn't help anything, it merely triples the codebase.

EDIT:

A valuable read for getters/setters in C++.

##### Share on other sites
The problem is not get/set, the problem is how you are using get/set.

A few reasons for using get/set. First you can change the underlying data type and still not break anything because everything is still going through the get/set and you just change the implementation of that.

The biggest reason for get/set instead of public. One point of failure. I rarely have setters that just set the private member. I use setters to make sure the value is valid. Because everything has to go through the setter it is a great place to make sure you are going to have valid data.

theTroll

##### Share on other sites
Yeah, Java is notorious for the getter/setter mentality, and it doesn't always help. Usually I try to avoid it. If it's a compound data type, there's no real reason to add getters and setters. Those are generally only useful when you want to perform some complex operations or bound checking on the input. So I do not want incrementDate() on a Calendar class to accept negative numbers because my calendar is only meant to go forward (trivial example and maybe not too useful since you might want a calendar to go backward, but you get the idea). If it's something that operates on data, like how Antheus points out, then let the class operate on the data and not expose the data to other classes, breaking encapsulation.

##### Share on other sites
Quote:
 Original post by PzcOnly reason to have get/set functions instead of modifying the variables themselves is to make it harder to modify them by accident.

That's a decent point, however I think it's fair to note that if all a class does is hold data that is only manipulated through outside stimuli (calling a "setter") or returned unchanged (calling a "getter") that's a code smell that needs to be refactored.

Quote:
 A valuable read for getters/setters in C++.

That's an interesting read... though it seems like a terribly naughty idea at first :) Then you realize the internals of the helper class are not exposed. Interesting.

Quote:
 The biggest reason for get/set instead of public. One point of failure. I rarely have setters that just set the private member. I use setters to make sure the value is valid. Because everything has to go through the setter it is a great place to make sure you are going to have valid data.

Another good point.

I am finding that TDD tends to generate plenty of getters/setters which for some reason annoy me [smile]... (into refactoring).

If a setter is only used once to put your object into a good state, consider moving it into the constructor as Fowler suggests.

If you're using a getter, make sure that you're not just checking that the data is valid (which should be done inside the class), and that the returned data cannot be mutated outside the class.

EDIT: Another good article to consider

[Edited by - Verg on July 22, 2007 7:41:18 PM]

##### Share on other sites
Quote:
 Original post by VergGenerally speaking, if your class has a lot of "get" and "set" members and it is not a POD type, the data isn't where it is supposed to be anyway.Take a look at what is calling all those "get" and "set" members, and think about whether it would be smarter to move the data into that class.

Or (more likely IMX), smarter to move that functionality into the class with the accessors and mutators. (It's often repeated in a few places, too, further indicating refactoring in that direction.)

For example, if you commonly find structures like 'x.set_foo(x.get_foo() + y);', it's a strong indication that you should instead have something like 'x.increase_foo(y)'.

##### Share on other sites
Quote:
 Original post by Antheus

Excellent summary.