이 시점에서 자바의 공공 장소는 비극적 인 역사적 디자인 결함 일까? [닫은]


17

이 시점에서 기본적으로 객체 상태에 공개 필드를 사용해서는 안되는 것은 Java 정통 인 것 같습니다. (나는 반드시 동의하지는 않지만 내 질문과는 관련이 없습니다.) 오늘날 우리가 어디에서 왔는지 Java의 공공 분야가 언어 디자인의 실수 / 결함이라는 것이 분명합니까? 아니면 오늘날에도 언어의 유용하고 중요한 부분이라는 합리적인 주장이 있습니까?

감사!

업데이트 : C #, Python, Groovy 등과 같은보다 우아한 접근 방식에 대해 알고 있습니다. 직접 이러한 예제를 찾지는 않습니다. 나는 아직도 벙커 안에 아직도 누군가가 있는지, 정말 멋진 공공 장소가 있는지, 그리고 대중이 모두 양인지 등을 궁금해하고 있습니다.

업데이트 2 : 명확하게 정적 인 최종 퍼블릭 필드는 퍼블릭 상수를 생성하는 표준 방법입니다. 객체 상태 (불변 상태조차도)에 공용 필드를 사용하는 것에 대해 더 많이 언급하고있었습니다. 저는 상수에 대해서는 공용 필드를 사용해야하지만 상태에는 사용하지 않아야하는 디자인 결함처럼 생각합니다. 언어 규칙은 가이드 라인이 아닌 구문에 의해 자연스럽게 적용되어야합니다.


2
그들이 실제로 결함이라는 당신의 근거는 무엇입니까?
Aaron McIver

1
Java에서 기호 상수 표현식을 작성하는 다른 방법이 있습니까?
Edward Strange

@Aaron 나는 그들이 결점이라고 진술하지 않았으며, 지금은 공공 장소를 절대로 사용해서는 안된다는 점에서 정통이라고 인식했다. 그 인식은 틀릴 수도 있지만 실제로 내가 인식 한 것은 잘못입니다.
Avi Flax

@Crazy Eddie 나는 그 사용에 대해 잊어 버렸다. 나는 더 일반적인 분야, 상태의 사용에 대해 더 많이 생각하고 있었다. 질문을 편집하겠습니다.
Avi Flax

답변:


14

필드가 최종 적이고 다른 응용 프로그램의 API에 노출되지 않고 응용 프로그램에서만 내부적으로 사용되는 한 마음에 들었습니다 . 이렇게하면 코드가 더 짧고 읽기 쉽습니다.

공용 필드를 노출하면 구현도 노출되므로 API에서 공용 필드를 노출해서는 안됩니다. getXXX()대신 메소드 로 노출 하면 API 인터페이스를 변경하지 않고 구현을 변경할 수 있습니다. 예를 들어 원격 서비스에서 가치를 변경하고 얻을 수 있지만 API를 사용하는 응용 프로그램은이를 알 필요가 없습니다.

변경 불가능한 클래스의 public final필드에 적합한 디자인입니다 .

에서 효과적인 자바 :

항목 14 : 공개 클래스에서는 공개 필드가 아닌 접근 자 메소드를 사용하십시오.

... 클래스가 패키지 전용이거나 개인 중첩 클래스 인 경우 데이터 필드를 노출하는 데 본질적으로 아무런 문제가 없습니다. 이 접근 방식은 접근 자 방식보다 덜 복잡합니다.

공개 클래스가 필드를 직접 노출하는 것은 좋은 생각이 아니지만 필드를 변경할 수없는 경우에는 덜 해 롭습니다.

JavaBeans 대신 불변 POJO를 사용해야하는 이유는 무엇입니까?를 참조하십시오 .


API에 노출시키지 않는 이유는 무엇입니까?
Steven Jeuris

2
@Steven : 공개 필드를 노출함으로써 구현도 노출 할 수 있습니다. getXXX()대신 메소드 로 노출 하면 API 인터페이스를 변경하지 않고 구현을 변경할 수 있습니다. 예를 들어 원격 서비스에서 가치를 변경하고 얻을 수 있지만 API를 사용하는 응용 프로그램은이를 알 필요가 없습니다.
조나스

@Jonas : 이것들은 일반적으로 상수의 후보가 아닙니다.
Steven Jeuris

@ 스티븐 : 처음에는 상수에 대해 이야기하는 것이 아니라 변경할 수없는 클래스의 공개 최종 필드에 대해 이야기하고 있습니다. 예를 들어 JavaBeans 대신 불변 POJO를 사용해야하는 이유는 무엇입니까?를 참조하십시오 .
조나스

@Jonas : 그것은 좋은 사용 사례입니다! 아마도 대답을 약간 업데이트하여 명확히하는 것이 도움이 될 것입니다.
Steven Jeuris

9

get / set 메소드 쌍의 사용은 비극적 인 역사적 디자인 결함입니다. 속성을 자세하고 비효율적으로 구현하는 다른 언어는 생각할 수 없습니다.


