상당한 시간이 걸리므로 정적 클래스 대신 객체를 사용해야하는 이유를 생각할 수 없습니다. 생각보다 물건에 더 많은 이점이 있습니까? [닫은]


9

나는 객체의 개념을 이해하고 Java 프로그래머로서 OO 패러다임은 실제로 자연스럽게 나에게 온다고 생각합니다.

그러나 최근에 나는 생각하는 것을 발견했다.

잠깐, 정적 클래스를 사용하는 것보다 적절한 객체를 사용하는 것의 실질적인 이점은 무엇입니까?

객체를 사용하면 두 가지 이점을 생각할 수 있습니다 (둘 다 중요하고 강력합니다).

  1. 다형성 : 런타임 중에 기능을 동적으로 유연하게 교환 할 수 있습니다. 또한 시스템에 새로운 기능 '부품'및 대안을 쉽게 추가 할 수 있습니다. 예를 들어 객체 Car로 작업하도록 설계된 클래스 Engine가 있고 Car가 사용할 수있는 시스템에 새 엔진을 추가하려는 경우 새 Engine하위 클래스를 만들고이 클래스의 객체를 객체에 전달할 Car필요없이 간단히 에 대해 변경하십시오 Car. 그리고 런타임 중에 그렇게 할 수 있습니다.

  2. '주변 기능 전달'가능 : 시스템 주위의 객체를 동적으로 전달할 수 있습니다.

그러나 정적 클래스보다 객체에 더 많은 이점이 있습니까?

종종 시스템에 새로운 '부품'을 추가 할 때 새로운 클래스를 생성하고 객체를 인스턴스화하여 추가합니다.

그러나 최근에 멈추고 생각했을 때 정적 클래스가 일반적으로 객체를 사용하는 많은 장소에서 객체와 동일하게 작동한다는 것을 깨달았습니다.

예를 들어, 저장 /로드 파일 메커니즘을 앱에 추가하려고합니다.

객체를 사용하면 호출 코드 줄은 다음과 같습니다. Thing thing = fileLoader.load(file);

정적 클래스를 사용하면 다음과 같습니다. Thing thing = FileLoader.load(file);

차이점이 뭐야?

평범한 정적 클래스가 똑같이 작동 할 때 객체를 인스턴스화 해야하는 이유를 생각할 수없는 경우가 종종 있습니다. 그러나 OO 시스템에서 정적 클래스는 매우 드 rare니다. 그래서 나는 뭔가를 놓치고 있어야합니다.

내가 나열한 두 가지 이외의 다른 개체에 더 많은 이점이 있습니까? 설명 해주십시오.

편집 : 명확히하기 위해. 기능을 바꾸거나 데이터를 전달할 때 객체가 매우 유용하다는 것을 알았습니다. 예를 들어 멜로디를 구성하는 앱을 작성했습니다. MelodyGenerator멜로디를 다르게 만드는 여러 서브 클래스가 있었으며이 클래스의 객체는 서로 바뀌 었습니다 (전략 패턴).

멜로디도 지나가는 것이 유용하기 때문에 객체였습니다. 화음과 음계도 마찬가지였습니다.

그러나 시스템의 '정적'부분은 어떻습니까? 예를 들어 '파일 저장'메커니즘입니다. 정적 클래스가 아닌 객체로 구현 해야하는 이유는 무엇입니까?


따라서 필드와 메소드, 객체, 레코드가없는 객체 대신 정적 메소드로 전달되고 정적 메소드에서 반환되는 스칼라 값이 많이 있습니까? 편집 : 새로운 예는 다음과 같이 제안합니다 : 인스턴스 메소드가없는 객체? 그렇지 않으면 무엇 Thing입니까?

FileLoader소켓에서 읽은 것으로 교체해야 할 때 어떻게됩니까 ? 아니면 테스트를위한 모의? 아니면 zip 파일을 여는 것입니까?
Benjamin Hodgson 2016 년


1
@delnan 좋아. 대답이 이해하는 데 도움이되는 질문을 찾았습니다. 왜 시스템의 '정적'부분을 객체로 구현할까요? 질문의 예와 같이 저장 파일 메커니즘. 객체에서 구현하면 무엇을 얻을 수 있습니까?
Aviv Cohn 2016 년

