Avoiding setter to change value of class's property

I have a class with one private field:

class Person {
  string name;
  public void setName(string name);
}

Then, using some object which is responsible for interacting with user (in this example by command line), I want to change the value of this field:

Person somePerson;
CommandLineView view;
somePerson.setName(view.askUserForName());

It works. But I don't like using set function as it exposes class members. Therefore I started looking how to avoid it.

New implementation looks like this:

class Person
{
  string name;
  public void changeName(view) { name = view.askUserForName(); }
}

and:

Person somePerson;
CommandLineView view;
somePerson.changeName(view);

Now Person does not expose its member. Moreover this class is responsible for logic related to changing name (for example function changeName could also update database, notify interested parties etc.

The question is: Is such kind of refactoring a good practice? Or maybe implementation with setter was better, even if it break encapsulation?

Upvotes: 1

Views: 629

Answers (1)

Borys Serebrov
Borys Serebrov

Reputation: 16172

I think there should be no method to set the name at all, it should be a constructor parameter:

Person somePerson(view.askUserForName());

Problem with your approach is that you first create the object which is not fully initialized, so is dangerous to use: Person somePerson. What if you forget to setName? Will your code still work with this "empty" person?

And then you allow to directly modify the internal state with setName method, which is also not good.

Using the constructor parameter you avoid both of these problems.

As for the original question - I don't think there is big difference between the two methods. The result is exactly the same - you call the method and the internal object state changed. You can name it setName or changeName, result is the same.

The second method with changeName(view) actually is worse because you also introduce the dependency of the Person on the View object. Now, if you want to change the name, you always need to create the View object first.

Upvotes: 1

Related Questions