시작은 시큐어 코딩 가이드에 나와있는 public한 메소드를 통하여 반환된 private한 배열(CWE-495)을 보고 시작되었다.
https://cwe.mitre.org/data/definitions/495.html
시큐어 코딩 가이드에는 이러한 취약점을 조치하기 위하여 필요한 경우 배열의 복제본을 반환하거나 수정을 제어하는 public 메소드를 별도로 선언해야한다고 나와있었다.
이 내용을 보고 필자는 만약에 private로 선언된 객체가 클래스 변수로 존재한다면 동일한 처리를 해주어야한다 생각했다.
우선 객체의 복사본(deep copy)을 반환하기 위한 방법을 검색했더니 총 3가지 방법이 나왔다.
1. 복사 생성자 OR 복사 팩토리 사용
2. 직접 객체를 생성하여 복사
3. Clonable 인터페이스를 구현하여 clone 메소드 재정의
하지만 위의 방법들을 사용하는데 있어서 문제가 있었다.
우선 1. 복사 생성자 OR 복사 팩토리 사용, 2. 직접 객체를 생성하여 복사를 사용하여 진행하기엔 객체 내부에 변수가 너무 많아서 하기 싫었다.(설계부터 갈아 엎고 싶다)
그래서 3. Clonable 인터페이스를 구현하여 clone 메소드 재정의을 사용하려 하였으나
클래스 내부에 가변 객체가 변수로 존재할 경우 clone 메소드 재정의하는 것을 권장하지 않는다고 한다.
이 내용은 추후 이펙티브 자바 13장을 읽은 후 다시 정리하겠다.
따라서 나는 결국 울며 겨자먹기로 생성자를 재정의하려고 하고 있었다...
하지만 회사 이사님께서 이를 보고 말씀해주셨다.
시큐어 코딩이라는건 애초에 자바를 타겟으로 나온게 아니라 자바에 맞춰져 있지 않다.
자바는 해당 객체를 바로 return해주는 것이 맞다고 하셨다.
자료구조들을 보면 get을 할 때 객체의 원본 주소값을 return 해주고 있지 않은가?
애초에 보안툴에서도 단순 경고만 남겨주는거라 문제가 없다고 하셨다.
근데 이 이야기를 듣고 나는 getter로 불러와서 해당 변수의 값이 변경 가능하니까 캡슐화가 안된 것이 아닌가? 라는 의문이 들었다.
이사님께서는 캡슐화라는건 해당 객체의 데이터값이 아닌 객체의 주소값을 말하는거다.
따라서 객체의 주소값이 변경되지않으면 정상적으로 캡슐화가 된 것이다. 라고 하셨다.
이렇게 이해하고 넘어가려 했는데 위의 내용으로 토론을 하던 친구가 아래와 같은 링크를 보내주었다.
https://songkg7.github.io/posts/getter-and-setter/
진정한 캡슐화의 경우 getter/setter도 없어야 한다는 내용이었다.
하지만 위 글의 필자도 어느 수준의 캡슐화를 진행할 지는 개발하는 코드의 목적에 맞춰 판단하면 된다고 하였다.
만일 getter와 setter를 사용하지 않고 개발을 할 것을 생각해보니 너무나도 불편할 것이라는 생각이 든다.
결론
캡슐화라는 것은 객체지향의 하나의 특징일 뿐이고 이것을 무조건 지켜야하는 것은 아니다라는 결론을 내렸다.
데이터 반정규화도 정규화에 어긋나지만 좀 더 데이터를 수월하게 관리하기 위해 사용하지 않는가?
'개발일지' 카테고리의 다른 글
문자열 탐색 성능 개선 (0) | 2024.05.30 |
---|---|
MySQL SELECT 쿼리 성능 개선 (1) | 2023.08.20 |