1
기본값은 비 정적 객체를 사용해야합니다. 의도를 더 잘 표현한다고 생각되면 정적 클래스 만 사용하십시오. System.Math.NET에서 정적 클래스로 훨씬 더 의미가있는 예입니다. 스왑하거나 조롱 할 필요가 없으며 논리적으로 인스턴스의 일부로 만들 수있는 작업이 없습니다. 나는 당신의 '저장'예가 그 법안에 맞지 않다고 생각합니다.
Benjamin Hodgson

답변:


14

lol 당신은 내가 일했던 팀처럼 들린다.)

Java (그리고 아마도 C #)는 확실히 그 프로그래밍 스타일을 지원합니다. 그리고 저는 첫 번째 본능 인 사람들과 함께 일합니다. "정적 방법을 만들 수 있습니다!" 그러나 시간이 지남에 따라 당신을 따라 잡을 수있는 미묘한 비용이 있습니다.

1) Java는 객체 지향 언어입니다. 그리고 그것은 기능적인 사람들을 견인하지만 실제로는 꽤 잘 견뎌냅니다. OO의 기본 개념은 상태를 숨기고 상태를 숨기고 해당 컨텍스트에 적합한 기능 만 노출함으로써 의미를 보존하는 작은 단위의 데이터 및 기능을 갖도록 기능과 상태를 번들하는 것입니다.

정적 메서드 만있는 클래스로 이동하면 방정식의 "상태"부분이 깨집니다. 그러나 국가는 여전히 어딘가에 살아야합니다. 그래서 시간이 지남에 따라 보았던 것은 모든 정적 메소드가있는 클래스가 점점 더 복잡한 매개 변수 목록을 갖기 시작한다는 것입니다. 상태가 클래스에서 함수 호출로 이동하기 때문입니다.

모든 정적 메서드를 사용하여 클래스를 만든 후에는 하나의 공통 매개 변수가있는 메서드 수를 조사하십시오. 매개 변수가 해당 함수의 포함 클래스이거나 매개 변수가 인스턴스의 속성이어야한다는 힌트입니다.

2) OO의 규칙은 꽤 잘 이해되어 있습니다. 잠시 후 클래스 설계를보고 SOLID와 같은 기준을 충족하는지 확인할 수 있습니다. 그리고 많은 연습 단위 테스트 후에 클래스를 "적합한 크기"와 "일관성있는"요소로 만드는 것이 좋습니다. 그러나 모든 정적 메소드가있는 클래스에는 좋은 규칙이 없으며 거기에 모든 것을 묶어서는 안되는 이유가 없습니다. 수업은 편집자에게 열려 있습니다. 새로운 방법을 추가하십시오. 잠시 후, 응용 프로그램은 각각 세계를 지배하려는 여러 경쟁 "신 개체"로 바뀝니다. 다시 말하지만, 그것들을 더 작은 단위로 리팩토링하는 것은 매우 주관적이고 올바른지 알기가 어렵습니다.

3) 인터페이스는 Java의 가장 강력한 기능 중 하나입니다. 클래스 상속은 문제가있는 것으로 판명되었지만 인터페이스를 사용한 프로그래밍은 언어의 가장 강력한 트릭 중 하나입니다. (ditto C #) 모든 정적 클래스는 해당 모델에 넣을 수 없습니다.

4) 당신이 이용할 수없는 중요한 OO 기술에 문을 두 드린다. 따라서 스크루 드라이버가 있다면 얼마나 쉬운 일인지 알지 못하고 도구 상자에 망치로 몇 년 동안 일할 수 있습니다.

4.5) 가장 어렵고 깨지지 않는 컴파일 타임 종속성을 만듭니다. 따라서 예를 들어 FileSystem.saveFile()런타임에 JVM을 페이크 아웃하지 않는 한 변경할 수있는 방법이 없습니다. 즉, 정적 함수 클래스를 참조하는 모든 클래스는 특정 구현에 대해 컴파일 타임이 엄격하게 의존하지 않으므로 확장이 거의 불가능하고 테스트가 엄청나게 복잡해집니다. 정적 클래스는 격리하여 테스트 할 수 있지만 해당 클래스를 참조하는 클래스는 격리하여 테스트하기가 매우 어려워집니다.

