Correct way to expose instance variables to other classes - java

Can someone help me understand this:
"For example, an object's instance variables (member fields that aren't constants), should always be private. Period. No exceptions. Ever. I mean it. (You can occasionally use protected methods effectively, but protected instance variables are an abomination.) You should never use get/set functions for the same reason—they're just overly complicated ways to make a field public (though access functions that return full-blown objects rather than a basic-type value are reasonable in situations where the returned object's class is a key abstraction in the design)." - http://www.javaworld.com/article/2073649/core-java/why-extends-is-evil.html
I don't understand what he means by, "You should never use get/set functions for the same reason—they're just overly complicated ways to make a field public." Let's say I have a simple Person class with Name and Age instance variables. How should I make these available to other classes? Does he mean that I should create a Data Transfer Object? Would this be a correct implementation? Is this really preferable to having the getters and setters in the Person class?
public class Person {
private PersonData personData;
public Person (String name, int age){
this.personData =
new PersonData(name, age);
}
// get personData
// person methods...
}
// data transfer object
class PersonData {
private String name;
private int age;
public PersonData(String name, int age){
this.setName(name);
this.setAge(age);
}
// getters and setters ...
}

More of a comment that an answer...
The article is dedicated to stablishing the need/advantages of loose coupling, and techniques to get it.
One of the points is avoiding relying in the internal data structure of an object, and only use its operators. In that point, automatically making your state accessible is bad, since objects using your classes may rely in these properties instead of using the more "refined" operations given to them.
From my understanding of the article, a possible example could be the following:
Imagine a Person class/interface with two operations, say, isOldEnoughToBuyBeer and isOldEnoughToDriveCars.
if you create in Person a setter/getter for dateOfBirth, then you are tying the implementations of Person to have such a property, and to implement the operations as "check current date agains dateOfBirth property and return true based in the number of years".
Of course, the statement "You should never use get/set functions for the same reason—they're just overly complicated ways to make a field public" may be too restrictive; while it is making a good point that even access through getters/setters has its consequences, it is hard to imagine that attributes are used only internally to the class that holds them.

You should definitely have getters for all the properties of the object you wish to expose to other objects. And if your object is mutable, you'll probably want setter methods for all the properties that can be modified.
set/get methods are not overly complicated ways to make a field public. They allow you to control the access and modification of your members.
For example, if your class is immutable, a get method that returns some object would return a clone of that object, to prevent the caller from modifing it.
For another example, if your class is mutable, a setter can contain validation of the new value you are trying to set.

The author argues that you should never have public instance variables. (Because they break encapsulation, but I believe you are not quiestioning this - if needed, though, we can get to it.)
When he says "You should never use get/set functions for the same reason" he's saying that, in practice, having public get and set methods for an instance variable is roughly* the same as having the varible itself public.
The only difference (and the reason why he writes "they're just overly complicated ways to make a field public"), is that instead of the modifier public in the instance variable, you created two additional methods.
(Data) Transfer Objects are a complete different animal, they aren't related to the discussed context.
* "Roughly" because we are talking about the (usual) hipothesis of the getter and setter just reading and writing to the instance variable, not doing any additional processing.

Correct way to expose instance variables to other classes
You should provide as low access to instance field as possible. The preferred way to provide access is to have three items
A private field
An public accessor method
An public mutator method
This Approach has following benefits
First benefit: This approach increases abstraction.
Suppose the getter(or accessor) method for Name is defined as follows
String getName() {
return name;
}
Now for some reason you want to change implementation of name as
String firstName;
String lastName;
In this case you can change getName() as
String getName() {
return firstName + " " + lastName;
}
Using this approach does not break your existing code which otherwise would be difficult(if not impossible) to obtain.
Second benefit: You can perform error checking all at once.
Consider a situation when the age entered by user is negative or practically impossible (like 99999999). In that case you can check such input in mutator method. This avoid manual checking and repetition of error check at different places
In addition it is advised that you should not write accessor method that return references to mutable object. This will break encapsulation. Use .clone() method of object class to return an object.

