문득 getter,setter 제네레이터를 통해 VO,DTO를 만들고 왜 이렇게 사용할까?하는 생각이 들었다.
getter ,setter를 만드는건 제네레이터가 해주기 때문에 쉽게 만들 수 있고 값을 받아오고 입력해줘서
DB와 DAO를 연결해준다는 느낌으로 사용하고 있었다.
일단 getter,setter를 사용하는 이유는 클래스의 필드에 직접 접근하는걸 막기 위해서다.
자바는 고수준(High Level)의 언어인데, 고수준이라는것은 개발자들이 어떤 이론의 밑바닥까지 알 필요가 없다는 것을 의미한다.
JAVA를 이용해서 네트워크 통신을 할때 http나 패킷에 대한 것을 몰라도 개발은 할 수 있다.
자세한 것들은 JAVA가 제공하는 클래스들이 알아서 하기 때문에,
개발자는 좀 더 자유롭게 자신이 원하는 기능을 만들 때에 제약이 줄게된다.
마치 운전자들이 자동차의 작동원리를 몰라도 키를 뽑아 시동을 걸고 기어를 바꾸고 엑셀과 브레이크, 핸들을 움직일 수 있으면
운전을 할 수 있다는 것이다.
운전자들은 엔진이 어떤 원리로 돌아가고 기어조작이 어떤 원리로 작동되는지 알 필요가 없다.
개발자를 자동차 정비사로 비유해보자.
자동차 정비사들이 자동차 부품을 직접 만들줄 알아야 정비를 할 수 있는건 아니다.
자동차의 '부품'의 기능과 종류만 알고 있으면 되니까..
물론 그 이상 자세히,깊히 이해하게 된다면 정비의 수준을 넘어 부품을 직접 만들고 설계 할 수 있을 것이다.
자바는 객체지향 언어이고, 객체지향은 '부품화'의 정점이다. 메소드는 부품화의 예라고 할 수 있겠다.
연관된 로직들을 결합해서 메소드라는 완제품의 파츠들을 만들고,
이 메소드들을 부품으로 하나의 완제품인 독립된 객체를 만드는 것이다.
부품화는 독립된 객체들을 모아 만드는 것만은 아니다.
제대로 된 부품이라면 어떻게 만들어졌는지 모르는 사람도 그 부품을 사용하는 방법만 알면 쓸 수 있어야한다.
다시 자동차를 예로들어 배터리가 어떻게 만들어졌고 어떤 원리인지 몰라도 배터리가 나가서 시동이 안걸리면
배터리를 사서 -+를 연결해서 교체하고, 점프선을 연결해서 시동을 걸 수 도 있다.
즉, 내부의 동작 방법을 안으로 숨기고 사용자에겐 그 부품의 사용법 만을 노출하고 있는 것이다.
따라서 객체의 데이터는 함부로 공개하지 않는다.
그래서 사용하는것이 getter와 setter이다.
getter setter는 객체의 데이터에 직접 접근하지 않고 메소드를 통해 데이터에 접근,변경한다.
그런데 왜 클래스의 필드에 직접 접근하면 안될까?
public class VO {
public String a;
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
}
위와 같은 코드가 있다 get,set이 있지만 private로 선언하는 원래 방식과 다르게
public으로 선언을 했기 때문에 외부 클래스에서 접근이 가능하다.
EX)
다른 클래스에서
VO vo=new VO();
vo.a = "hello"
라고 하면
VO객체의 a에는 hello가 객체에 직접 저장된다.
예제를 통해 확인해보자.
내가 라이브러리를 제작 후 배포를 하는 사람이라고 했을 때,
사용자는 vo.a = "hello"로 객체에 직접 저장할 수도 있지만, vo.setA("hello")로 변수 a에 값을 저장 할 수도 있다.
public class Run {
public void setA(VO vo,String param) {
vo.setA("입력한 값은?=" + param);
}
위의 VO와 Run이라는 라이브러리를 제작 후 배포했다고 가정하자.
이 라이브러리는 "입력한값은?=" 이라는 문자열에 사용자가 입력하고자 하는 스트링값을
"입력한 값은?= / [사용자가 입력한 파라미터(스트링값)] " 이렇게 받을 수 있는 의도로 설계했다.
public class Getset {
public static void main(String[] args) {
VO vo = new VO();
Run run = new Run();
run.setA(vo,"aaa");
System.out.println(vo.getA());
vo.a = "bbb";
System.out.println(vo.getA());
}
}
자신이 입력한 문자앞에 문자열을 붙이고 싶어 하는 어떤 사용자는
내가 만든 라이브러리인 VO와 Run을 사용해 (원래라면 라이브러리 사용을 위해 import해야하지만 생략한다)
"입력한 값은?=" 이라는 문자열을 입력한 값 앞에 출력하고 싶다.
사용자는
aaa와 bbb라는 파라미터를 입력했다.
aaa는 get,set 메소드를 통해서 aaa를 입력했고
bbb는 직접 입력했다. (원래는 VO(get&set)를 private로 선언해서 이것이 불가능하다)
결과는
입력한 값은?=aaa
bbb
이다.
이것이 무엇이 잘못됐는가?
내가 만든 라이브러리는 결국 틀이다. 라이브러리는 클래스라는 틀을 이용해서 만든 객체이다.
그런데 "입력한 값은?=파라미터" 라는 틀을 객체의 데이터에 마음대로 접근할 수 있다면
메소드를 통해 만들어진 데이터는 의미가 없어진다. 틀이 부숴져버리는 것이다.
또한 객체에서 데이터는 어떤 메소드의 실행 결과를 누적해서 보존하는 경우가 많기 때문에
함부로 누구나 사용할 수 있게 해주면 안된다.
객체의 데이터는 메소드를 통해 변경해야한다.
객체지향 프로그래밍 방식은 필요한 로직이나 기능을 수행할 수 있는 객체에게 내가 원하는 일을 요청하는 형태로
이루어지기 때문이다.
setter
외부에서 메소드를 통해 데이터에 접근하면, 메소드는 매개값을 검증해서 유효한 값만 데이터로 저장할 수 있다.
getter
데이터 복사본을 던져주기 때문에 원래 객체의 데이터를 손상시키지 않는다. 따라서 원본 데이터는 안전하다. 간단하게 생성자를 통해서만 데이터를 넣어줄 수 있고 getter 메소드만 있다면( 물론 인스턴스 변수가 기본 자료형이나
String인 경우) 외부에서는 객체의 원본 데이터를 변경할 수 없게 된다.
getter&setter 메소드 선언방식이다.
getter:getFieldName()
-접근제한자 :public
-리턴타입 : 필드의 리턴타입
-메소드이름:get+필드이름 (!!첫문자는 대문자로 한다)
-리턴값 : 필드값
setter:setFieldName(타입 fieldName)
-접근제한자 :public
-리턴타입 : void
-메소드이름:get+필드이름 (!!첫문자는 대문자로 한다)
-매개변수타입:필드타입
private를 통해 외부로부터 필드를 보호하고 안전하게 get&set으로 변경/사용한다.
public class VO {
private String a;
}
위의 VO를 이렇게 private로 선언 후 마우스 오른쪽 클릭 - Source - generate getter&setter을 하면 자동으로 생성되어 편하게 사용할 수 있다.
'JAVA > 자바' 카테고리의 다른 글
Java 입력 받은 값을 배열에 저장 (0) | 2021.12.11 |
---|---|
extends 와 implements의 차이 - 상속 (0) | 2021.08.13 |
Iterator와 map의 반복문 (0) | 2021.08.06 |
indexOf() , lastindexOf- 특정 문자 인덱스 위치 찾기 (0) | 2021.08.06 |
isEmpty와 ==null - 객체가 비어있는지 확인하는 방법 (2) | 2021.08.06 |