5) 당신은 동료를 미치게 할 것입니다. 내가 일하는 대부분의 전문가들은 코드를 진지하게 받아들이고 최소한 어느 정도의 디자인 원칙에주의를 기울입니다. 언어의 핵심 의도를 제쳐두면 끊임없이 코드를 리팩터링하기 때문에 머리카락을 빼낼 수 있습니다.

언어를 사용할 때는 항상 언어를 잘 사용하려고합니다. 예를 들어 Java를 사용하는 경우 좋은 OO 디자인을 사용합니다. 언어를 실제로 활용하기 때문입니다. 파이썬에있을 때 모듈 수준 함수를 가끔 클래스와 혼합합니다. 파이썬으로 만 클래스를 작성할 수는 있지만 언어를 잘 사용하지 않을 것이라고 생각합니다.

또 다른 전술은 언어를 잘못 사용하는 것이며 그로 인해 발생하는 모든 문제에 대해 불평합니다. 그러나 그것은 거의 모든 기술에 적용됩니다.

Java의 주요 기능은 이해하기 쉬운 작은 테스트 가능한 단위로 복잡성을 관리하는 것입니다. Java는 구현과 무관하게 명확한 인터페이스 정의를 강조합니다. 이는 큰 이점입니다. 그렇기 때문에이 언어 (및 다른 유사한 OO 언어)가 널리 사용됩니다. 모든 장황함과 의식에 대해, 큰 Java 앱으로 작업을 마치면 아이디어가 코드보다 프로젝트에서보다 역동적 인 언어로 더 명확하게 분리되어있는 것처럼 느껴집니다.

그러나 어려운 일입니다. 나는 사람들이 "정적"버그를 얻는 것을 보았고, 그들과 이야기하기가 어렵다. 그러나 나는 그들이 그것을 극복 할 때 큰 안도감을 가지고 있음을 보았다.


주로 소형 및 모듈 식 상태를 유지하고 상태와 기능을 함께 유지하는 것에 대해 이야기합니다. 정적 클래스 로이 작업을 수행하는 데 방해가되는 것은 없습니다. 그들은 상태를 가질 수 있습니다. 그리고 getters-setter로 캡슐화 할 수 있습니다. 또한 시스템을 기능과 상태를 캡슐화하는 작은 클래스로 나눌 수 있습니다. 이 모든 것은 클래스와 객체 모두에 적용됩니다. 그리고 이것은 정확히 나의 딜레마입니다. 앱에 새로운 기능을 추가한다고 가정하십시오. 분명히 그것은 SRP에 순종하기 위해 별도의 클래스로 갈 것입니다. 그러나 왜이 클래스를 정확히 인스턴스화해야합니까? 이것이 내가 이해하지 못하는 것입니다.
Aviv Cohn 2016 년

내 말은 : 때로는 왜 물체를 원하는지 분명합니다. 편집에서 내 질문으로 예제를 사용하겠습니다. 멜로디를 구성하는 앱이 있습니다. 멜로디 제너레이터를 연결하여 다른 멜로디를 생성 할 수있는 다양한 스케일이있었습니다. 멜로디는 객체 였기 때문에 스택에 넣고 오래된 것들 등을 재생하기 위해 되돌아 갈 수있었습니다. 이런 경우에는 왜 객체를 사용해야하는지 분명합니다. 내가 이해하지 못하는 것은 왜 시스템의 '정적'부분을 나타 내기 위해 객체를 사용해야 하는가입니다. 예를 들어 저장 파일 메커니즘. 왜 이것이 정적 클래스가 아니어야합니까?
Aviv Cohn 2016 년

정적 메소드가있는 클래스는 상태를 외부화해야합니다. 때로는 매우 중요한 팩토링 기술입니다. 그러나 대부분의 경우 상태를 캡슐화하려고합니다. 구체적인 예 : 몇 년 전 한 동료가 Javascript로 "날짜 선택기"를 작성했습니다. 그리고 그것은 악몽이었다. cusomers는 그것에 대해 끊임없이 불평했습니다. 그래서 나는 그것을 "달력"객체로 리팩토링했고, 갑자기 그것들을 나란히 놓고, 몇 달과 몇 년 사이에 점프하는 등 여러 객체를 인스턴스화하고있었습니다. 우리는 실제로 기능을 꺼야 할 정도로 풍부했습니다. 인스턴스화는 그 규모를 제공합니다.
Rob

