0

Ok I am sure I am missing something really, really simple, but I am stuck.

Hypothetical:

I have an interface I wish to make public for people to develop against. Let's say it's an mp3 player. I want to let them know what it can do, without revealing how I do it.

So I have:

public interface IPlayer()
    public void play()

then I have the implementation

public class MP3Player implements IPlayer
    public void play() {
       // my wonderful magical code here
    }

Now the person using my interface to play the song does something like

IPlayer.play();

So my question is, what do I do on my end to link the 3 classes together? I obviously do not want to expose the second part of code, so how do I release this API and link it to my code?

Any help is greatly appreciated.

MaxPower
  • 881
  • 1
  • 8
  • 25

2 Answers2

2

Even though he'll know nothing about the actual implementation of that class (nor even it's existence), you fellow developer still needs to have access to an instance of the class that implements your interface (i.e.: an instance of an MP3Player)... but see it only as an IPlayer.

Thus, you need to provide him with a way to get such an instance. What I'd suggest you to do is having two packages:

package: yourproject.api
 - contains: public interface IPlayer
             public class IPlayers
package: yourproject.impl
 - contains: public class MP3Player implements IPlayer

Where IPlayers would be a factory class that has one method:

public static IPlayer createIPlayer() {
    return new MP3Player();
}

And you would only expose the yourproject.api package :)

ccjmne
  • 9,333
  • 3
  • 47
  • 62
  • What do you mean by expose? If the `impl` package isn't provided at runtime, the application will fail. – Sotirios Delimanolis Jun 24 '14 at 01:39
  • By *expose*, I meant via Maven for example, using: `yourproject.api` to let users who use your project only know about its `api` package. – ccjmne Jun 24 '14 at 01:42
  • Sorry, I meant if the `impl` package isn't provided at runtime (in your example), the application could not run. – Sotirios Delimanolis Jun 24 '14 at 01:43
  • I'm actually only quite familiar with *Maven* and am maybe relying too much on what I'm used to. But, by doing this, the other projects who have a *Maven dependency* to `yourproject` won't have any visibility to the `MP3Player` class or anything that's not in the `yourproject.api` package, even though **at runtime**, the MP3Player implementation will be used, of course, yes. – ccjmne Jun 24 '14 at 01:47
  • So `impl` has to be _provided_ at runtime by some _container_ or such (ex. servlet containers). – Sotirios Delimanolis Jun 24 '14 at 01:48
  • ... Yes, that's exactly the idea, thank you! But it wouldn't be properly *exposed* (available at compile time). Does it seem reasonable? – ccjmne Jun 24 '14 at 01:50
-1
IPlayer player = new MP3Player(); //or any other class that implements IPlayer
player.play();

Its just about depending on abstraction instead of implementations, so if you need to use a different player sometime in the future, you can just instantiate a different one that implements IPlayer (Polymorphism).

class DVDPlayer implements IPlayer {
    public void play(){
    }
}

edit: true, forgot to add that you can implement the Factory Pattern if you only need to create Player objects. (And make constructors package accessible so they can just be called from within the factory)

Ed Morales
  • 1,027
  • 5
  • 9
  • so would I then have to make public that IPlayer is implemented by MP3 player? Would that be necessary for the third party to know? – MaxPower Jun 24 '14 at 01:33
  • If they need to use it then yes, they would need to be able to create a IPlayer variable. – Ed Morales Jun 24 '14 at 01:35