정적 메소드 만 포함하는 *** Helper 또는 *** Util 클래스를 사용합니까?


19

나는 종종 Java 또는 모든 종류의 언어에서 도우미 또는 유틸리티 클래스에 직면합니다. 그래서 나는 이것이 일종의 안티 패턴인지 여부를 묻고 있었고 이러한 종류의 클래스의 존재는 소프트웨어의 디자인과 아키텍처에서 누락이 부족한 것입니다.

이러한 클래스는 종종 정적 메소드를 사용하여 제한되며 많은 기능을 수행합니다. 그러나 대부분 상황에 따라 다르며 상태가 가득합니다.

내 질문은, 그런 종류의 정적 도우미 / 유틸리티 클래스에 대한 당신의 의견은 무엇입니까? 왜냐하면 장점은 클래스 이름 만 사용하는 빠른 호출이기 때문입니다.

그리고 어떤 종류의 추상화 수준에서 이런 종류의 클래스를 사용하지 않겠습니까?

제 생각에는 키워드 "정적"은 메소드 선언이 아닌 클래스 선언 (Java) 내에서만 허용되어야합니다. 내 의견으로는이 방법을 사용하면 Procuedural 및 OO-Paradigm을 Java로 결합하고 키워드의 오용을 피할 수있는 좋은 대안이 될 수 있습니다.

답변으로 인한 추가 사항 :

처음에는 다른 패러다임을 결합하고 심지어 기계 또는 vm 컴파일 된 코드 내에서 런타임 해석 스크립트 언어를 사용할 수있는 것이 합법적이라고 생각합니다.

필자의 경험은 프로젝트의 개발 과정에서 이러한 종류의 도우미 및 유틸리티 또는 이름이 무엇이든 원래 코드 모듈의 모든 잊혀진 구석 내에서 성장하고 성장하여 사용되고 있으며 원래 원래 모듈 식 및 flexibel로 설계되었습니다. 리팩토링을하지 않거나 디자인에 대해 다시 생각할 시간이 없기 때문에 시간이 지남에 따라 훨씬 더 나빠질 수 있습니다.

staticJava에서 제거해야 한다고 생각 합니다. 특히 더 정교한 기능적 언어 요소를 사용할 수있는 곳이 있습니다.



도우미가 클래스를 인스턴스화 할 필요가 없다면 괜찮습니다. 문제는 도우미가 클래스의 구체적인 구현을 인스턴스화 한 다음 해당 인터페이스를 조롱 할 수없는 경우입니다. 도우미가 인터페이스 또는 추상 클래스를 전달하면 괜찮습니다.
bobek

절차 적 프로그래밍을 주장한다고해도 괜찮습니다. 객체 지향 프로그래밍을 주장한다고 주장하는 것이 아닙니다.
발견

1
@Spotted : 객체 지향 프로그래밍만을 주장한다고 주장하는 비즈니스 가치가 없기 때문에 항상 혼합 패러다임 프로그래밍을 수행하고 똥을 완료하십시오.
RemcoGerlich

@RemcoGerlich 정확합니다. 내 요점은 대답이 주로 어떤 프로그래밍 패러다임과 관련하여 "철학적"이라는 점에 주목하는 것이 었습니다.
발견

답변:


20

Java에는 무료 함수가 없으므로 정적 함수로 일부 형식 클래스에 배치해야합니다. 우아함이 부족할 수 있지만 필요한 해결 방법은 반 패턴이 아닙니다.

다음으로 무료 기능에는 아무런 문제가 없습니다. 실제로 자유 기능을 사용하면 모든 까다로운 세부 사항 대신 공용 인터페이스에만 액세스 할 수 있으므로 커플 링이 줄어 듭니다.

물론, 자유 / 정적 기능을 사용한다고해서 변경 가능한 공유, 특히 전역 상태의 위험을 완화 할 수는 없습니다.


2
@TimothyTruckle 정적이거나 불필요 this하며 적절하게 인스턴스화해야합니다.
Caleth

6
@TimothyTruckle Java이기 때문에. 다른 언어 는 인스턴스 메소드가 아니라고 선언하기 위해 클래스에 넣어야하는 오버 헤드없이 무료 함수 를 가질 수 있습니다 . 그리고 어느 시점에서, 당신은 긴밀한 결합이 있어야합니다. 좋은 여부는 전적으로 해당 기능이 무엇이고 않습니다 .
nvoigt

5
@TimothyTruckle 물론, 상태를 유지하는 것이 "좋지 않은"주된 이유가 될 것입니다.
nvoigt