3
"OO에 대한 아이디어는 상태를 숨기고 상태를 숨기고 의미와 관련이있는 기능 만 노출함으로써 의미를 보존하는 작은 단위의 데이터와 기능을 갖도록 상태와 기능을 번들링하는 것입니다." 이것은 근본적으로 잘못되었습니다. OO는 변경 가능한 상태를 의미하지 않으며 추상화는 OO에 배타적이지 않습니다. 추상화를 달성하는 두 가지 방법이 있으며 객체는 그중 하나 일뿐입니다 (다른 하나는 추상적 데이터 유형 임).
Doval

1
@Doval 나는 모든 OO 토론이 반드시 함수형 프로그래밍 토론으로 바뀌어야하는 이유를 이해하지 못한다.
Rob

6

당신은 물었다 :

그러나 정적 클래스보다 객체에 더 많은 이점이 있습니까?

이 질문 전에 다형성 을 나열 하고 객체 사용의 두 가지 이점 으로 전달했습니다 . 나는 이것이 OO 패러다임의 특징이라고 말하고 싶다. 캡슐화 는 OO 패러다임의 또 다른 기능입니다.

그러나 이것들은 이점이 아닙니다. 이점은 다음과 같습니다.

  1. 더 나은 추상화
  2. 더 나은 유지 보수성
  3. 더 나은 테스트 가능성

당신은 말했다 :

그러나 최근에 멈추고 생각했을 때 정적 클래스가 일반적으로 객체를 사용하는 많은 장소에서 객체와 동일하게 작동한다는 것을 깨달았습니다.

나는 당신이 거기에 유효한 포인트가 있다고 생각합니다. 기본적으로 프로그래밍은 데이터 변환 및 데이터 기반의 부작용 생성에 지나지 않습니다. 때때로 데이터를 변환하려면 보조 데이터가 필요합니다. 다른 경우에는 그렇지 않습니다.

첫 번째 변환 범주를 처리 할 때는 보조 데이터를 입력으로 전달하거나 어딘가에 저장해야합니다. 객체는 그러한 변환에 정적 클래스보다 나은 접근 방법입니다. Object는 보조 데이터를 저장하고 적시에 사용할 수 있습니다.

두 번째 변형 범주의 경우 정적 클래스는 좋지 않은 경우 객체만큼 좋습니다. 수학 함수는이 범주의 전형적인 예입니다. 표준 C 라이브러리 함수의 대부분도이 범주에 속합니다.

당신은 물었다 :

객체를 사용하면 호출 코드 줄은 다음과 같습니다. Thing thing = fileLoader.load(file);

정적 클래스를 사용하면 다음과 같습니다. Thing thing = FileLoader.load(file);

차이점이 뭐야?

경우 FileLoader하지 않습니다, 지금까지 , 나는 두 번째 방법으로 갈 것, 데이터를 저장해야합니다. 작업을 수행하기 위해 보조 데이터가 필요할 가능성이 크면 첫 번째 방법은 더 안전한 내기입니다.

당신은 물었다 :

내가 나열한 두 가지 이외의 다른 개체에 더 많은 이점이 있습니까? 설명 해주십시오.

나는 OO 패러다임을 사용하는 것의 이점 (장점)을 열거했다. 나는 그들이 설명을 희망합니다. 그렇지 않다면 정교하게 기뻐할 것입니다.

당신은 물었다 :

그러나 시스템의 '정적'부분은 어떻습니까? 예를 들어 '파일 저장'메커니즘입니다. 정적 클래스가 아닌 객체로 구현 해야하는 이유는 무엇입니까?

이것은 정적 클래스가 단순히하지 않는 예입니다. 애플리케이션 데이터를 파일로 저장하는 방법에는 여러 가지가 있습니다.

  1. CSV 파일로 저장하십시오.
  2. XML 파일로 저장하십시오.
  3. json 파일로 저장하십시오.
  4. 데이터를 직접 덤프하여 이진 파일로 저장하십시오.
  5. 데이터베이스의 일부 테이블에 직접 저장하십시오.

