Reference to main class

Discussion in 'Plugin Development' started by timsavage, Aug 1, 2014.

Thread Status:
Not open for further replies.
  1. Offline

    timsavage

    What is the preferred way to get a reference to the main class in other classes?

    I've seen it done by passing a parameter to a class constructor, like this:

    Code:java
    1. onEnable() {
    2. MyClass myClass = new MyClass(this);
    3. }


    And then assigning the parameter to a field in MyClass:

    Code:java
    1. public class MyClass {
    2.  
    3. private final PluginMain plugin;// reference to main class
    4.  
    5. public MyClass(PluginMain plugin) {
    6. this.plugin = plugin;
    7. }
    8. ...


    But I also have seen it done by declaring a static field in the main class, like this:

    Code:java
    1. public final class PluginMain extends JavaPlugin {
    2. static PluginMain plugin;
    3. ...


    Which is then referenced in the other class like this:

    Code:java
    1. PluginMain.plugin.getLogger().info("Output log message from MyClass");


    Finally, I've seen one example that used a getter method in the main class to get a reference.

    So the question is, which of these are correct? Are there situations where one style would be preferred over the other? And would using both styles in the same plugin ever be appropriate?

    Thanks in advance for clarifying this for me. I've searched around the web, but really couldn't get an understanding of why or when you would use one style over the other, or if both are appropriate, even within the same plugin.
     
  2. Offline

    xTigerRebornx

    timsavage Its mainly preference, though I usually recommend the first as "new programmers" don't seem to understand the concept of what static does and simply think that it is "a way to access this from any class" rather then what it actually is.
    Though, a simple idea of how a static getter could be simplified and not involve you handling an instance at all:
    Code:
    public static PluginMain getInstance(){
      return (PluginMain) Bukkit.getPluginManager().getPlugin("PluginMain");
    }
    Where you fill PluginMain and the String argument to match your situation.
     
    xTrollxDudex and mythbusterma like this.
  3. Offline

    mythbusterma

    timsavage

    https://forums.bukkit.org/threads/using-main-class-as-singleton.291234/
    https://forums.bukkit.org/threads/static-instance-of-javaplugin.161067/

    There's tons of other threads if you just Google them, normally you want to use the constructors because it is better OOP and it allows for better testing. In short, you shouldn't use the Singleton design pattern unless you have a very good reason to, and even if you do, it would still be best for most of your classes to take a constructor argument when possible.
     
    xTrollxDudex and TheSpherret like this.
  4. Offline

    1Rogue


    I'd say this is a much better alternative:

    Code:java
    1. public static PluginMain getPlugin() {
    2. return JavaPlugin.getPlugin(PluginMain.class);
    3. }
     
    xTrollxDudex likes this.
  5. Offline

    teej107

    timsavage There's nothing wrong with using the methods posted above, my personal preference is to just use the parameters in the constructor. By using encapsulation, I can easily tell what classes can access from other classes. If I pass a plugin in a constructor of an object, I know that the object needs to access methods from the plugin class.
     
  6. Offline

    timsavage


    I like the simplicity of this, but JavaPlugin.getPlugin() method doesn't seem to exist. Am I missing something?
     
  7. Offline

    ZodiacTheories

    timsavage

    Have you put the class in the parantheses?
    Code:java
    1. JavaPlugin.getPlugin(MainClass.class);


    should work fine
     
  8. Offline

    timsavage

    Ok, I've been building against the RB 1.6.4-R2.0 version of bukkit. Apparently, this method was added later, as it's in the beta and dev builds of the API.

    My reason for asking was because things started to get a little sticky with abstract classes and their children when passing the reference to their constructor methods, and I started to question my methodology after seeing the static reference style in other plugins I've worked on.

    I also felt comfortable with passing a reference as a parameter when the parameter list was otherwise empty, but less so when other parameters where present. It seemed to be out of place, when usually the only reason for needing the reference was to be able to access the plugin's getLogger() method.

    Thanks for the replies and links, it's helped to clarify this for me.
     
  9. Offline

    AoH_Ruthless

    ZodiacTheories
    JavaPlugin.getPlugin(class) only exists for 1.7.2-R0.3 and above (As I learned the hard way). :(

    timsavage
    Otherwise, use a modified singleton structure to retrieve a static instance as others suggested.
     
  10. Offline

    mythbusterma

    timsavage

    In the parent class you could have a protected member "parent" and utilise it like that, or you could have it private and all the child classes could use this.getParent()
     
Thread Status:
Not open for further replies.

Share This Page