Programing

유틸리티 클래스는 사악합니까?

lottogame 2020. 9. 23. 08:03
반응형

유틸리티 클래스는 사악합니까? [닫은]


이 실을 봤어요

"유틸리티"클래스가 사악한 경우 일반 코드를 어디에 두어야합니까?

그리고 유틸리티 클래스가 왜 나쁜지 생각 했습니까?

수십 개의 클래스 깊이가있는 도메인 모델이 있다고 가정 해 보겠습니다. 인스턴스를 xml-ify 할 수 있어야합니다. 부모에게 toXml 메서드를 만드나요? MyDomainXmlUtility.toXml 도우미 클래스를 만들어야합니까? 이것은 비즈니스 요구가 전체 도메인 모델에 걸쳐있는 경우입니다. 실제로 인스턴스 메서드로 속합니까? 애플리케이션의 xml 기능에 대한 많은 보조 메서드가 있다면 어떨까요?


유틸리티 클래스는 정확히 악한 것은 아니지만 좋은 객체 지향 디자인을 구성하는 원칙을 위반할 수 있습니다. 좋은 객체 지향 디자인에서 대부분의 클래스는 단일 항목과 모든 속성 및 작업을 나타내야합니다. 사물에 대해 작업하는 경우 해당 메소드는 해당 사물의 구성원이어야합니다.

그러나 유틸리티 클래스를 사용하여 여러 메서드를 함께 그룹화 할 수있는 경우가 있습니다. 예를 들어 java.util.Collections모든 Java 컬렉션에서 사용할 수있는 여러 유틸리티를 제공하는 클래스가 있습니다. 이들은 특정 유형의 Collection에만 국한되는 것이 아니라 모든 Collection에서 사용할 수있는 알고리즘을 구현합니다.

실제로해야 할 일은 디자인에 대해 생각하고 방법을 배치하는 것이 가장 적합한 위치를 결정하는 것입니다. 일반적으로 클래스 내부의 작업입니다. 그러나 때로는 실제로 유틸리티 클래스입니다. 그러나 유틸리티 클래스를 사용할 때는 임의의 메서드를 여기에 넣지 말고 목적과 기능에 따라 메서드를 구성하십시오.


일반적인 합의는 유틸리티 클래스가 그 자체로 악하지 않다는 것 입니다. 신중하게 사용하면됩니다.

  • 정적 유틸리티 메소드를 일반적이고 재사용 가능하도록 설계하십시오. 상태 비 저장인지 확인하십시오. 즉, 정적 변수가 없습니다.

  • 유틸리티 메서드가 많은 경우 개발자가 쉽게 찾을 수 있도록 클래스로 분할합니다.

  • 도메인 클래스의 정적 또는 인스턴스 메서드가 더 나은 솔루션이 될 수있는 유틸리티 클래스를 사용하지 마십시오. 예를 들어, 추상 기본 클래스 또는 인스턴스화 가능한 도우미 클래스의 메서드가 더 나은 솔루션인지 고려하십시오.

  • Java 8 이상에서는 인터페이스의 "기본 메소드"가 유틸리티 클래스보다 더 나은 옵션 일 수 있습니다.


이 질문을 보는 또 다른 방법은 인용 된 질문에서 "유틸리티 클래스가"악한 "경우" 라는 주장이 밀려 오는 주장임을 관찰하는 것입니다. 나 같은 질문 :

"돼지가 날 수 있다면 우산을 가져 가야하나요?"

위의 질문에서 나는 실제로 돼지가 날 수 있다고 말하는 것이 아닙니다 ... 또는 그들이 있다는 제안에 동의합니다 .

전형적인 "xyz is evil" 진술은 극단적 인 관점을 제시함으로써 생각하게 만드는 수사적 장치입니다. 문자 적 사실의 진술로 의도 된 경우는 드뭅니다.


유틸리티 클래스는이를 지원하는 데이터로 책임을 그룹화하지 못하기 때문에 문제가 있습니다.

그러나 그것들은 매우 유용하며 나는 더 철저한 리팩터링 동안 영구적 인 구조 또는 디딤돌로 항상 구축합니다.

A로부터 클린 코드의 관점 유틸리티 클래스는 단일 책임과 오픈 폐쇄 원칙을 위반. 변경해야 할 이유가 많으며 설계 상 확장 할 수 없습니다. 리팩토링 중에는 중간 정도의 균열로만 존재해야합니다.


나는 그것이 악해지기 시작한다고 생각합니다.

1) 너무 커집니다 (이 경우 의미있는 범주로 그룹화).
2) 정적 메서드가 아니어야하는 메서드가 있습니다.

그러나 이러한 조건이 충족되지 않는 한 매우 유용하다고 생각합니다.


경험의 법칙