이러한 옵션을 제공하는 유일한 방법은 인터페이스를 만들고 인터페이스를 구현하는 객체를 만드는 것입니다.

결론적으로

당면한 문제에 대한 올바른 접근 방법을 사용하십시오. 한 가지 접근법에 대해 종교적으로 접근하지 않는 것이 좋습니다.


다양한 객체 유형 (클래스) 필요가 저장 될 경우에도 (예 Melody, Chord, Improvisations, SoundSample등), 추상화를 통해 구현을 단순화하는 것이 경제적 일 것입니다.
rwong

5

때로는 언어와 상황에 따라 다릅니다. 예를 들어, PHP요청을 처리하는 데 사용되는 스크립트에는 항상 전체 서비스 수명 동안 생성해야하는 하나의 서비스 요청과 하나의 응답이 있으므로 요청에 대해 작동하고 응답을 생성하는 정적 메소드가 적합 할 수 있습니다. 그러나에 작성된 서버 Node.js에는 동시에 여러 가지 다른 요청과 응답이있을 수 있습니다. 첫 번째 질문은 정적 클래스가 실제로 싱글 톤 객체에 해당하는지 확인하는 것입니다.

둘째, 싱글 톤이 있더라도 객체를 사용하면 Dependency_injectionFactory_method_pattern 과 같은 기술을 사용하여 다형성을 활용할 수 있습니다 . 이것은 종종 다양한 Inversion_of_control 패턴 에서 사용되며 테스트, 로깅 등을위한 모의 객체를 만드는 데 유용합니다.

위의 장점을 언급 했으므로 상속하지 않은 것이 있습니다. 상속. 많은 언어는 인스턴스 메소드를 대체 할 수있는 것과 같은 방식으로 정적 메소드를 대체 할 수 없습니다. 일반적으로 정적 메서드를 상속하고 재정의하는 것이 훨씬 어렵습니다.


대답 해줘서 고마워. 귀하의 의견으로는 시스템의 '정적'부분을 만들 때 소리가 들리지 않는 시스템의 부분 또는 데이터를 파일에 저장하는 시스템의 부분과 같이 '통과'하지 않는 것 : 객체 또는 정적 클래스에서 구현해야합니까?
Aviv Cohn 2016 년

3

Rob Y의 게시물 외에도


load(File file)사용하는 다른 모든 함수와 기능을 명확하게 분리 할 수 ​​있다면 정적 메서드 / 클래스를 사용하는 것이 좋습니다. 상태를 외부화하고 (나쁜 것은 아닙니다) 예를 들어 부분적으로 적용하거나 함수를 카레 할 수 있으므로 중복성을 얻지 못하므로 반복하지 않아도됩니다. (실제로는 factory패턴 을 사용하는 것과 동일하거나 유사합니다 )

그러나 이러한 기능 중 두 가지 기능이 공통적으로 사용되기 시작하면 기능을 어떻게 든 그룹화 할 수 있습니다. load기능뿐만 아니라 hasValidSyntax기능 도 있다고 상상해보십시오 . 무엇을 하시겠습니까?

     if (FileLoader.hasValidSyntax(myfile))
          Thing thing = FileLoader.load(myfile);
     else
          println "oh noes!"

myfile여기에 두 개의 참조가 있습니까? 모든 통화에 대해 외부화 된 상태를 전달해야하므로 반복해야합니다. Rob Y는 상태 (여기서는 file) 를 내부화하여 다음과 같이 수행하는 방법을 설명 했습니다.

     FileLoader myfileLoader = new FileLoader(myfile)
     if (myfileLoader.hasValidSyntax())
          Thing thing = myfileLoader.load();
     else
          println "oh noes!"

동일한 물체를 두 번 통과해야하는 것은 피상적 인 증상입니다. 파일이 두 번, 두 번 열 분석해야 할 수도 있습니다, 그리고 경우, 두 번 폐쇄 - 그것은 나타낼 수있는 실제 문제는 몇 가지 작업이 중복 수행한다는 것입니다 hasValidSyntax()load()재사용 상태 (부분적으로 해석 파일의 결과)에 사용할 수 없습니다.
rwong

