4

Recently, I have been coding with the Bukkit API, however my question is not related to it directly.

In the Bukkit API, one can have a single instance of a main class (new MainClass() throws an error), so I was wondering, is it better for me to pass the main class to all of my classes using a constructor, OR should I just use a static method that returns the instance (MainClass.getInstance())

I'm curious as to which one is better (in terms of performance and practice).

Chris Martin
  • 30,334
  • 10
  • 78
  • 137
Horsey
  • 151
  • 1
  • 13
  • You should [pass it](https://en.m.wikipedia.org/wiki/Dependency_injection), but you should [only be passing what is needed](https://en.m.wikipedia.org/wiki/Law_of_Demeter) instead of passing your "main" object to all other instances, then having those instances dig into the inners of the main object. – Vince Jul 19 '17 at 03:45
  • @VinceEmigh Better to implement singleton ? – Suresh Atta Jul 19 '17 at 03:49
  • @SureshAtta That would introduce global state, which makes code [harder to reason with](https://softwareengineering.stackexchange.com/questions/148108/why-is-global-state-so-evil) and harder to test. It would be abuse of the pattern (which is why it's now [considered an anti-pattern](https://stackoverflow.com/questions/12755539/why-is-singleton-considered-an-anti-pattern)). The [recommended alternative would be DI](https://stackoverflow.com/questions/1300655/whats-alternative-to-singleton), more specifically passing only what is needed (rather than main itself) to lower exposure – Vince Jul 19 '17 at 03:52
  • @VinceEmigh Well actually, A lot of methods in the Bukkit API require a main class as a context, so it would be necessary for me to pass the whole main class. Can you tell me why passing using a constructor is prefered over static? It's seems that using a static method is more convenient. – Horsey Jul 19 '17 at 04:16
  • @Horsey It may not be necessary to stick with the [god object](https://en.wikipedia.org/wiki/God_object) approach. But even if so, using DI would make your code easier to test and scale up. I wrote an answer, although there's topic on this all over the place. If you need me to spruce up the answer, let me know. – Vince Jul 19 '17 at 04:35
  • Also, include a code example of the structure – Vince Jul 19 '17 at 04:52

1 Answers1

3

The better approach, in terms of practice, would be your first suggestion:

Pass the main class to all of my classes using a constructor

This is called dependency injection, and is the preferred alternative over global access.

It discourages over-exposure (encourages encapsulation, which is good), and makes testing easier by allowing natural mocking (opposed to using a framework like PowerMock). It's recommended you use this approach if possible.


As for your second suggestion:

Should I just use a static method that returns the instance

This approach tends to be frowned upon, especially if Main is mutable.

If you expose a global mutable instance, you are introducing global state, which tends to be a pain.

Any module that relies on it may wind up be coupled to other modules that rely on it. This is referred to as common coupling, and should be avoided if possible, as it's one of the tightest forms of coupling.

Global access make accessing easier, but at the price of potentially tangling up code. It should really only be used when required.

Vince
  • 14,470
  • 7
  • 39
  • 84