Related

Is it better to use getters or to access private members directly?

Which of the following is better? Is it even opinion-based or are there any relevant differences? Can one or the other be favored in some scenarios?
public class MyClass {
private Integer myField;
public void setMyField(Integer myField) {
this.myField = myField;
}
public Integer getMyField() {
return myField;
}
}
I need a method to check wether something is allowed or not. Please, let's not talk about the sense of this code example. It's just a minimal example.
Implementation 1
public boolean isAllowed() {
MyEnum.ALLOWED.getInt().equals(getMyField());
}
Implementation 2
public boolean isAllowed() {
MyEnum.ALLOWED.getInt().equals(myField);
}
Edit:
This post does not have an answer in the linked question (see comments to the initial post)
Which of the following is better? Is it even opinion-based or are
there any relevant differences? Can one or the other be favored in
some scenarios?
It is question of good practice I think. The difference is in the readability of the code.
As a general rule, you should avoid indirection if not required.
The current instance of MyClass has the information in one of these fields to implement the operation. It doesn't need to hide its internal state to itself. So in internal, MyClass has no valuable reason to favor the use of the getMyField() over the direct use of the myField field.
The getMyField() accessor is more suitable to be used by clients of the class.
So I think that it is better in any case in your example code :
public boolean isAllowed() {
MyEnum.ALLOWED.getInt().equals(myField);
}
Edit :
Beyond the readability, here is an example why you have no interest to couple the internal state to a public getter.
Suppose during the development phase you remove from the class the public getMyField() method because not need or not needed any longer for clients of the class, if isAllowed() relies on getMyField() in its implementation, it will be broken and you should replace it by myField.
My answer won't be the most informative however it will come from direct experience of dealing with this pattern. When designing an object it is often tempting to directly access member fields rather than rely on accessors. The desire stems from wanting to simplify the object and avoid adding clutter from methods that simple return a value. Taking your example a step further to add context & meaning:
public class MyClassmate {
private Integer age;
public MyClassmate(Integer age) {
this.age = age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getAge() {
return age;
}
}
Here age is a simple number and it appears unnecessary to add getters/setters around it. If we add the following method you would be tempted to directly access the field since there is no change in behavior:
public Integer calculateScore() {
if(age > 21) return 100 - getNumberOfIncorrectAnswers();
//Add 10% before for younger students
else return (100 - getNumberOfIncorrectAnswers()) + 10;
}
Your object may then grow new features with methods relying on the age field where you continue to use it directly. Later, you might alter the way age is originated and pull the value from across a network. You might not want to incorporate the networking logic in the constructor because it is an expensive operation which should only be triggered as needed. The calculateScore() method could make the network connection and discover the age but then too would all of the other methods that rely on age. But what if calculateScore looked as follows?:
public Integer calculateScore() {
if(getAge() > 21) return 100 - getNumberOfIncorrectAnswers();
//Add 10% before for younger students
else return (100 - getNumberOfIncorrectAnswers()) + 10;
}
You could then enhance the object changing the way it derives age without touching the calculateScore() method. This means your method follows Open Closed Principle (OCP). It is open for enhancement but closed to change, or you didn't have to change the method source in order to change where it gets the age.
Depending on the complexity of your app and object model there may still be times when encapsulated access is overkill but even in these scenarios it is good to understand the tradeoffs of direct field access and these more simplistic scenarios are mostly rare.
In general you should understand that the need for encapsulation is almost never immediate. It appears over time as the object grows and if the object is not setup with encapsulation from its onset it is more expensive to phase it in. That's what makes this approach so difficult to appreciate. It takes experience (i.e. making the typical oversimplification and suffering several times over several years) to feel why encapsulation is necessary. It is not something you can eyeball and detect.
That said, this used to be a much bigger problem than it is today when IDEs were not as full featured. Today you can use the built in encapsulate fields refactoring in certain IDEs like IntelliJ to introduce the pattern as you need it. Even with modern IDEs it is still favorable to practice encapsulation from the onset.
I would recommend using the getter because in certain scenarios, it can have some additional logic (like formatting, checking for nulls and so on). So you may be losing some logic when using the field itself.
To keep a good encapsulation, the first think you need to think is which methods are you going to expose outside your class, if here, for example you are going to use only the is allowed method, I would make public only that method, and define the field in the constructor, if the field is suitable to change then you will need getter/setters but always depends on what do you want to offer from your class. And keep as much encapsulated as you can.
public class MyClass {
private Integer myField;
MyClass(Integer myField){
this.myField = myField;
}
//Only this method is offered nobody need to know you use myField to say true/false
public boolean isAllowed() {
MyEnum.ALLOWED.equals(myField);
}
}
In my Software Engineering courses I was told to realize the "principle of secret". Thus, you should always use getter- and setter-routines. This way you can be sure that nobody accesses the member variable by accident.
Strange functions or objects may never see or even change member variables except you explicitly tell them to do so by setter and getters.
Due to your attribute being private, you can only securely access it within other class using getter or setter methods. So I would say that the best implementation is the one following the encapsulating principle, i.e., the one using the getter instead of accessing directly.
This will prevent data leaks as well.
https://www.tutorialspoint.com/java/java_encapsulation.htm

Why are private variables with handlers encouraged? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Are Getters and Setters evil?
I can't find a logical reason behind having a private variable with a getter and a setter that does nothing but directly handling the value being preferable to having a public variable.
Am I missing something?
Because,
Validation is one reason. Keeping the field name out of the public API also allows you to change it later without breaking the API. And it allows you to change the class later in other ways as well, e.g. moving the field to some other class (so that the public setter would call a setter in a different class). Having the setter called also allows you to do other things, e.g. notify interested other components of the change of value. None of this would be possible if the field was accessed directly.
They are preferred to future proof the code. In the future if you want to eliminate the variable or use another variable to derive this variables value - the change is simpler. You just need to change the getter/setter, the rest of the code remains unaffected. This is not the case with direct access to the variable.
As #user370305 already mentioned one reason is validation.
Other reason is types conversion. Setter may accept string and parse it to integer.
Yet another reason is data encapsulation. It is not necessarily to have a simple filed stored in the same class. Method setName(String) of class Person may store the name in more complicated data structure. Using simple field does not allow you to change the internal implementation of class Person without affecting code that uses it.
EDIT:
yet another technical reason.
It is much easier to discover and debug code with getters and setters. If some field is changed unexpectedly you can just toggle break point into appropriate setter and find the problem very quickly. If this field is public and you have 1000 references to this field you theoretically have to put 1000 breakpoints in all these places.
1. Encapsulation has different use in different context, In design patterns its like behaviors that keeps changing needs to be encapsulated in abstract class, or interface.
2. Having private instance variable and public getter setter is b
3. Its mainly done to Validate the input from the user... Setting the value to an instance variable directly is dangerous.
Eg:
int dogAge;
System.out.println("My dogs age is :"+dogAge);
Now what if someone gives a negative age... then.......???
So we must do it this way...
int dogAge;
public void setAge(int age){
if (age>0){
dogAge = age;
}
else{
System.out.println("Not a valid age");
}
}
public int getAge(){
return dogAge;
}
System.out.println("My dog age is :"+ getAge());
Its simple .. if you make those variable public then you give rights for ading any values to them .
But if you do that via getter or setter ... you can put checks over it and control the input or conversion without letting the end user know that
eg :
getName(){
return firstName+lastName;
}
or
getData(){
// code to convert byte to Mb or whatever you like to represent
}
Use of accessors to restrict direct access to field variable is preferred over the use of public fields, however, making getters and setter for each and every field is overkill and considerd as not a good practice. It also depends on the situation though, sometimes you just want a dumb data object. Accessors should be added for field where they're really required. See this link to know more about it Getter Setter: To Use or Not to Use.
I can't find a logical reason behind having a private variable with a getter and a setter that does nothing but directly handling the value being preferable to having a public variable.
Consider that any additional code that you put into getters and setters adds to complexity and also needs to be tested. For a small system which is fully controlled by you, there may be little benefit in using getters and setters. Use your professional judgement. You may not need the future proofing and added complexity. Or it may be more important to you to have the efficiency and simplicity of direct access.
Personally, I think that getters and setters are over-used. For a small system which is fully controlled by you, direct access may be the way to go.

Java setter and getter?

Everyone knows that Java supports data hiding.
I went for an interview. Then interviewer asked me that if Java supports data hiding by using private as datatype.
He said if we use setters and getters in that class then by using those setters and getters we can get that private data easily.
So how this is supporting data hiding here?
It may be possible that he was trying me catch me in trap. But I could not reply this.
What should I reply for this?
He was arguing that if "Data Hiding" is an OOP principle then aren't we breaking it by exposing via getters and setters. I think he wanted you to spell out the difference in principle between being able to access a data member directly vs. doing it via a getter or setter. In the former case a client of the class can mishandle the data, assign it a value that the class designer has not designed the class to handle (for example set the age of a student as 500).
In the latter (using a setter) the class designer has imposed certain restrictions on what values can be assigned to the data. In the age example the setter might be something like:
void setAge(int age) {
if(age<3 || age>100)
return;
this.age=age;
}
assuming that students of age below 3 and over 100 aren't allowed. So you are still hiding your data but allowing means to manipulate it in a way consistent with the logic of your module.
Very simple Example:
Version 1 of class could have getter like this.
public int getTotal() {
return total_;
}
Version 2 could do this
public int getTotal() {
return a + b;
}
We've changed how the class is implemented, but clients of the class don't need to change as well, because the data is hidden behind a getter.
Data hiding is bad term, better say data encapsulation. In java access to private members is done through accessors and mutators ( getter and setter), it is all about hiding and controlling access to your members so you can control how inner state of instance will be modified.
I think if you mention something about java reflection / metadata -> you will get bonus points
The class fields are hidden, if we declare them private. No doubt (we ignore nasty reflection tricks). If we want to make the values accessible, we provide access methods (getter/setter for example).
But there is no requirement to provide getters and setters for all fields or to name them according to fields (in general).
The class internals (the fields) are perfectly hidden.
protected String name;
public void setName(String newName){
if(newName.length() > 5) this.name = newName
}
public String getName(){
return this.name;
}
In this simple case the name attribute can be accessed by its name in this class and in all its children. If you want to set the value of name from an unrelated class than you will have to use the setName() method where you can apply some validation for example.
Here you can find any information you need about this special methods.
Be aware that any property of a class can be accessed if the mutators and accessors are public. This is one of the key points of the Java Bean concept and almost all java frameworks relate to this concept at one point or another.
What you are talking about seems to be Encapsulation. Basically the getters and setters allow you to expose class variables as you like and hide any others. Getters and Setters also allow you to perform any other necessary steps such as validation.
Getters and Setters can have different access modifiers themselves, so you can expose data to certain classes but not others by using different access modifiers.
I bet he was waiting that you will refer to "immutable" types also.
PD. private is no type, it is an access modifier.
The support for "data hiding" can be explained by the fact that the getter and setter methods are like gateways to the data.
It is only by convention - the JavaBeans convention to be exact - that it is expected from them to operate on the member they are named after. They could do anything else and it would still be perfectly compilable and legal java.
Maybe, he mean Encapsulation as information hiding.
If you make the setter & getter public/protected/default, then you could access the private members on different levels .. if you make setter&getter private then the data is really hidden. This last way to go makes no sense at all though
You may think about implement set/get methods in many different ways.
As some answers already pointed out, set/get don't have to actually set or return actual members.
For example, let's say you have a Coordinate class with set/get for (x, y). The inner implementation might be based on polar coordinates:
private double radius;
private double angle;
and the get/set for (x, y) do some coordinate transformation with sin and cos.
You could change the implementation of the class to any other system of coordinate at will and still just keep the set/get for (x, y) as public methods.
So, to sum up, my answer to the question would be: the public interface of a class might provide set/get, but the actual implementation can (and should) be hidden by making all members private (or protected). So we could say that having public set/get on private data is "implementation hiding" rather than data hiding.
Data Hiding and Encapsulation are frequently mistaken for security by first time oops learners. Its important to understand that data hiding and encapsulation have nothing to do with security.
These concepts exist to ensure that inheritance of a class A, from class B (class B extends A) does not inherit the "encapsulated" members.
I hope this kinda clarifies your confusion, and also motivates you to read and study more. Your question is very basic to the OOPS concepts. And the interviewer is not trying to corner, you but ask you very basic questions on OOPS. Study hard!!!

Why are instance variables in Java always private?

I'm newbie to Java and I'm learning about encapsulation and saw an example where instance variables are declared as private in a class.
http://www.tutorialspoint.com/java/java_encapsulation.htm
I have 2 queries:
Why are instance variables private? Why not public?
What if instance variables are made public and accessed directly? Do we see any constraints?
Can you explain with an example as to what will go wrong in case the instance variables are declared as public in a class in Java?
Instance variables are made private to force the users of those class to use methods to access them.
In most cases there are plain getters and setters but other methods might be used as well.
Using methods would allow you, for instance, to restrict access to read only, i.e. a field might be read but not written, if there's no setter. That would not be possible if the field was public.
Additionally, you might add some checks or conversions for the field access, which would not be possible with plain access to a public field. If a field was public and you'd later like to force all access through some method that performs additional checks etc. You'd have to change all usages of that field. If you make it private, you'd just have to change the access methods later on.
If phone was private:
Consider this case:
class Address {
private String phone;
public void setPhone(String phone) {
this.phone = phone;
}
}
//access:
Address a = new Address();
a.setPhone("001-555-12345");
If we started with the class like this and later it would be required to perform checks on the phoneNumber (e.g. some minimum length, digits only etc.) you'd just have to change the setter:
class Address {
private String phone;
public void setPhone(String phone) {
if( !isValid( phone) ) { //the checks are performed in the isValid(...) method
throw new IllegalArgumentException("please set a valid phone number");
}
this.phone = phone;
}
}
//access:
Address a = new Address();
a.setPhone("001-555-12345"); //access is the same
If phone was public:
Someone could set phone like this and you could not do anything about it:
Address a = new Address();
a.phone="001-555-12345";
If you now want to force the validation checks to be performed you'd have to make it private and whoever wrote the above lines would have to change the second line to this:
a.setPhone("001-555-12345");
Thus you couldn't just add the checks without breaking other code (it wouldn't compile anymore).
Additionally, if you access all fields/properties of a class through methods you keep access consistent and the user would not have to worry about whether the property is stored (i.e. is a instance field) or calculated (there are just methods and no instance fields).
They don't have to be private - but they should be. A field is an implementation detail - so you should keep it private. If you want to allow users to fetch or set its value, you use properties to do so (get and set methods) - this lets you do it safely (e.g. validating input) and also allows you to change the implementation details (e.g. to delegate some of the values to other objects etc) without losing backward compatibility.
First, it is not true that all instance variables are private. Some of them are protected, which still preserves encapsulation.
The general idea of encapsulation is that a class should not expose its internal state. It should only use it for performing its methods. The reason is that each class has a so-called "state space". That is, a set of possible values for its fields. It can control its state space, but if it exposes it, others might put it in an invalid state.
For example, if you have two boolean fields, and the class can function properly only in 3 cases: [false, false], [false, true], and [true, false]. If you make the fields public, another object can set [true, true], not knowing the internal constraints, and the next method called on the original object will trigger unexpected results.
Making instance variables public or private is a design tradeoff the
designer makes when declaring the classes. By making instance
variables public, you expose details of the class implementation,
thereby providing higher efficiency and conciseness of expression at
the possible expense of hindering future maintenance efforts. By
hiding details of the internal implementation of a class, you have the
potential to change the implementation of the class in the future
without breaking any code that uses that class.
Oracle White Paper
Like has been pointed out by several answerers already, instance variables don't have to be private, but they are usually at the very least not made public, in order to preserve encapsulation.
I saw an example in (I think) Clean Code, which very well illustrates this. If I recall correctly, it was a complex number (as in a+bi) type; in any case, something very much like that, I don't have the book handy. It exposed methods to get the value of the real and imaginary parts as well as a method to set the value of the instance. The big benefit of this is that it allows the implementation to be completely replaced without breaking any consumers of the code. For example, complex numbers can be stored on one of two forms: as coordinates on the complex plane (a+bi), or in polar form (φ and |z|). Keeping the internal storage format an implementation detail allows you to change back and forth while still exposing the number on both forms, thus letting the user of the class pick whichever is more convenient for the operation they are currently performing.
In other situations, you may have a set of related fields, such as field x must have certain properties if field y falls inside a given range. A simplistic example would be where x must be in the range y through y+z, for numerical values and some arbitrary value z. By exposing accessors and mutators, you can enforce this relationship between the two values; if you expose the instance variables directly, the invariant falls apart immediately, since you cannot guarantee that someone won't set one but not the other, or set them so that the invariant no longer holds.
Of course, considering reflection, it's still possible to access members you aren't supposed to, but if someone is reflecting your class to access private members, they had better realize that what they are doing may very well break things. If they are using the public interface, they might think everything is fine, and then they end up with nasty bugs because they unknowingly did not fully adhere to the implementation details of your particular implementation.
In traditional Object-Oriented design, a class will encapsulate both data (variables) and behavior (methods). Having private data will give you flexibility as to how the behavior is implemented, so for example, an object could store a list of values and have a getAverage() method that computes and returns the mean of these values. Later on, you could optimize and cache the computed average in the class, but the contract (i.e., the methods) would not need to change.
It has become more popular the past few years (for better or worse) to use anemic data models, where a class is nothing but a bunch of fields and corresponding getters and setters. I would argue that in this design you would be better off with public fields, since the getters and setters provide no real encapsulation, but just fool you into thinking you are doing real OO.
UPDATE: The example given in the link in the question is a perfect example of this degenerate encapsulation. I realize the author is trying to provide a simple example, but in doing so, fails to convey any real benefit of encapsulation (at least not in the example code).
Because if you change the structure of the class (removing fields etc.); it will cause bugs. But if you have a getX() method you can calculate the needed value there (if field was removed).
You have the problem then that the class does not know if something is changed and can't guarantee integrity.
Well keeping fields private has many advantages as suggested above.
Next best level is to keep them package private using java default access level.
Default level avoid cluttering in your own code and prevents clients of your code from setting invalid values.
For user of class
We, who are using ide like eclipse, netbins.....
saw that it suggest us for public method, so if creator of class provide getter and setter for private instance variable you do not have to memorize the name of variable. just write set press ctrl+space you are getting all of setter method created by creator of that class and choose your desired method to set your variable value.
For creator of class
Sometimes you need to specify some logic to set variable value.
"suppose you have an integer variable which should store 0