2
@nvoigt, 나는 그 대답을 명시 적으로 명시 함으로써이 대답이 크게 향상 될 것이라고 생각합니다. 스테이트 풀 스태틱은 나쁘다. 무국적자는 좋다. 정말 간단합니다.
David Arno

3
@TimothyTruckle 그것은 꽉 결합되지 않습니다. 느슨한 결합을 설명하고 있습니다. 이러한 맥락에서 긴밀한 결합은 일종의 상호 의존성을 의미합니다. 단방향 종속성은 해당 요구 사항을 충족하지 않습니다.
JimmyJames

18

정적 유틸리티 또는 도우미 함수는 일부 지침을 준수하는 경우 안티 패턴이 아닙니다.

  1. 부작용이 없어야합니다

  2. 이러한 함수가 작동하는 클래스에 속하지 않는 응용 프로그램 특정 동작에 사용됩니다.

  3. 공유 상태가 필요하지 않습니다

일반적인 사용 사례 :

  • 응용 프로그램 특정 방식으로 날짜 형식 지정
  • 한 유형을 입력으로 사용하고 다른 유형을 리턴하는 함수.

예를 들어 사용자 작업을 한 응용 프로그램에서 활동에 대한 분개를 유지합니다. 후속 날짜를 지정하고 이벤트 알림을 다운로드 할 수 있습니다. 저널 항목을 가져 와서 .ics 파일의 원본 텍스트를 반환하는 정적 유틸리티 클래스를 만들었습니다.

공유 상태가 필요하지 않았습니다. 상태를 변경하지 않았으며 iCal 이벤트를 생성하는 것은 응용 프로그램에 따라 다르며 분개 클래스에 속하지 않았습니다.

정적 함수 또는 유틸리티 클래스에 부작용이 있거나 공유 상태가 필요한 경우 단위 테스트를 위해 조롱하기 어려운 커플 링이 도입되므로이 코드를 다시 평가하는 것이 좋습니다.


4

그것은 당신의 접근 방식에 달려 있습니다. 많은 응용 프로그램은 고전적인 사고 방식 (현재 사용중인 사이트 모음을 포함)과 달리보다 기능적으로 작성되었습니다.

이 사고 방식을 통해 작업자 클래스에는 정적 메소드로 함께 묶을 수있는 많은 유틸리티 메소드가 있습니다. 데이터를 보유하고 전달되는 일반 객체에 더 가깝게 공급 / 사용됩니다.

유효한 접근 방식이며 특히 규모에 따라 잘 작동 할 수 있습니다.


"특히 규모에 관계없이 매우 잘 작동 할 수 있습니다" 아니오 . 프로젝트의 규모가 커짐에 따라 정적 액세스로 인한 긴밀한 커플 링 원인 이 곧 나타날 것입니다.
Timothy Truckle

@TimothyTruckle Agent.Save (obj)가 obj.Save ()보다 훨씬 더 밀접하게 결합되어있는 방법을 설명해 주시겠습니까? 에이전트는 클래스 인스턴스와 같은 정적 메소드에서도 DI / IoC 참조를 얻을 수 있습니다. 참고로 Stack Exchange 자체는 이러한 유형의 사고 방식으로 작성되었으며 다른 ASP.Net 앱보다 확장 성이 뛰어납니다.
추적기 1

"Agent.Save (obj)가 obj.Save ()보다 훨씬 더 밀접하게 결합되어있는 방법을 설명해 주시겠습니까?" 이것은 잘못된 예입니다. 올바른 예는 Agent.Save(obj)vs. agentInstance.Save(obj)입니다. 후자를 사용하면 사용 코드 에 삽입 할 수 agentInstance있습니다. 결과적으로 하위 클래스 를 삽입 Agent하여 Agent재 컴파일하지 않고 다른 "유형"의 사용 코드를 재사용 할 수 있습니다 . 이다 낮은 커플 .
Timothy Truckle

나는 그것이 실제로 몇 가지 일에 있다고 생각합니다. 상태가 필요한가, 얼마나 유연해야하며, 글로벌 / 인스턴스 상태를 갖는 것이 괜찮습니까? 결정하는 것은 각 개발자 / 건축가에게 달려 있습니다. 모든 것을 전체적으로 이해하기 어렵게 만드는 시나리오에 복잡성을 추가하는 것보다 간단한 코드베이스를 선호합니다. 내가 node / js에 대해 좋아하는 것 중 하나는 단순 / 깨끗한 코드를 작성하고 DI / IoC 고유의 코드를 작성하지 않고도 테스트를 계속할 수 있다는 것입니다.
추적기 1

