Is there anything wrong with a class with all stat

2019-03-08 13:12发布

I'm doing code review and came across a class that uses all static methods. The entrance method takes several arguments and then starts calling the other static methods passing along all or some of the arguments the entrance method received.

It isn't like a Math class with largely unrelated utility functions. In my own normal programming, I rarely write methods where Resharper pops and says "this could be a static method", when I do, they tend to be mindless utility methods.

Is there anything wrong with this pattern? Is this just a matter of personal choice if the state of a class is held in fields and properties or passed around amongst static methods using arguments?

UPDATE: the particular state that is being passed around is the result set from the database. The class's responsibility is to populate an excel spreadsheet template from a result set from the DB. I don't know if this makes any difference.

标签: c# java oop
16条回答
祖国的老花朵
2楼-- · 2019-03-08 13:44

The biggest problem IMO is that if you want to unit test classes that are calling the class you mention, there is no way to replace that dependency. So you are forced to test both the client class, and the staticly called class at once.

If we are talking about a class with utility methods like Math.floor() this is not really a problem. But if the class is a real dependency, for instance a data access object, then it ties all its clients in to its implementation.

EDIT: I don't agree with the people saying there is 'nothing wrong' with this type of 'structured programming'. I would say a class like this is at least a code smell when encountered within a normal Java project, and probably indicates misunderstanding of object-oriented design on the part of the creator.

查看更多
We Are One
3楼-- · 2019-03-08 13:45

I'm not quite sure what you meant by entrance method but if you're talking about something like this:

 MyMethod myMethod = new MyMethod();
 myMethod.doSomething(1);

 public class MyMethod {
      public String doSomething(int a) {
          String p1 = MyMethod.functionA(a);
          String p2 = MyMethod.functionB(p1);
          return p1 + P2;
      }
      public static String functionA(...) {...}
      public static String functionB(...) {...}
 }

That's not advisable.

I think using all static methods/singletons a good way to code your business logic when you don't have to persist anything in the class. I tend to use it over singletons but that's simply a preference.

 MyClass.myStaticMethod(....);

as opposed to:

 MyClass.getInstance().mySingletonMethod(...);

All static methods/singletons tend to use less memory as well but depending on how many users you have you may not even notice it.

查看更多
一夜七次
4楼-- · 2019-03-08 13:48

Well, personnally, I tend to think that a method modifying the state of an object should be an instance method of that object's class. In fact, i consider it a rule a thumb : a method modifying an object is an instance method of that object's class.

There however are a few exceptions :

  • methods that process strings (like uppercasing their first letters, or that kind of feature)
  • method that are stateless and simply assemble some things to produce a new one, without any internal state. They obviously are rare, but it is generally useful to make them static.

In fact, I consider the static keyword as what it is : an option that should be used with care since it breaks some of OOP principles.

查看更多
姐就是有狂的资本
5楼-- · 2019-03-08 13:51

Is there anything wrong with this pattern? Is this just a matter of personal choice if the state of a class is held in fields and properties or passed around amongst static methods using arguments?

Speaking from my own personal experience, I've worked on 100 KLOC applications which have very very deep object hiearchies, everything inherits and overrides everything else, everything implements half a dozen interfaces, even the interfaces inherit half a dozen interfaces, the system implements every design pattern in the book, etc.

End result: a truly OOP-tastic architecture with so many levels of indirection that it takes hours to debug anything. I recently started a job with a system like this, where the learning curve was described to me as "a brick wall, followed by a mountain".

Sometimes overzealous OOP results in classes so granular that it actually a net harm.

By contrast, many functional programming languages, even the OO ones like F# and OCaml (and C#!), encourage flat and shallow hiearchy. Libraries in these languages tend to have the following properties:

  • Most objects are POCOs, or have at most one or two levels of inheritance, where the objects aren't much more than containers for logically related data.
  • Instead of classes calling into each other, you have modules (equivalent to static classes) controlling the interactions between objects.
  • Modules tend to act on a very limited number of data types, and so have a narrow scope. For example, the OCaml List module represents operations on lists, a Customer modules facilitates operations on customers. While modules have more or less the same functionality as instance methods on a class, the key difference with module-based libraries is that modules are much more self-contained, much less granular, and tend to have few if any dependencies on other modules.
  • There's usually no need to subclass objects override methods since you can pass around functions as first-class objects for specialization.
  • Although C# doesn't support this functionality, functors provide a means to subclass an specialize modules.

Most big libraries tend to be more wide than deep, for example the Win32 API, PHP libraries, Erlang BIFs, OCaml and Haskell libraries, stored procedures in a database, etc. So this style of programming is battle testing and seems to work well in the real world.

In my opinion, the best designed module-based APIs tend to be easier to work with than the best designed OOP APIs. However, coding style is just as important in API design, so if everyone else on your team is using OOP and someone goes off and implements something in a completely different style, then you should probably ask for a rewrite to more closely match your teams coding standards.

查看更多
We Are One
6楼-- · 2019-03-08 13:52

What you describe is simply structured programming, as could be done in C, Pascal or Algol. There is nothing intrinsically wrong with that. There are situations were OOP is more appropriate, but OOP is not the ultimate answer and if the problem at hand is best served by structured programming then a class full of static methods is the way to go.

查看更多
别忘想泡老子
7楼-- · 2019-03-08 13:53

"state of a class is ...passed around amongst static methods using arguments?" This is how procedual programming works.

A class with all static methods, and no instance variables (except static final constants) is normally a utility class, eg Math. There is nothing wrong with making a unility class, (not in an of itself) BTW: If making a utility class, you chould prevent the class aver being used to crteate an object. in java you would do this by explictily defining the constructor, but making the constructor private. While as i said there is nothing wrong with creating a utility class, If the bulk of the work is being done by a utiulity class (wich esc. isn't a class in the usual sense - it's more of a collection of functions) then this is prob as sign the problem hasn't been solved using the object orientated paradim. this may or maynot be a good thing

The entrance method takes several arguments and then starts calling the other static methods passing along all or some of the arguments the entrance method received. from the sound of this, the whole class is just effectivly one method (this would definatly be the case is al lthe other static methods are private (and are just helper functions), and there are no instance variables (baring constants)) This may be and Ok thing, It's esc. structured/procedual progamming, rather neat having them (the function and it's helper)all bundled in one class. (in C you'ld just put them all in one file, and declare the helper's static (meaning can't be accesses from out side this file))

查看更多
登录 后发表回答