ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JAVA] 접근제어자, getter/setter
    spring.project.log 2022. 3. 26. 11:33

    ref

    자바에서 loose coupling과 tight coupling의 차이

    https://www.upgrad.com/blog/loose-coupling-vs-tight-coupling-in-java/

     

    Loose Coupling vs Tight Coupling in Java: Difference Between Loose Coupling & Tight Coupling | upGrad blog

    When two classes, modules, or components have low dependencies on each other, it is called loose coupling in Java.

    www.upgrad.com

    의존성 주입

    https://tecoble.techcourse.co.kr/post/2021-04-27-dependency-injection/

     

    의존관계 주입(Dependency Injection) 쉽게 이해하기

    이번 글에서는 DI(의존성 주입, 의존관계 주입)의 개념을 설명한다.

    tecoble.techcourse.co.kr

    coupling cohesion 결합과 응집

    http://www.fet.uwe.ac.uk/~jsa/OODP(E-learning)/LectureMaterials/Unit3Output/unit3(1011-12)/page_16.htm 

     

    Object coupling and cohesion

    Object coupling and cohesion In this section we are going to highlight the good and bad aspects of object collaborations and how you should structure the design of systems to support reuse and maintainability. In order to do this we are going to recap on e

    www.fet.uwe.ac.uk

     

    https://www.baeldung.com/cs/cohesion-vs-coupling

     

    처음 접근제어자를 접한 건 자바를 배운 지 얼마 안되었을 때이다.

    내가 무분별하게 getter/setter를 남발했었는데 그것이 객체지향과 멀리 떨어져있다는 것을 깨달았다~ 그리고 매우 안티패턴이었다~ 원래 getter와 setter를 만든 목적과는 동떨어져 있다는 것~


     

    먼저 js에 익숙해진 현재의 나는 접근제어자를 오해했다. 네임스페이스가 충돌*해서 필요하다고 추측했었는데, 이는 접근제어자가 없고 한 파일 단위로 모듈을 실행시키는 js에서 const와 let이 없을 때 발생했던 호이스팅과 유사한 문제였다.

    하지만 네임스페이스가 충돌하는 것과 호이스팅은 다르다. "값을 재할당하는 것"과 변수 선언의 공간이 겹치는 것은 다르기 때문이다.

    추측이 틀린 이유는 자바는 하나의 파일이 곧 클래스이기 때문이다. 그래서 각각의 네임스페이스를 갖는다. 즉 독립된 공간이어서 충돌을 잘 하지 않고, 자바를 쓰는 사용자들이 이름을 길고 장황하게 적는 관습(?)이 있기 때문에 이름 가지고 충돌은 잘 나지 않는다.


    그러면 접근제어자는 왜 쓰는가?

    접근을 제어하기 위해서 쓰는 것이다.

    그럼 접근은 왜 제어하는가?

    캡슐화를 하려고 하는 것이다.(바깥에서 모르게, 해당 클래스에서만 알 수 있게)

    캡슐화는 왜 하려는 것인가?

    클래스 안에 있는 것(필드와 메서드)들에게 의존을 하지 않게 하기 위해 쓰는 것이다.

     

    먼저 내가 익숙한 js에서 export는 자바에서 public과 같다. 무엇을 기준으로 실행시킬지가 다른 것이다. 자바는 클래스 기준, js는 모듈 기준으로 독립된 스페이스를 가진다. 

    객체지향의 한 방법론으로 js에서는 모듈화를 시키는 것이다.

    차이점이 있다면,

    js에선 모듈의 범위와 객체의 범위가 다르다 

    자바는 객체의 범위와 모듈의 범위가 같다

     

    나는 이번주에 dependency, 의존성이라는 개념을 처음 학습했다.

    의존한다는 것은 하나의 변화가 의존하고 있는 것(들)에 영향을 미친다는 것이다.

    의존성을 주입한다면, 편하지만 그 만큼 책임을 져야한다는 트레이드 오프가 있다.

    의존하는 대상이 바뀌면 대응을 해야 하기 때문이다.

    예시로 한 프레임워크에 의존하는 코드는 프레임워크에 의존하고 있어 "갈아끼우기 어렵기 때문에" 책임을 져야 한다고 말한 것이다.

    하지만 객체지향은 "구현체를 갈아끼우는" 목적으로 만들어졌기 때문에 (다른 프레임워크나 라이브러리에)의존을 하는 구현체는 객체지향의 안티패턴이 되는 것이다. 객체지향은 느슨한 결합(loosening coupling)을 지향한다고 한다.

    한마디로 접근제어자는 객체에 의존하지 않게 하기 위해서 쓴다!

    레퍼런스에서의 예시

    프로그램에서 A와 B라는 두 개의 클래스를 만들었다고 가정하자. 클래스 A는 부피라고 불리며 클래스 B는 실린더의 부피를 평가한다. 클래스 A 볼륨을 변경하면 클래스 B를 강제로 변경할 필요가 없다. Java에서는 이를 loose coupling이라고 한다. 클래스 A에서 클래스 B의 변경이 필요한 경우 tight coupling이 필요하다.

     

    public은, public interface다. 외부에서 쓸 수 있는 인터페이스라는 뜻이고,

    private은 내부에서만 쓸 수 있는 인터페이스다.

    자바는 언어차원에서 강제해서 에러가 뜨게 하는 것이고, 다시 말하지만 js에선 이를 exports 시켜서 public처럼 사용할 수 있다. 모듈 단위의 인터페이스(default)가 아니라 모듈(파일) 바깥에서도 쓸 수 있는 인터페이스라는 뜻.


    만약 

    객체의 프로퍼티가 바뀐다면 - 인터페이스가 바뀌는 것이고 - 의존관계에 있는 것들을 모두 바꿔주어야 한다.

    그래서 그 "어느 클래스에서 프로퍼티를 바꿔줄 것인가"를 세부적으로 나눠놓은 것이 접근제어자이다. (이 글을 설명하는 시점이 다른 것임)

    private 클래스 자기 자신

    default 같은 패키지 내

    protected 같은 패키지 그리고 상속하는 클래스

    public 모두

    getter/setter

    자바동네에선 만들어주는게 관례이긴 한데… setter를 만드는 건 안티패턴이다!

    프로퍼티 = 상태 = 계속 변할 수 있다

    상태를 파생시키는 것을 setter로 할 수 있기 때문에 불변이 보장되지 않는다. 

     

    학생이 들어있는 배열이 있다고 가정하자.

    학생 수 = array.length
    
    public int getStudetCount() {
    	return this.studentList.length;
    }

    = 프로퍼티가 없지만 studentList.length(배열의 길이로 계산해서 리턴했기 때문에 할당하는 값이 존재하지 않는다.)

     

    내가 이전에 썼던 안티패턴

    private int studentCount;
    public int getStudentCount() {
    	return this.studentCount;
    }

    이렇게 하면 굳이 private으로 접근을 제어해주는 의미가 없다. 왜냐면 getStudentCount가 public이기 때문에 메서드는 퍼블릭으로 접근이 가능하기 때문에(..)

     

     

    잘못된 세터

    검사를 안하는 세터(타입을 검사안해주는 세터)

    public int setStudentCount(int count) { 
    	this.studentCount = count;
    }

    다른 클래스나 패키지에서 누가 실수로 this.stuentCount를 변경한다고 했을 때 타입을 검사하지 않기 때문에 int가 아닌 값으로 변경될 수 있다 덜덜...

    'spring.project.log' 카테고리의 다른 글

    .equals와 ==  (0) 2022.04.16
    문자열 계산기 javascript.ver  (0) 2022.04.10
    오버라이딩(overriding)과 오버로딩(overloading)  (0) 2022.03.18
    이넘(enum)  (0) 2022.03.17
    인터페이스(interface)  (0) 2022.03.17
Designed by Tistory.