I often hear people say, "I'm tired of writing getter / setter methods one by one, but why should I write them? Where should I write them after all?", So I wrote an article.
(100% guarantee that Masakari will fly)
In addition, here, words with similar properties such as fields, instance variables, properties, and member variables are not used properly, but are collectively called fields. In addition, methods, member functions, etc. are also collectively referred to as methods.
First, I will briefly explain how the concept of getter / setter method was born.
One of the properties of object-oriented programs is polymorphism. This is, for example
--In Smalltalk, no matter what object the receiver is, you only have to worry about being able to respond to the messages you send. --In Java, if the object implements a specific Interface, you can call the method of the specific Interface of that object without worrying about the implementation.
It is the nature.
In other words, you are programming for the interface, not the implementation. This makes it possible to reduce the cost of software development.
When programming an interface, that is, writing a program that maximizes implementation dependencies, the most important thing is to make the concrete implementation inaccessible (encapsulation). Fields are just included in the internal implementation, so we need to provide an alternative method to prevent them from being accessed directly from the outside. This creates a pattern that "for a specific field, we will prepare a method to acquire the data from the outside or a method to change the data from the outside". The methods that corresponded to this pattern were later called "getter / setter methods".
Writing an example of using the getter / setter method in Java looks like this
class User{
private String name;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
This is the one you often see.
By the way, I think Smalltalk best reflects the concept of encapsulation and getter / setter methods. This is because in Smalltalk, the access modifier of an instance variable (in Java etc.) cannot be changed from protected.
Object subclass: #User
instanceVariableNames: 'name'
User>>name
^ name
User>>name: aName
name := aName
Here, Smalltalk, or its affiliated OOPL setter / getter methods, are in the form name, name: as in the example above, unlike common styles. (It's really beautiful ...)
The getter / setter method also has the disadvantage of making the code redundant. In the example below, defining just three fields would make the code bloated.
class User{
private String name;
private int age;
private boolean isAdmin;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
public boolean getIsAdmin(){
return isAdmin;
}
public void setIsAdmin(boolean isAdmin){
this.isAdmin = isAdmin;
}
}
Here are some cases where it is better not to define getter / setter methods.
PI (Persistence Ignorance) is a pattern of a class that "behaves as a mere structure". Also known as POJO (Plain old java object). Using this pattern, the above Java code can be rewritten as:
class User{
public String name;
public int age;
public boolean isAdmin;
}
In a simple struct, the field itself behaves as an interface, so you don't have to write redundant setter / getter methods, and it's okay to write it this way in an object-oriented program.
This pattern is often used in model classes and the like.
ActiveRecord, such as Ruby on Rails and Laravel, allows you to dynamically access fields that aren't defined in your code.
For example, in Laravel
class User extends Model{
}
$user = User::first();
$user->id; //1 or something
$user->name; //ogiwara
Of course, you don't need to define getter / setter methods in such cases.
By the way, even if it is not defined in the code, if it is PHP, @property etc. is PHPDoc If you write in, you can get hinting support from IDE etc., so write as below.
/**
* @property int $id
* @property string $name
*/
class User extends Model{
}
Kotlin, C #, etc. have language specifications that make it easier to write getter / setter methods. In Kotlin, consider creating the same User model created in Java above.
class User{
public name: String
public age: Int
public isAdmin: Boolean
}
Here, when changing the specifications such as "to leave a log when the name field is accessed", just rewrite as follows.
class User{
public name: String
get(){
println("The name was accessed")
name
}
public age: Int
public isAdmin: Boolean
}
In other words, "the processing can be extended later for the acquisition and modification of fields." This feature can also serve as a field delegation, as follows:
class User{
private realName: String
public name: String
get(){
realName
}
set(value){
realName = value
}
}
This feature is provided in Kotlin, C # under the name "getter / setter".
I'm most happy with language specifications that can be extended later, such as Kotlin and C #.
Recommended Posts