2

정적 클래스를 사용할 때 가장 큰 문제는 종속성 을 강제 로 숨기고 구현에 의존 하도록 강요 한다는 것입니다. 다음 생성자 서명에서 종속성은 무엇입니까?

public Person(String name)

글쎄, 서명으로 판단하면 사람은 이름이 필요합니다. 구현이 다음과 같은 경우는 아닙니다.

public Person(String name) {
    ResultSet rs = DBConnection.getPersonFilePathByName(name);
    File f = FileLoader.load(rs.getPath());
    PersonData.setDataFile(f);
    this.name = name;
    this.age = PersonData.getAge();
}

따라서 사람은 단순히 인스턴스화되지 않습니다. 우리는 실제로 데이터베이스에서 데이터를 가져 와서 파일에 대한 경로를 제공합니다. 파일에 대한 경로를 파싱해야합니다. 그런 다음 원하는 실제 데이터를 삭제해야합니다. 이 예는 분명히 정상에 있지만 요점을 증명합니다. 그러나 더 많은 것이있을 수 있습니다. 다음 테스트를 작성합니다.

public void testPersonConstructor() {
    Person p = new Person("Milhouse van Houten");
    assertEqual(10, p.age);
}

그래도 통과해야합니까? 우리는 다른 모든 것들을 캡슐화 했지요. 글쎄, 실제로 예외가 발생합니다. 왜? 아, 그렇습니다. 우리가 몰랐던 숨겨진 의존성은 세계적 상태를 가지고 있습니다. DBConnection요구가 초기화와 연결되어 있습니다. FileLoader로 초기화 요구 FileFormat(같은 객체 XMLFileFormat또는 CSVFileFormat). 들어 본 적이 없습니까? 그게 요점입니다. 정적 호출은 이러한 종속성을 숨기므로 코드 (및 컴파일러)는 이러한 것들이 필요하다는 것을 알 수 없습니다. 테스트라고 했습니까? 새로운 주니어 개발자는 최근 릴리스에서 이와 같은 것을 제공했습니다. 결국 컴파일 된 = 작동합니다.

또한 MySQL 인스턴스가 실행되지 않는 시스템을 사용 중이라고 가정하십시오. 또는 Windows 시스템에 있지만 DBConnection클래스가 Linux 상자가있는 Linux 상자 (Linux 경로 포함)에서만 MySQL 서버로 이동한다고 가정하십시오. 또는에 의해 리턴 된 경로 DBConnection가 읽기 / 쓰기가 아닌 시스템에 있다고 가정 하십시오. 즉, 코드 오류가 아니라 코드의 유연성을 제한하고 구현에 연결되는 디자인 오류로 인해 이러한 조건 중 하나에서이 시스템을 실행하거나 테스트하려고하면 실패합니다.

이제 우리는 데이터베이스에 대한 모든 호출을 하나의 특정 Person인스턴스, 특정의 번잡 한 경로를 통과하는 로그에 기록하려고 합니다. 우리는 로깅을 넣을 수는 DBConnection있지만 모든 것을 기록 하여 많은 혼란을 겪고 추적하려는 특정 코드 경로를 구별하기가 어렵습니다. 그러나 DBConnection인스턴스에 의존성 주입을 사용하는 경우 단순히 데코레이터에서 인터페이스를 구현하거나 객체와 함께 두 옵션을 모두 사용할 수 있으므로 클래스를 확장 할 수 있습니다. 정적 클래스를 사용하면 종속성을 주입하거나 인터페이스를 구현할 수 없으며 데코레이터로 랩핑 할 수 없으며 클래스를 확장 할 수 없습니다. 우리는 코드의 깊은 곳에 숨겨져있는 직접 호출 만 할 수 있습니다. 따라서 우리는 강요됩니다 구현에 숨겨진 의존성을 갖습니다.

