1

I am suing freely the Singleton pattern and I was wondering; when is enough, enough? These are all of my Singletons for now. I am not using all of them together as some call the others.

Database db = Database.getInstance(this);  // wrapper for the library
Realm realm = Realm.getInstance(this);  // library I use
AppUtils appUtils = AppUtils.getInstance(this); // app specific functions that manipulate database queries to produce targeted values
Utils utils = Utils.getInstance();
Generator gen = Generator.getInstance(this); // necessary for the library

I was thinking of also doing something like

AppFragments fr = AppFragments.getInstance(this, AttributeCommonInEveryActivity>)

or should I interface it and do BlerpActivity extends BlourpActivity

Finally, to clear any bias that might occur affecting your opinion. I know it seems like that I only use one design pattern, but I am not. I work with design and utility in mind ^_^

Rabbid76
  • 142,694
  • 23
  • 71
  • 112
MayTheSchwartzBeWithYou
  • 1,111
  • 1
  • 13
  • 29
  • 1
    If `Database db` is indeed "wrapper for the library", then you do not need `Realm realm`, as `db` should hold the `Realm` instance, and you can get it through `db` if something other than `db` needs it. With respect to your other three singletons, without knowing what they do, it is difficult to advise you. Have a specific, concrete reason why the data needs to be global in scope, though. Having singletons because "typing is hard" isn't a good reason. :-) – CommonsWare Jun 20 '15 at 22:56
  • 1
    Seems like you could use a good [DI](https://en.wikipedia.org/wiki/Dependency_injection) framework, such as [Guice](https://github.com/google/guice/wiki/Motivation). That way, you could avoid hand-written JVM singletons (an anti-pattern) altogether, by simply [scoping](https://github.com/google/guice/wiki/Scopes) the created objects appropriately. – Mick Mnemonic Jun 20 '15 at 23:00
  • @CommonsWare Hello and thank you for your feedback. The Realm is the library and not of my own construction. That's how you communicate with the DB (called Realm /lame). It's the only Singleton I can't avoid. Database gets the Context and creates a new RealmInstance to fetch commonly used results. You are absolutely right for the last sentence. I try to make it as modular as I can – MayTheSchwartzBeWithYou Jun 20 '15 at 23:03
  • @MickMnemonic Thank you for the library. Will take a look. The anti - pattern comment seems to come around these days, but I am for "use whatever works" Wow. Went through Guice and it seems like gold. – MayTheSchwartzBeWithYou Jun 20 '15 at 23:07
  • As always it depends... e.g. for the db, if this db class represents a single connection then singleton is the wrong choice probably, if it has a pool of connections and is managing everything then it can be the right choice. – maraca Jun 21 '15 at 00:23

1 Answers1

4

Yes. Yes you are. But before I even get to that, I don't think you're even using the singleton pattern.

Take a method like Realm.getInstance(this), and let's say this is a FooClass. If Realm were a singleton, only one instance of it would ever exist. If that's true, then why would you have to pass in this? Would the result be different if you passed in a different FooClass?

Now to the actual problem- the troubles of singletons have been covered many times before, so I won't go into that. Instead, I'll show you an alternative: dependency injection.

Here's the singleton (?) version of your Realm class:

class Realm {
    private static final Realm instance = new Realm();

    public static Realm getInstance(FooClass foo) {
        // black magic with foo
        return instance;
    }
}

// usage:
Realm realm = Realm.getInstance(this);

Now, here's the DI version:

class Realm {
    public Realm(FooClass foo) {
        // black magic with foo
    }
}

// usage:
Realm realm = new Realm(this);

You tell me which one looks shorter.

Community
  • 1
  • 1
James Ko
  • 25,479
  • 23
  • 92
  • 196
  • Hello. Without knowing the internals or Realm (https://realm.io/) I think they use something like `Realm.getInsance(context)` where they initialize the context as `this.context = context.getApplicationContext()` which is unique and persistent. So as long as you pass any form of `Context` it will always get the same. Same thing applied for my other classes – MayTheSchwartzBeWithYou Jun 21 '15 at 16:11