이 문제는 두 가지 관점에서 볼 수 있습니다.

  • 전체적인 *Util방법은 종종 잘못된 코드 디자인 또는 지연 명명 규칙의 제안입니다.
  • 재사용 가능한 도메인 간 상태 비 저장 기능을위한 합법적 인 설계 솔루션입니다. 거의 모든 일반적인 문제에 대해 기존 솔루션이 있습니다.

예 1. util클래스 / 모듈 의 올바른 사용법 . 외부 라이브러리 예

대출과 신용 카드를 관리하는 애플리케이션을 작성하고 있다고 가정 해 보겠습니다. 이러한 모듈의 데이터는 웹 서비스를 통해 json형식으로 노출 됩니다. 이론적으로는 객체를에있는 문자열로 수동으로 변환 할 수 json있지만, 이는 바퀴를 재발 명 할 것입니다. 올바른 솔루션은 Java 객체를 원하는 형식으로 변환하는 데 사용되는 외부 라이브러리를 두 모듈 모두에 포함하는 것입니다. (예제 이미지에서 gson 을 보여 주었습니다 )

여기에 이미지 설명 입력


예 2. util클래스 / 모듈 의 올바른 사용법 . util다른 팀원들에게 변명없이 자신 만의 글쓰기

As a use case assume that we need to perform some calculations in two modules of application, but both of them need to know when there are public holidays in Poland. In theory you can make these calculations inside modules, but it would be better to extract this functionality to separate module.

Here is small, but important detail. Class/module you have written is not called HolidayUtil, but PolishHolidayCalculator. Functionally it is a util class, but we have managed to avoid generic word.

여기에 이미지 설명 입력


Utility classes are bad because they mean you were too lazy to think up a better name for the class :)

That being said, I am lazy. Sometimes you just need to get the job done and your mind's a blank .. that's when "Utility" classes start creeping in.


Looking back at this question now, I'd say that C# extension methods completely destroy the need for utility classes. But not all languages have such an in-genius construct.

You also have JavaScript, where you can just add a new function right to the existing object.

But I'm not sure there really is an elegant way to solve this problem in an older language like C++...

Good OO code is kinda hard to write, and is hard to find since writing Good OO requires a lot more time/knowledge than writing decent functional code.

And when you're on a budget, your boss isn't always happy to see you've spent the whole day writing a bunch of classes...


I don't entirely agree that utility classes are evil.

While a utility class may violate OO principals in some ways, they aren't always bad.

For example, imagine you want a function that will clean a string of all substrings matching value x.

stl c++ (as of now) doesn't directly support this.

You could create a polymorphic extension of std::string.

But the problem is, do you really want EVERY string you use in your project to be your extended string class?

There are times when OO doesn't really make sense, and this is one of them. We want our program to be compatible with other programs, so we will stick with std::string and create a class StringUtil_ (or something).

I'd say it's best if you stick with one util per class. I'd say it's silly to have one util for all classes or many utils for one class.


It's very easy to brand something a utility simply because the designer couldn't think of an appropriate place to put the code. There are often few true "utilities".

As a rule of thumb, I usually keep code in the package where it is first used, and then only refactor to a more generic place if I find that later it really is needed elsewhere. The only exception is if I already have a package that performs similar/related functionality, and the code best fits there.


Utility classes containing stateless static methods can be useful. These are often very easy to unit test.


With Java 8 you can use static methods in interfaces ... problem solved.


Most Util classes are bad because:

  1. They broaden the scope of methods. They make code public that would otherwise be private. If the util method is needed by multiple callers in separate classes and is stable (i.e. doesn't need updating) it's better in my opinion to copy and paste private helper methods into the calling class. Once you expose it as an API, you make it harder to understand what the public entry point to a jar component is (you maintain a tree structured called hierarchy with one parent per method. This is easier to mentally segregate into components which is harder when you have methods called from multiple parent methods).
  2. They result in dead code. Util methods over time become unused as your app evolves and you end up with unused code polluting your code base. If it had remained private your compiler would tell you the method is unused and you could just remove it (the best code is no code at all). Once you make such a method non private your computer will be powerless to help you remove unused code. It may be called from a different jar file for all the computer knows.

There are some analogies to static vs dynamic libraries.


Utility classes are not always evil. But they should only contain the methods that are common across a wide range of functionality. If there are methods that are only usable among a limited number of classes, consider creating a abstract class as a common parent and put the methods in it.


클래스에 메서드를 추가 할 수없는 경우 (예 Account: Jr. 개발자의 변경에 대해 잠겨 있음) 다음과 같이 몇 가지 정적 메서드를 Utilities 클래스에 추가합니다.

public static int method01_Account(Object o, String... args) {
    Account acc = (Account)o;
    ...
    return acc.getInt();
}  

참고 URL : https://stackoverflow.com/questions/3340032/utility-classes-are-evil

반응형