Java의 Getter&Setter? Builder?

nGyu·2022년 2월 3일
0
post-thumbnail

Java 에서는 객체지향 특성 중 외부에서 직접적으로 Class 내부의 변수에 접근할 수 없게끔하는 은닉성 이라는것이 존재한다.
이러한 은닉성 때문에 직접적으로 변수의 값을 변경하거나 조회할 수 없는데, 이를 위해 Getter와 Setter가 존재한다.

Getter & Setter

사용방법

public class conter{
	private int count = 1
}

이런 형식의 카운터 클래스가 있다고 가정해보자.
여기서, private 로 선언이 되어있기때문에 외부 클래스에서는 해당 count 변수를 직접적으로 접근하여 수정/조회를 할 수 없다.

어떻게 해야하나?
바로 Getter와 Setter를 이용하면 된다.

Getter

Getter 이 단어를 보면 무엇이 생각나는가?
우리가 수정/조회를 위해 Getter 와 Setter를 사용한다고 했으니, 조회를 위한 메서드라고 할 수 있을것이다.
선언하는 방법은 아래와 같다

public class Conter{
	private int count = 1
    
    public int getCount() { return this.count; }
}

이런 형태로 해주면 된다.
여기서, 메서드 이름을 짓는 룰이 있는데 이는 get+변수명 으로 선언을 해주면 된다.
this는 뒤에서 다시 알아보도록 하겠다.

그럼 다른 클래스에서 이 Getter를 불러오기 위해서는 어떻게 해야하나?
아래처럼 하면 된다.

Conter counter = new Counter();
counter.getCount();

Setter

Setter도 위와 다를게 없다.

public class Conter{
	private int count = 1
    
    public int getCount() { return this.count; }
    public void setCount(int count){
    	this.count = count
    }
}

Setter는 리턴값이 없어 void 형식으로 선언을 해 주고, count 의 변수값을 setter를 통해 가져온 변수값으로 다시 초기화를 시킨다.
메서드의 이름은 Getter와 같은 룰을 가지고 있는데, set+변수명 으로 지어주면 된다.

다른 클래스에서 사용을 할 때 Getter와 똑같이 사용해주면 된다.

Conter counter = new Counter();
counter.setCount(10);

this

Getter와 Setter를 하면서 this라는 키워드가 계속 보이는데 도대체 이 this는 무엇일까?

this = 객체 바로 자기자신

이게 무슨소리인가 싶을것이다.
Java는 객체단위의 프로그래밍을 한다고 하는데, 우리는 위 예시를 통해 Counter라는 객체를 만들고 이 객체 안에 변수를 선언을 하였다. 다시 보자면 Counter내부에서 this를 사용하게 되면 해당 객체에 선언된 변수, 메서드 등을 호출할 수 있게 되는것이다.

this.count = 10; // 객체 내부 변수
this.increaseNumber(1); // 객체 내부 메서드
this(10,1) // 해당 객체의 생성자

위와같은 형식으로 변수에 접근할 수 있고 메서드에도 접근할 수 있으며, 생성자까지도 접근할 수 있다.

return this.count;

이런식으로 접근한 변수의 값을 반환해주는것도 가능하다.

Builder

자, 여태 Getter&Setter를 알아보았고, 여기서 사용하는 this에 대해서도 알아보았다.
그런데 만약 변수가 많아진다면 어떨까?

public class User{
	private String userName;
    private String userEmail;
    private int userAge;
    private String phoneNumber;
    private boolean permission;
    private int userNumber;
}

이런 형태의 객체가 있다고 해보자.
그럼 Getter 6개 Setter 6개 총 12개가 된다. 이렇게 보면 코드가 얼마나 길어질까?
진짜 엄청나게 길어질것이다.
지금은 6개로 예시를 들었지만, 한 객체에서 관리하는 변수가 많아질수록 더 길어질 수 있다.

생성자를 사용하면 되기에 길어지는것은 큰 문제가 아닐 수 있다.
하지만, 동적으로 값을 넣어줘야한다고 생각을 해 보자.

User user = new User("홍길동","mail@mail.com",23,"010-1234-5678",false,2931);

생성자를 이용해서 이렇게 넣어줄 수 있다.
자, 그런데 핸드폰 번호가 없는사람이 있을 수 있다.
그리고 permission 의 경우 true가 아니라면 궂이 넣어주지 않아도 될 수 있다.
그렇다면 이를 위해서 생성자를 만들때 userEmail과 permission은 넣지 않고 추가로 작성을 하면 될까?
물론 문제가 될건 없다.

그런데 필자가 왜 Builder를 들고나왔는지 자세히 알아보자.

Builder Pattern

우선, Builder의 장점을 보도록 하겠다.

  1. 필요한 데이터만 설정이 가능하다.
  2. 코드의 가독성이 높아진다.
  3. 불변성을 확보할 수 있다.
  4. 더욱 유연한 코드 작성에 용이하다.

장점들을 먼저 보니 무슨소리인가 싶을것이다.
우선, Builder Pattern을 적용한 코드를 보도록 하겠다.

public class User{
// 생략
	public class UserBuilder{
		private String userName;
		private String userEmail;
		private int userAge;
		private String phoneNumber;
		private boolean permission;
		private int userNumber;

		//바로 아래 UserBuilder 메서드는 꼭 필수로 입력해야하는 필드가 있을 경우
        //필수로 받을 수 있도록 하기 위해 선언한다.
		public UserBuilder(int userNumber) {
        	this.userNumber = userNumber;
        }
 		public UserBuilder setUserName(String userName){
            this.userName = userName;
            return this;
        }
        public UserBuilder setUserEmail(String userEmail){
          this.userEmail = userEmail;
          return this;
        }
        //위와같은 패턴으로 작성하면 됩니다.
        //생략
        public User build(){
          return new User(this)
       	}
	}
}

주석과 함께 사용방법에 대해 작성을 해 보았다.
이런식으로 빌더 패턴을 제작할 수 있는데, 이를 통해 더욱 깔끔한 코드를 사용할 수 있게된다.
그럼 이 코드를 어떻게 사용하면 되는지 또 궁금할것이다.
아래와같이 사용을 하면 된다.

User user = new User.UserBuilder(123123)
					.setUserName("홍길동")
                    .setUserEmail("mail@mail.com")
                    .setUserAge(23)
                    .build();
user.getUser();

이런식으로 사용해주면 된다.


점층적 생성자 패턴을 이용해 육안상 동적으로 받게할 수는 있지만, 이는 객체 내의 변수가 새로 생기면 모든 생성자를 수정해야는 문제점이 있고,
setter를 하나하나 다 적용을 해주면 가독성이 굉장히 떨어지게 된다.

그런데 실제 예제를 통해 확인을 하니 뭔가 이상하다
빌더패턴을 적용하고 나서 객체의 코드가 굉장히 길어보인다.
이는 Lombok으로 해결할 수 있는데, 다음에 다시 알아보도록 하겠다.

profile
지금보다 내일을, 모레를 준비하자

0개의 댓글