3

I'm creating a Java class that should encapsulate the six orbital elements of a celestial object, the six osculating elements of the same celestial object, the mass of the body and the name of the body. This means that my Java object must be created with no less than fourteen parameters, and I am now thinking about including another four constants of perturbation as parameters, which will bring that number up to eighteen.

This is how it looks with fourteen parameters:

new Planet("Mercury", 3.3022E23,0.387098, 0., 0.205637, 0.00002123, 7.00559, -0.00590158, 252.252, 149473., 77.4577, 0.1594, 48.3396, -0.122142) 

I've looked around people say that a class that takes in more than ten parameters is probably poorly designed. They also say that a class should do one thing and one thing only. Well, I'm just doing one thing literally, the only thing the class does so far is calculating the position of the celestial object with those parameters as a function of time.

What is best practice for dealing with this situation?

6
  • 1
    More classes for different types of fields and Builder instead of constructor. Commented Feb 23, 2014 at 21:40
  • Can a group of these parameters be described as a single entity? This will allow you to create a class (or subclass) for them and pass them as a single argument. For instance perturbation. Commented Feb 23, 2014 at 21:41
  • If the values don't need to change then a constructor with methods to access only the values you will really need later on is what I do. Commented Feb 23, 2014 at 21:41
  • OK, so far I have three suggestions: Builder, small classes that serve only to encapsulate data (basically arrays), and to keep using the constructor. No resolution because I don't know which one of you to trust. Commented Feb 23, 2014 at 21:45
  • The answer really depends on what you want to achieve here. For example, do you want to make the code to instantiate a Planet shorter? Do you want to make the code more clear about what the numbers do? Do you want to introduce compilation checks for the parameters to the constructor (fourteen parameters: which one is which?)? Commented Feb 23, 2014 at 21:51

4 Answers 4

3

I recommend the Bloch Builder, by Joshua Bloch (item 2) in Effective Java, 2nd edition:

http://www.informit.com/articles/article.aspx?p=1216151&seqNum=2

It is a pattern designed specifically for classes with lots of fields, although it is intended for optional parameters, which is not your case. However, I still think this might be a good way for you to approach it. Such as

Planet p = new Planet.Builder("Mercury").gravity(3.3022E23). anotherAttribute(0.387098).avgTemp(0.). somethingElse(0.205637).andAnotherThing(0.00002123). .... build(); 

(change them to meaningful stuff...I have no idea what the numbers actually represent :)

I recommend against setters in the Planet object, in order to make the fields immutable ( https://www.google.com/search?q=fields+immutable+java+benefit).

I hope this helps.

Sign up to request clarification or add additional context in comments.

10 Comments

This is the right answer but your implementation is totally screwy. It should be new Planet.Builder().name("Mercury").gravity(....).build();
That I'm putting the planet name in the constructor makes it "totally screwy"? I do understand about the underscore though...I happen to do something a bit different, and forgot to change it back.(programmers.stackexchange.com/questions/228939/…). Fixed.
Like the setters also recommended here I don't think this is good OOP design. It allows the user of the class to create objects that will not work, because the method does not have access to all data that it needs.
You're saying that Joshua Bloch's builder pattern is bad OOP design? You're going to have to elaborate a bit more on that one. It can absolutely be designed without sacrificing stability. You validate the data in the build() function, or the Planet constructor (which is what I do), or you can get really tricky and don't allow the build function to be called until each field is properly set (by having the self-returning functions return an alternate NotYetReadyToBeBuilt object...good luck with that one...).
Personally, I've always found these builder pattern's to be a pain. IF a class doesn't need mandatory values before it becomes viable, then this approach is fine. But what I really don't like, is when people do this and forget some values. You end up with a non viable object and you might not know why.
|
2

I would prefer combining the already mentioned solutions - as you write in your intro "I'm creating a Java class that should encapsulate the six orbital elements of a celestial object, the six osculating elements of the same element, the mass of the body and the name of the body.", it seems to me that you can group each six parameters into a new datastructure, so that you end up with four parameters for the Planet constructor (name, mass and the two parameter objects with six own values each) - next step I would ask myself if the six orbital and osculating elements somehow carry extra meaning or are merely a group of six (as in "arbitrary number") elements and can therefore be represented as a list.

Comments

1

I would just have a bunch of setters. Maybe use name as constructor parameter. Just to make it clearer to read. Figuring out which of those 14+ parameters is which is just too difficult for the reader if you set them all in the constructor. Or use a builder as suggested by others.. Both are about the same for me.

1 Comment

Having setters is an anti-pattern. You can't reason behind the state of the object anymore since it's so easily mutable and could be modified by anything.
0

I would recommend you to use Builder Design Pattern. If you are using lombok annotation all the verbose code can be generated by using @Builder annotation.

@Builder class Some{ private String a; private String c; private String d; private String e; } 

You can generate object with the following semantics:

Some someObject = Some.builder() .a("a") .b("b) .c("c") .d("d") .e("e) .build(); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.