KengoTODA / wish-list

issue list as a public todo list
1 stars 0 forks source link

An explanation why "utility" class is needless, and should be removed #4

Open KengoTODA opened 9 years ago

KengoTODA commented 9 years ago

I strongly believe that utility class is a signal of bad design, especially responsibility of classes.

There is no clear explanation on the WWW, I need to write an article to explain this motivation to remove needless utility classes.

why "utility" is not good

When you want to create an utility class, what you found is: A problem in its responsibility design, or a necessity of creating a new class which has new responsibility.
Because utility classes cannot be best solution: It is like GLOBAL something (which should be reduced in modern programming), it introduces a background knowledge to read your code (), and it combines a lots of classes.

example

If you want to make an utility method which divides your String token into two parts (e.g. header and tail), you should NOT write utility methods like String takeHeaderFrom(String token) nor String[] divideToken(String token).

In this situation, what you should do is creating a class which represents Token.
Then you can implement more intuitive methods like String getHeader() and String getTail(). This design reduces visibility of methods, and maintainer can find these methods easily.

when "utility" is acceptable

Utility class is acceptable only when both of programming language and standard library (e.g. JDK) provide no intuitive solution. For instance, you may create an utility to close resource.

But recently we have several great common library like Apache Commons and Guava. So currently we should have no motivation to create own utility classes.

LeonLiuY commented 9 years ago

I think sometimes Apache common and Guava mislead Java programmers. They are great & useful, but only for fixing the hole of Java(lack of metaprogramming) & JDK(lack of basic functions and hard to extend) design.

LeonLiuY commented 9 years ago

I think your concern on why "utility" is not good and the example above are a little weak to make sense.

XXXTokenlizer.takeHeaderFrom(String)

XXXTokenlizer.divideToken(String)

v.s.

new XXXToken(String).getHeader()

This design reduces visibility of methods, and maintainer can find these methods easily.

I couldn't get this point. They're all wrapped in a class, whether it is static, or not, doesn't make sense on this point. (I think they are same)

The visibility or the easiness to find depends on good or bad organization of static methods, but not whether they are static or not.

Maybe static methods are easy to become a mess makes sense for me.

Still, it depends:

For example,

Math.max(a, b)

vs

new Max(a,b).value()

I prefer the former.

If this token logic, is really simple, common, independent. I would prefer it to be static

KengoTODA commented 9 years ago

Thanks for your feedback! I'll share my opinion.

I couldn't get this point. They're all wrapped in a class, whether it is static, or not, doesn't make sense on this point. (I think they are same)

For me it makes sense, let's have an example in WebApp development; new Token(string) will be handled in Controller/DAO layer and token.getHeader() will be handled in Service layer. So in Service layer, we do not have to consider followings:

This is why we prefer well-defined business (domain, demand) based type than common data type (e.g. String, Integer, BigDecimal etc.). And if you use business based type, there is no need to provide utility.

KengoTODA commented 9 years ago

Maybe static methods are easy to become a mess makes sense for me.

I share the same feeling with you.

LeonLiuY commented 9 years ago

This is why we prefer well-defined business (domain, demand) based type than common data type (e.g. String, Integer, BigDecimal etc.)

In this point I totally agree with you, in the context of domain models. I'm a DDD fan.

But IMO, it is a little out of the title -- why "utility" is not good. I prefer "when utility is not good"

I could agree Do not use utility to make domain model, but not generally "utility" is needless.

In another word, utility is bad when the function of it contains domain specific behavior.

Maybe I'm just struggling on the words.

BTW, I can understand your worry of the problems. I think I gained the same experience like you, that many projects are consisted by anemic domain model(POJO) and dozens of DAOs, services, controllers.

These problems not only happen with utilities.

Many logic implemented in DAOs, services or controllers are actually domain logic, and should be put into domain model. One characteristic of those kind of logic are that, they are easily duplicated, and probably for validations & constraints on the domain object.

I think those problems have already been discussed a lot in the past. DDD theory can help you tell your motivation to others easily. I think we should share more concepts of OO and DDD. They are correct way to make business software.

(IMO, OO is nearly missing in our current products)

KengoTODA commented 9 years ago

Thanks for your review.

I prefer "when utility is not good"

How about "why UNIQUELY DEFINED utility is not good"?

I think that Math.max() method is not the best solution for needs. It should be method of set, list and stream of countable something. But it's a part of JDK (or default library), it's really famous, and its cost to use are simple so it's OK to use.

I don't say that we should use IntStream.of(1, 2).max().get() instead of Math.max(1, 2). :laughing:

KengoTODA commented 9 years ago

About DDD and OO, yes it should be root of problem. The uniquely defined utility is just a smell of them.

We should learn them with care and motivation, to apply them to our products.