When to use get/set Methods in java [duplicate]

This question already has answers here:
Why use getters and setters/accessors?
(37 answers)
Closed 6 years ago.
I want to know when to use get and set methods(getName,setName ) in my class and when simple classVariable.name = "" instead а = classVariable.getName()
Here is example of class using set and get methods
public class ClassExampe {
String name;
String course;
public String getName ( )
{
return name;
}
public void setName (String studentName)
{
name = studentName;
}
public String getCourse ( )
{
return course;
}
public void setCourse (String studentCourse)
{
course = studentCourse;
}
}
Thanks
Using Getters / Setters vs using Fields
As a rule of thumb:
use the variables directly from the same class (actually from the same .java file, so inner classes are ok too), use Getters / Setters from other classes.
The simple rule is: never use direct access (except, of course, when referring to them from inside the class).
field access can't be proxied
you may want to have some event notification
you may want to guard against race conditions
expression languages support setters and getters
theoretically this breaks encapsulation. (If we are pedantic, setter and getter for all fields also breaks encapsulation though)
you may want to perform some extra logic inside the setter or getter, but that is rarely advisable, since consumers expect this to follow the convention - i.e. being a simple getter/setter.
you can specify only a setter or only a getter, thus achieving read-only, or write-only access.
Even if this does not happen that you need any of these, it is not unlikely. And if you start with field access, it will be harder to change.
In Java, using a getter and setter is usually considered best practice.
This is because if you ever need to change your code to do something else when a property is accessed or modified, you can just change it in the existing getter or setter.
I tend to think it causes a bit of clutter for simple objects, but if you have ever had to refactor a public property to a getter and setter to add additional functionality you will see that it can be a pain.
I suspect most will say to always use getters/setters to access private members. It's not necessary, but is considered a "best practice".
One advantage is that you can have more than just simple assignment and returning. Example:
public void setLevel(int lvl)
{
if (lvl<0)
{
this.level=1;
}
else
this.level = lvl;
}
public int getLevel()
{
if (this.someIndicator==4)
return this.level*7.1;
else
return level;
}
Getters and Setters allow you to change the implementation later (e.g. do something more complex), allow you to implement validation rules (e.g. setName throws an exception if the name is not more than 5 characters, whatever.)
You could also choose to add a getter but not a setter so that the variable is like 'read-only'.
That's the theory, however in many cases (e.g. Hibernate using setters) you cannot throw exceptions in setters so you can't do any validation. Normally the value will just be assigned/returned. In some companies I've worked at, it's been mandatory to write getters and setters for all attributes.
In that case, if you want to access an attribute from outside an object, and you want it to be readable/writable, I just use a public attribute. It's less code, and it means you can write things like obj.var += 5 which is easier to read than obj.setVar(obj.getVar() + 5).
If you mean: when to use public accessor methods instead of making the internal, private variable public my answer is "always" unless there is a severe performance reason.
If you mean, call your own get and set methods vs direct access to the vars w/in your class I still say call your own access methods. This way, any conversion, edits or rules you implement as part of get/set get invoked automatically by your own internal calls as well as external callers.
In pure OO languages (for example, Smalltalk) there is no concept of public - all internal vars are private and so you must use accessors. In less pure OO languages, you can make things public - however exposing the internals of your data structures and implementation is an exceptionally bad idea for stability and maintenance in the long run. Look up "tight coupling" for more on this.
Simply put, if you expose internal vars publicly, people can access them directly and if you ever change name or type everything down the line breaks. This is called side effects.
Its a matter of taste, but generally speaking you always should use get/set methods for all properties that are public. But for things like Value Objects (VOs) that you probably are not going to be bothered with for some time you can use public variables without getting too much criticism I think.
In general, you'd want to use setters and getters to give the opportunity to developers reusing your code by modifying it or extending it to add layers of processing and control when accessing and modifying your internal data. This wouldn't be possible in Java when using direct accesses.
Parenthesis: However, it's perfectly possible in other languages, for instance in Scala, when the line between properties and methods can become quite fine. And it's great, as then it doesn't become a coding-problem that gets in the way and it makes usage more transparent.
You can also often consider that in your class you can feel free to access your internal (private or protected) members directly, as you're supposed to know what you're doing, and you don't need to incur the overhead of yet another method call.
In practice, multiple people working on a class might not know what everyone's doing and those lines of integrity checking in your getters and setters might be useful in most cases, while the micro-optimization may not.
Moreover, there's only one way for you to access a variable directly, whereas you can define as many accessors as you want.
Encapsulate the private fields of a class and expose them with getter/setter classes the way you want to.

Categories

Resources