(주의! Getter, Setter 은 접근 제한자의 종류가 아니라, 접근/통제하는 수단)
// “A + 10 을 실행해야 해, A 값을 줘.” (X)
A.getValue() + 10
// “A에 10을 더해줘” (O)
A.add(10)
객체는 내부 데이터 구현을 노출하면 안된다.
그러나, Getter/Setter 는 내부 데이터와 구현을 노출시키므로
유지보수에 악영향을 미친다.
'구현 은닉'
즉, 클래스의 구현 방식을 마음대로 바꾸어도 외부에 영향을 미치지 않아야 한다.
이는 어떠한 작업을 수행하는데 필요한 정보를 요구하지 않고, 정보를 가진 객체가 일을 대신하게 만들면 된다.
Getter 메소드는 해당 필드의 값을 읽을 수 있는
메소드
필드 값을 외부에서 가져갈 수
있다암묵적인 규칙으로 다음과 같이 메서드의 이름을 명명한다
이런 코드가 주어진다고 가정해보자.
여기서 age 와 name 을 제외한 다른 필드값들을 숨기고 싶다면
class Application {
public static void main(String[] args){
Person jinhwan = new Person();
}
}
class Person {
int age; // 필요한 정보
int name; // 필요한 정보
String hobby;
int hobby_id;
String school;
int school_id;
String phoneNumber;
int gender;
int pw;
}
이는 은닉성
과 관련있다. (참고: OOP (Object-Oriented Programming, 객체 지향 프로그래밍) - 1) 캡슐화 (Encapsulation))
모든 필드에 private 제한을 걸어 해당 클래스 안에서만 노출되도록 만든다.
그리고 필요한 정보(age 와 name) 에만 Getter 메서드를 사용해서 외부에서 조회할 수 있도록 한다.
class Person{
// private을 사용해서, 해당 클래스 안에서만 노출되게 하여 변수의 접근을 제한함 (변수들의 외부 노출을 제한)
private int age;
private int name;
private String hobby;
private int hobby_id;
private String school;
private int school_id;
private String phoneNumber;
private int gender;
private int pw;
public int getAge() { // 필요한 정보 age를 getter을 이용해서 드러냄
return age;
}
public int getName() { // 필요한 정보 name을 getter을 이용해서 드러냄
return name;
}
public void setAge(int age) {
if(age >=0){
this.age = age;
}
else
this.age = 0;
}
}
@Getter
해당 필드에 대한 Getter 메소드를 자동으로 생성
@Getter 를 사용한다면, getXXX() 로 일일이 코드를 작성해줘야하는 불편함을 줄일 수 있다
Getter 메소드만으로 외부에서 객체의 상태를 변경하지는 못하지만, 그 결과값이 객체의 상태를 변경시키는데에 사용될 수는 있다.
객체는 독립적이어야하는데, Getter 를 통해 로직 처리를 하는 메소드가 많아 질수록 Getter 에 대한 의존성은 매우 높아질 것이다.
Getter 를 통해 얻은 상태값으로 하려고 했던 행동을
그 상태값을 가진 객체가 하도록 행동의 주체를 옮긴다.
값을 비교할 때 get을 사용해 객체의 변수를 꺼내와서 비교했다면,
isSame()과 같은 메소드를 객체에 위치시켜 비교하고자 하는 값을 메소드의 파라미터로 넘겨 객체가 판별하도록 하는 것이다.
Setter 메소드는 해당 필드의 값을 설정할 수 있는
메소드
필드 값을 외부에서 변경할 수
있다암묵적인 규칙으로 다음과 같이 메서드의 이름을 명명한다
메소드가 매개값 검증을 하고, 유효한 값만 객체의 필드에 저장하기 때문
변수의 값 대입이 여러 곳에서 제한 없이 가능한 것을 접근 제한자로 막고,
접근 범위에 한해서 메소드로 대입전 값을 처리 후 대입되게 하기 위해
Setter 를 사용하지 않은 경우
코드가 더 복잡해진다면, 다른 메소드에 의해 값이 변경 or 이상한 값이 age에 들어오는 문제가 발생할 수 있음
class Application {
public static void main(String[] args) {
Person jinhwan = new Person();
jinhwan.age = -1;
jinhwan.howOld();
}
}
class Person {
int age;
void howOld() {
System.out.println(age);
}
}
Setter 를 사용한 경우
class Application{
public static void main(String[] args) {
Person jinhwan = new Person();
jinhwan.setAge(-1); // 메소드를 이용해서, age에 -1을 대입
jinhwan.howOld();
}
}
class Person{
private int age; // private을 사용하여, 직접 값 할당을 못하게 제한
public void setAge(int age) { // 메소드를 이용해서, age에 -1을 대입
if (age >= 0) {
this.age = age;
} else {
this.age = 0;
}
}
void howOld() {
System.out.println(age);
}
}
@Setter
@Data = @Getter + @Setter + @RequiredArgsConstructor + @toString + @EqualsAndHashCode
모든 필드를 대상으로 접근자와 설정자가 자동으로 생성되고 (@Getter, @Setter),
final 또는 @NonNull 필드 값을 파라미터로 받는 생성자가 만들어지며 (@RequiredArgsConstructor),
toStirng, equals, hashCode 메소드가 자동으로 만들어진다 (@toString, @EqualsAndHashCode)