Java: When to make methods static v. instance [clo

2019-01-31 06:54发布

I have a Gene class that keeps track of genes. Gene has a method for calculating the distance between two genes. Are there any reasons to make it static?

Which is better?

public static int geneDistance(Gene g0, Gene g1)

or

public int geneDistance(Gene other)

Arguments for/against making it static? I understand what it means for a member to be static, I'm just interested in its implications for maximum cleanliness/efficiency/etc.

I repeat the same pattern for returning trimmed versions of two genes, finding matches between genes, finding matches between animals (which contain collections of genes), etc.

标签: java oop static
16条回答
Animai°情兽
2楼-- · 2019-01-31 07:21

public static int geneDistance(Gene g0, Gene g1) would be part of a separate utility class like Collections and Arrays in Java whereas public int geneDistance(Gene other) will be part of the Gene class. Considering you have other operations like "trimmed versions of two genes, finding matches between genes, finding matches between animals (which contain collections of genes), etc" I would create a separate static utility class for them as these operations aren't semantically meaningful to what a Gene is.

If the the semantics of "gene distance" can be wrapped up into your equals(Object o) method then you could consume it there or else include it in your static utility.

查看更多
仙女界的扛把子
3楼-- · 2019-01-31 07:24

Here's a meta-answer, and a fun exercise: survey a bunch of the Java SDK's library classes and see if you can categorize the commonalities between static methods in different classes.

查看更多
老娘就宠你
4楼-- · 2019-01-31 07:25

I'd select the second approach. I see no advantage in making the method static. Since the method is in the Gene class, making it static only adds one extra parameter with no extra gain. If you need a util class, that's a whole different deal. But in my opinion there's usually no need for a util class if you can add the method to the class in question.

查看更多
Luminary・发光体
5楼-- · 2019-01-31 07:27

Two important considerations which have not been mentioned are whether gene1.geneDistance(gene2) is always expected to match gene2.geneDistance(gene1), and whether Gene is and always will be a sealed class. Instance methods are polymorphic with respect to the types of the things upon which they are invoked, but not the types of their arguments. This can cause some confusion if the distance function is supposed to be transitive, but things of different types might compute distance differently. If the distance function is supposed to be transitive, and is defined as being the shortest transformation that either class knows about, a good pattern may be to have a protected instance method int getOneWayDistance(Gene other) and then have something like:

public static int geneDistance(Gene g0, Gene g1)
{
  int d0=g0.getOneWayDistance(g1);
  int d1=g1.getOneWayDistance(g0);
  if (d0 < d1) return d0; else return d1;
}

Such a design will ensure that distance relation behaves transitively, while allowing individual types to report shortcuts to instances of other types that those other types may not know about.

查看更多
混吃等死
6楼-- · 2019-01-31 07:30

I would like to start answering on your question with the new one: What your class Gene is responsible for? May be you have heard about the 'Single-Responsibility Principle': A class should have only one reason to change. So, I believe if you answer this question you will be able to decide how your application should be designed. In this particular case, I would not use neither the first approach nor the second one. In my opinion it is much better to define new responsibility and encapsulate it in a separate class or may be a function.

查看更多
趁早两清
7楼-- · 2019-01-31 07:32

IMO there is no absolute "better", but public int geneDistance(Gene other) is stylistically more similar to other methods in Java (e.g. Object.equals, Comparable.compareTo), so I'd go that way.

查看更多
登录 后发表回答