prgrms-web-devcourse / BE-Team-preArmand-Book-study

2 stars 2 forks source link

[아이템 17 질문 모음] #7

Closed HunkiKim closed 2 years ago

HunkiKim commented 2 years ago
  1. 자신 외에는 내부의 가변 컴포넌트에 접근할 수 없도록 해야한다. (106P 맨위) 어떤말인지 와닿지않는다.
  2. 110p에 중간에 가변동반 클래스는 도대체 무엇일까요?
  3. 결론적으로 private final을 기본으로 만들라고 했는데 불변에서 결국 가장 큰 장점은 어떤걸까요? 많은 장점들이 있지만 이중에서도 가장 큰 이유가 궁금합니다.
epicblues commented 2 years ago
  1. 내부에 불변 객체가 아닌 가변 객체를 참조하는 공개 멤버(public, protected)를 두지 말아야 한다고 저는 해석했습니다. 클라이언트가 마음대로 그 가변 객체를 바꿀 수 있으니까요!
  2. String - 불변 객체, StringBuilder - 내부에 변경 가능한 String 후보(여기서는 byte[] value)를 동반(보관)할 수 있는 객체. 라고 저는 해석했습니다. 매우 길고 복잡한 String을 단계적으로 만들고 싶은 경우(예를 들어 알고리즘에서 반복문을 돌면서 출력할 문자열 만들기) 사용할 수 있는 가변동반 클래스가 StringBuilder라고 보면 되지 않을까요?
  3. 가장 좋은 점은 책에서도 강조했던 thread-safe하다는 것이 아닐까 싶습니다. 어떤 스레드도 해당 객체의 상태를 변경할 수 없기 때문에 사용자는 그 객체의 상태를 100% 안심하고 사용할 수 있기 때문에? 정도 생각납니다.
Leeyerimearth commented 2 years ago
  1. 필드 접근자를 접근할 수 있도록 설정해 놓는 것 포함하여, 참조값을 얻을 수 있는 메서드(getter, getter가 아니어도 이름만 다른 참조값 리턴 메서드) 라고 생각했습니다.

    1. 저도 민성님과 같은 의견입니다. thread-safe하기때문에 사용자가 의심없이 가져다 쓸 수 있다는것과 가변객체여서 발생 할 수 있는 예상치 못한 오류(값의 불일치 라던가..)가 발생할 일이 없다는 것 아닐까요?
kimziou77 commented 2 years ago

자신 외에는 내부의 가변 컴포넌트에 접근할 수 없도록 해야한다. (106P 맨위) 어떤말인지 와닿지않는다.'

사용하는 측이 가변컴포넌트에 어떤짓을 할지 모르기 때문입니다.

컴포넌트가 변경이 될 여지가 있는 부분은 크게 두가지라고 생각합니다.

1. 사용자가 외부에서 해당 컴포넌트를 사용할때
2. 내부에서 일련의 작업을 위해서 변경할때

여기서 저는 2번보다 1번에 의한 변경을 더욱 조심해야 한다고 생각하는게 예측할 수 있는 2번과 달리 사용하는 측이 가변컴포넌트에 어떤짓을 할지 모르기 때문입니다.

많은 취약점들이 사용하는쪽의 인풋과 사용에 제약을 두지 않아서 발생한 경우가 많다고 느낍니다. 저희가 의도한대로 사용하지 않으면 저희가 대응할 수 없으니까요. 사용자들이 맘대로 사용하는 예시라고 한다면 SQL Injection 과 예전 log4j 취약점 이런 것이 있을것 같습니다.

이번 강의에서 나왔었던 내용을 인용하자면, 사용자가 입력하는 input이 그대로 가변컴포넌트에 들어가서 "Select * from User where name = "+name 여기 사용자가 인풋으로 "Subin" 이렇게 이름만 넣길 기대했는데 "Subin and Age=24" 이런식으로 작성을 한다면 Subin이 몇살인지 알기위해 사용자가 악의적으로 쿼리를 이용할 수 있을겁니다. 사용자에게 저희가 작성해야할 SQL문을 수정할 수 있게 열어둔 것이죠 따라서 강의에서는 이런 부분을 binding 형식으로 바꾸어서 쿼리문은 "Select * from User where name = ?" 이렇게 결정해놓고, 무슨값을 넣더라도 SQL문은 name까지만 쿼리가 되도록 SQL문을 작성하는 형식으로 나아간것 같습니다.

따라서 이런 내부에서 변하는 부분은 외부에서 맘대로 사용하지 못하도록 일차적으로 private로 막기도 하고, 사용자 인풋에 의해서 변경될 여지가 있는 부분들에 제약을 걸어두는 방식(입력값 검증, 바인딩 등)으로 안전하게 개발해야 한다고 말하는 내용이지 않을까 싶습니다


결론적으로 private final을 기본으로 만들라고 했는데 불변에서 결국 가장 큰 장점은 어떤걸까요?

값에 대한 신뢰성이라고 생각합니다. 멀티 스레드 환경도 그렇고, 해당 값으로 개발하는 개발자 (본인 혹은 같이 개발하는 동료 개발자)는 개발을 하면서 코드를 실수로 변경할 수 있습니다. (어? 이거 변경하면 안되는 값이었어?) 따라서 이런 값들이 변경되지 않았음을 확신해야 하고 중요하다면 구현할때 값에 대한 검증도 추가적으로 해주어야 합니다. 하지만 final로 했을때 이 값에 들어있는 값은 변경되지 않았음을 확신할 수 있습니다.