항상 나쁜가요? 반드시 그런 것은 아니지만 관점을 바꾸고 "이것이 실례가 되어서는 안될 충분한 이유가 있습니까?" 라고 말하는 것이 좋습니다. "이것이 실례 될만한 충분한 이유 있습니까?" 코드가 Math.abs()구현 방식과 사용 방식 에서처럼 흔들리지 않고 상태가 없다고 진정으로 말할 수 있다면 정적으로 만드는 것을 고려할 수 있습니다. 그러나 정적 클래스에 대한 인스턴스가 있으면 사실 후에 항상 다시 캡처하기 쉽지 않은 유연성의 세계를 제공합니다. 또한 코드 종속성의 실제 특성을보다 명확하게 보여줄 수 있습니다.


숨겨진 의존성은 매우 좋은 지적입니다. 나는 "어떻게 코드가 구현되는지가 아니라 어떻게 사용되는지에 따라 판단되어야한다"라는 관용구를 거의 잊었다.
Euphoric

그러나 숨겨진 종속성은 정적이 아닌 클래스에도 존재할 수 있습니까? 그래서 왜 이것이 정적 클래스의 단점이 아닌 비 정적 클래스의 단점인지 알 수 없습니다.
valenterry

@valenterry 그렇습니다. 정적이 아닌 종속성도 숨길 수 있지만 핵심은 정적이 아닌 종속성을 숨기는 것이 선택 입니다. 나는 수 new(일반적으로 바람직하지 않습니다) 생성자에있는 개체의 무리를하지만, 내가 할 수있는 그 주사도. 정적 클래스를 사용하면 삽입 할 수있는 방법이 없습니다 (어쨌든 Java에서는 쉽지 않으며 언어를 허용하는 다른 토론이 될 것입니다). 그건 내가 아이디어를 강조하는 이유의가되고 강제로 내 대답에 너무 많이 숨어 종속성에.
cbojar 2016 년

그러나 메소드를 인수로 제공하여 메소드를 호출 할 때마다 삽입 할 수 있습니다 . 따라서 당신은 그것들을 숨기지 말고 모든 사람들이 "aha, 그 방법은이 인자에 의존합니다"보다는 "aha, 그 방법은 이러한 인자에 의존합니다"라는 것을 볼 수 있도록 명시 적으로 만들어야합니다. 알고있다".
valenterry

Java에서는 내가 아는 한, 전체 리플렉션 리그를 거치지 않고 정적 클래스를 매개 변수로 제공 할 수 없습니다. (나는 생각할 수있는 모든 방법을 시도했다. 당신이 방법을 가지고 있다면 그것을보고 싶다.) 그리고 당신이 그것을 선택한다면, 당신은 본질적으로 내장형 시스템을 파괴하고 있습니다 (매개 변수는 Class그런 다음 올바른 클래스인지 확인하거나 오리 타이핑 중입니다 (올바른 방법에 응답하는지 확인하십시오). 후자를하려면 언어 선택을 다시 평가해야합니다. 전자를하고 싶다면 인스턴스가
제대로 작동

1

내 두 센트.

질문 :

그러나 시스템의 '정적'부분은 어떻습니까? 예를 들어 '파일 저장'메커니즘입니다. 정적 클래스가 아닌 객체로 구현 해야하는 이유는 무엇입니까?

사운드를 재생하는 시스템 부분의 메커니즘이나 파일에 데이터를 저장하는 시스템의 메커니즘을 변경할 입니다. 대답이 예라면 abstract class/를 사용하여 추상화해야 함을 나타냅니다 interface. 미래의 것들을 어떻게 알 수 있습니까? 확실히, 우리는 할 수 없습니다. 따라서 상태가없는 java.lang.Math경우 객체 지향 접근 방식 과 같은 '정적 클래스'를 사용할 수 있습니다 .


놀림조의 조언이 있습니다 : 세 파업 당신은 리팩토링 변경이 실제로 필요할 때까지 하나가 보류 할 수 있음을 시사한다. "변경"의 의미는 하나 이상의 객체 유형을 저장해야합니다. 또는 둘 이상의 파일 형식 (스토리지 유형)으로 저장해야합니다. 또는 저장된 데이터의 복잡성이 급격히 증가합니다. 물론 변화가 곧 일어날 것이라고 확신한다면,보다 유연한 디자인을 미리 도입 할 수 있습니다.
rwong
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.