0

Should I be afraid to move top level classes to inner classes because it will make a class file 1.5k+ lines and 50+ methods long?

I'm using JavaFX for a pet project. I am a new developer (freshman year of college).

I have different classes for managing different parts of my UI. One for drawing the game board, a couple for logic in a side bar tabs, one for the menu bar, etc. One copy of each class is started by the main ViewController.

I've found this to be easy to manage. The problem is that I have to pass a bunch of parameters to each (the different UI elements created from scenebuilder). This sounds like a reason to use inner classes, right? Would a "helper" object that holds these elements be better? It's getting cumbersome to add new variables UI elements and that seems like a bad sign.

TLDR; How do you manage large ViewControllers on large projects?

  • You shouldn't expose any UI elements to other classes: you should keep them encapsulated in either the class that creates and displays them, or the controller class (if you are using FXML). It sounds like you have views and controllers, but no model. You can create a single instance of your model class(es) and share it among the controllers. That both reduces the parameters to pass and keeps UI elements encapsulated. Maybe see http://stackoverflow.com/questions/32342864 – James_D Dec 24 '15 at 14:08
  • @James_D I don't think we understand each other. I do have a model and I'm already creating (and passing around) a single instance of that model. I don't know what you mean when you say "you shouldn't expose any UI elements to other classes." Should I have a single class with 1.5k lines and 50+ methods or not? If I put all the logic for my *entire* UI into a single class that's about what I get. – Tennyson Taylor Bardwell Dec 25 '15 at 14:56
  • You should have separate top-level classes, not one monolithic class with inner classes. You said "I have to pass a bunch of parameters to each (the different UI elements created from scenebuilder)". This is what I mean by "exposing UI elements to other classes", and it means your design is wrong. Each class has a reference to the model: it should just observe properties in the model and update them. Again, see the example I linked. The different controllers make changes which affect other parts of the UI, but no UI elements are passed as parameters between them. – James_D Dec 25 '15 at 15:11
  • @James_D so you're saying I should have multiple fxml files? – Tennyson Taylor Bardwell Dec 26 '15 at 22:34

2 Answers2

1

Creating any class that is 1.5k+ lines and 50 methods long is a object oriented anti-pattern known as the God object.

Also generally avoiding having to pass large number of parameters around is generally accepted reason for using inner classes. You can see Oracles guidance in the page linked below. https://docs.oracle.com/javase/tutorial/java/javaOO/whentouse.html

Generally the best approach to avoid having to pass large numbers of parameters is to basically create classes to encapsulate the parameters, and pass that instances of those classes around instead.

Adam
  • 406
  • 3
  • 6
0

I don't know the specifics of the problem you are working on, but from your question, it looks like you are actually hitting the dependency injection problem.

All of your class depend on one another. For example, a helper might depend on different specific UI elements. Right now, you are wiring those dependencies by hand (passing in all of the dependencies as constructor params when you instantiate the class).

In steps dependency injection. If you are on Android the standard is Dagger and if you are on server, most people still use Guice. The basic idea here is that instead of hand wiring together all of the dependencies of each class, you create a constructor and declare your decencies, the framework will do the rest.

For example:

class A {
   @Inject public A(B b, C c) { ... }
}

class B {
   @Inject public B() { ... }
}

class C {
   @Inject public B() { ... }
}

When yo ask the framework for a new instance of A it will know to go and fetch B and C first and pass them into the constructor.

dolan
  • 1,716
  • 11
  • 22
  • If you want a JavaFX-specific DI framework, the commonly-recommended one is [afterburner.fx](http://afterburner.adam-bien.com/) – James_D Dec 24 '15 at 14:26