2

개인적으로 그러한 도우미 클래스의 유일한 중요한 부분은 개인 클래스로 만드는 것입니다. 그 외에도-그들은 엄격하게 좋은 아이디어입니다 (적절하게 적용됨).

내가 생각하는 방식은-클래스 (또는 함수)를 구현하는 경우-이와 같은 것이 도움이되고 구현을 더 명확하게 만듭니다. 어떻게 나쁜 것일 수 있습니까? 그리고 종종 특정 형태의 데이터에 의존하는 다른 알고리즘과의 통합 및 사용을 허용하기 위해 개인 도우미 클래스를 정의하는 것이 중요합니다.

'도우미'라고 라벨을 붙일 지 여부는 개인적인 취향의 작은 문제이지만, 구현에 도움이되고 더 많은 사람들에게 관심이 있거나 사용되지 않는다는 것을 의미합니다. 그게 말이되면 이해하십시오!


1
공용 유틸리티 클래스가 여전히 도움이 될 수 있습니다. 주요 예 : java.lang.Math.
amon

1

static오해에 근거한 도우미 클래스 의 보급 . 단지 static"유틸리티 클래스"메소드 만있는 클래스를 호출 한다고해서 POJO에서 일반적인 동작을 작성할 수는 없습니다.

static 도우미 클래스는 세 가지 이유로 반 패턴입니다.

  1. 이 헬퍼 메소드에 대한 정적 액세스는 종속성을 숨 깁니다 . 이러한 "유틸리티 클래스"가 POJO 인 경우 종속 클래스의 생성자 매개 변수 로 종속 클래스에 int를 삽입하여 종속 클래스의 모든 사용자에게 종속성을 명백하게 할 수 있습니다.

  2. 이 헬퍼 메소드에 대한 정적 액세스는 밀접한 결합을 유발 합니다. 이것은 도우미 메소드를 사용 하는 코드 는 재사용하기 어렵고 부작용으로 테스트 할 수 없음을 의미합니다.

  3. 특히 그들이 상태 를 유지한다면 이것들은 단지 전역 변수 일뿐 입니다. 그리고 글로벌 변수가 좋다고 주장하는 사람은 아무도 없습니다 ...

정적 헬퍼 클래스는 STUPID 코드 안티 패턴의 일부입니다 .


글로벌 상태는 질문과 관련이 없습니다 – max630

OP는 다음과 같이 썼다.

그러나 대부분 상황에 따라 다르며 상태가 가득합니다.

정적 statefull 구문 전역 상태입니다.

모든 종류의 코드에서 사용할 수 있습니다. – max630

그렇습니다. 그리고 거의 모든 응용 프로그램에는 일종의 전역 상태 가 필요합니다 .

그러나 전역 상태 ! = 전역 변수 .

의존성 주입을 통해 OO 기술로 전역 상태 를 생성 할 수 있지만 맨 아래에 전역 변수 인 statefull 정적 구조로 전역 상태를 피할 수는 없습니다 .


2
전역 상태는 질문과 관련이 없으며 모든 종류의 코드에서 사용할 수 있습니다.
max630

@ max630 내 업데이트를 참조하십시오
Timothy Truckle

1
커플 링없이 정적 프리 기능을 사용할 수 있습니다. Func<Result, Args>다른 곳에서 인스턴스화되는 객체를 전달 합니다.
Caleth

1
1) 나는 일반적으로 구현을 숨기는 것이 적합한 곳이라고 생각합니다. 2) 모든 것을 인수 / 의존성 주입으로 사용하면 일종의 디자인 타임 커플 링이 생성되므로 긴 종속성 체인에서 서명을 변경하는 데 많은 시간을 소비해야 할 때 이것을 느낄 수 있습니다. 그리고 Logger를 요구하는 모든 단일 함수 또는 기타 교차 문제를 논쟁으로 여깁니다. 그러나 (낮은 수준의 테스트를 더 어렵게 만들 수 있습니다.) 3) 물론 정적 함수는 상태가 없어야합니다.
Alex

1
@ 알렉스는 그 다음 날 그에게 다른 방법으로 주위를 가정 해 봅시다 :의 단위변경해야 할 이유가 같은 코드 참조 (정적 참조 된 "유틸리티"방법 포함)입니다 . 이 장치 내부의 모든 것은 구현 세부 사항 입니다. 다른 것은 의존성 이며, 장치는 정적 액세스 권한을 가져서는 안됩니다.
Timothy Truckle
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.