1
사실이지만, 이것은 질문의 요점에 다소 접선 적입니다. 이는 본질적으로 set / get 메소드와 공개 필드 중 하나를 선택했을 때 어떤 상황에서 필드를 선호 해야하는 이유가 있습니까? 다른 언어가 문제에 대한 더 나은 해결책을 제공한다는 것은 관련이없는 것 같습니다.
Jules

5

필자는 본질적으로 복잡한 숫자 또는 포인트와 같은 값 유형 인 클래스의 경우 공개 필드가 괜찮다고 생각합니다. 클래스는 클래스가 C 스타일 구조체와 같이 기본 유형을 그룹화하는 것 이상을 수행하지 않고 몇 가지 연산자를 정의 할 수 있습니다.


2
java.awt.Point친구들은 약간의 악몽입니다.
Tom Hawtin-tackline

@ TomHawtin-tackline : 문제 는 유형 변수 가 위치를 캡슐화 Point해야하는지 또는 변경할 수있는 위치로 엔티티의 정체성을 캡슐화 해야하는지 여부가 모호하다는 것 입니다. 개념적으로, 나는 통과 하는 코드를 배열을 통과하는 코드와 매우 비슷 하다고 생각 합니다. PointPoint
supercat

따라서 a를 가져 와서 Point수정하면 참조하는 객체가 화면에서 완전히 업데이트 될 것으로 기대해야합니까? 아니요, 문제 Point는 변경 가능하다는 것입니다. 우리는했다 String/ StringBuffer그러나 아이디어는 통과하는 것 같지 않았어요. / 배열을 전달하면 비슷한 문제가 있습니다.
Tom Hawtin-tackline

5

공용 상수를 정의하는 것이 여전히 유용합니다. 예 :

공개 정적 최종 int DAYS_IN_WEEK = 7;

그러나 가능한 경우 열거 형을 선호 하십시오. 예 :

public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, 
    THURSDAY, FRIDAY, SATURDAY 
}

간단한 구조체 클래스시뮬레이트하는 것도 유용합니다. 모든 분야에 대해 게터와 세터를 만들 이유가 전혀 없습니다.

class Point
{
    public int x, y;
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

그러나 다시 말하지만, 많은 사람들은 구조체가 Java와 같은 언어로 자리를 차지할 수 없다고 주장 할 것입니다.

1
@delnan : JavaBeans와 거의 동일하지만 JavaBeans는 훨씬 더 장황하며 스레드 안전하지 않습니다. JavaBeans 대신 불변 POJO를 사용해야하는 이유는 무엇입니까?를
조나스

일부 안드로이드 특정 관찰 : 열거 형은 정수보다 평가 속도가 느리고 피해야합니다. 또한 엄격한 루프에서 setter 및 getter가 자주 액세스하는 필드도 공개되는 것이 좋습니다.
일러

2

IDE가 널리 보급되기 전에 모든 필드를 공개하는 것은 프로토 타입 / 개념의 개념을 빠르게 만들 수있는 강력한 도구였습니다.

요즘에는 마우스 클릭만으로 게터 / 세터 쌍을 생성 할 수있을 때 사용에 대한 변명이 거의 없습니다.


4
그러나 10 개의 public final필드는 10 개의 getXXX()방법 보다 더 읽기 쉽습니다.
조나스

1
@Jonas 네,하지만 우리는 여기서 마지막 필드에 대해 이야기하지 않습니다. 공개 최종 필드도 정적 인 경우 상수이며 const키워드로 충분하고 정적이 아닌 경우 캡슐화를 심각하게 위반하는 것입니다.
biziclop

3
에 따라 @biziclop 위키 백과 : "자바의 키워드로 예약 있지만, const를 사용하고 어떤 기능이 없습니다되지 않는다"
아비 아마

@Avi Flax 예. 상수를 표시하는 데 사용될 수 있으므로 상수를 공용 필드로 선언 할 필요가 없습니다.
biziclop

2
게터 / 세터 쌍이 적절하다고 가정합니다. 종종 그렇지 않습니다.
David Thornley

2

이것은 주관적이지만 내 의견은 전체 대중 / 개인 개념이 구식이며 거꾸로되어 있다는 것입니다.

파이썬에는 공개 / 개인이 없습니다. 모든 것이 기본적으로 공개됩니다. 많은 문제를 일으키지 않았습니다.

Java에서는 "공용"으로 표시하는 죄를 피하기 위해 각 필드에 대해 무의미한 getter / setter를 만드는 경향이 있습니다. (IMHO 자신이 그렇게한다면 공개적으로 표시해야합니다).


파이썬에서는 이름 앞에 __를 붙여서 사물을 비공개로 표시 할 수 있습니다. 이러한 변수와 메소드에 여전히 액세스 할 수있는 방법이 있기 때문에 100 % 비공개는 아니지만 C #에서는 리플렉션과 비슷한 작업을 수행 할 수 있습니다.
Adam Lear
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.