设为首页 加入收藏

TOP

Utility Classes Are Evil(二)
2015-07-20 17:39:33 来源: 作者: 【 】 浏览:12
Tags:Utility Classes Are Evil
or every person, then utility classes will be an anathema to you.

The Dependency Inversion Principle

Depend on abstractions, not concrete implementations

This is a simple and powerful principle that produces more testable code and better systems. If you minimize the coupling between a class and the classes that it depends upon, you produce code that can be used more flexibly, and reused more easily.

However, a utility class cannot participate in the Dependency Inversion Principle. It cannot derive from an interface, nor implement a base class. No one creates an object that can be extended with a helper class. This is the partner of the Liskov Substitution Principle, but while utility classes do not violate the LSP, they do violate the DIP.


In summary, utility classes are not proper objects; therefore, they don’t fit into object-oriented world. They were inherited from procedural programming, mostly because most were used to a functional decomposition paradigm back then.

And there are other aritcals about this topic: [Are Helper Classes Evil?][1] by Nick Malik, [Why helper, singletons and utility classes are mostly bad][2] by Simon Hart, [Avoiding Utility Classes][3] by Marshal Ward, [Kill That Util Class!][4] by Dhaval Dalal, [Helper Classes Are A Code Smell][5] by Rob Bagby. [1]: http://blogs.msdn.com/b/nickmalik/archive/2005/09/06/461404.aspx [2]: http://smart421.wordpress.com/2011/08/31/why-helper-singletons-and-utility-classes-are-mostly-bad-2/ [3]: http://www.marshallward.org/avoiding-utility-classes.html [4]: http://www.jroller.com/DhavalDalal/entry/kill_that_util_class [5]: http://www.robbagby.com/posts/helper-classes-are-a-code-smell/

Object-Oriented Alternative

Example1

Let's take NumberUtils for example:

// This is a terrible design, don't reuse
public class NumberUtils {
  public static int max(int a, int b) {
    return a > b ? a : b;
  }
}

In an object-oriented paradigm, we should instantiate and compose objects, thus letting them manage data when and how they desire. Instead of calling supplementary static functions, we should create objects that are capable of exposing the behaviour we are seeking:

public class Max implements Number {
  private final int a;
  private final int b;
  public Max(int x, int y) {
    this.a = x;
    this.b = y;
  }
  @Override
  public int intValue() {
    return this.a > this.b ? this.a : this.b;
  }
}

This procedural call:

int max = NumberUtils.max(10, 5);  

Will become object-oriented:

int max = new Max(10, 5).intValue();

Example2

Say, for instance, you want to read a text file, split it into lines, trim every line and then save the results in another file. This is can be done with FileUtils from Apache Commons:

void transform(File in, File out) {
  Collection
   
     src = FileUtils.readLines(in, UTF-8); Collection
    
      dest = new ArrayList<>(src.size()); for (String line : src) { dest.add(line.trim()); } FileUtils.writeLines(out, dest, UTF-8); }
    
   

The above code may look clean; however, this is procedural programming, not object-oriented. We are manipulating data (bytes and bits) and explicitly instructing the computer from where to retrieve them and then where to put them on every single line of code. We’re defining a procedure of execution.
The OO alternative is:

void transform(File in, File out) {
  Collection
   
     src = new Trimmed( new FileLines(new UnicodeFile(in)) ); Collection
    
      dest = new FileLines( new UnicodeFile(out) ); dest.addAll(src); }
    
   

FileLines implements Collection and

首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇codeforces #185 A Plant(矩阵快.. 下一篇hdu 5017 Ellipsoid(西安网络赛 ..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·「链表」是一种怎样 (2025-12-25 19:20:51)
·C 语言中的链表有哪 (2025-12-25 19:20:48)
·c语言中的链表怎么学 (2025-12-25 19:20:45)
·Redis 分布式锁全解 (2025-12-25 17:19:51)
·SpringBoot 整合 Red (2025-12-25 17:19:48)