I have senderA
and senderB
both implementing sender
and both singletons, and I have a SenderWrapper
(which could possibly implement an ISenderWrapper
) class where I want to represent SenderA
and SenderB
as some sort of static constants.
I'm getting the instances, senderA
and senderB
using Guice
at runtime.
I'm creating many instances of the SenderWrapper
class in runtime (think one per request) and I want to somehow represent senderA
and senderB
in these classes. I will be using them in some methods defined in SenderWrapper
.
I have a couple of solutions to this:
I have two non static fields
senderA
andsenderB
and I pass them from the constructor. (Perhaps I could inject them as well but I'm worried about performance)I can have static fields for
senderA
andsenderB
and set them up in runtime in aGuice
module. But the problem is that these fields will not be const and sends the wrong message that it could be changed during runtime.
public class SenderWrapper implements ISenderWrapper {
public static Sender senderA = null;
public static Sender senderB = null;
public void dummyMethod() {
senderA.send(); senderB.send();
}
}
//in Guice module
@Provides
public providesSenderA(){
Sender senderA = new SenderA();
SenderWrapper.senderA = senderA;
return senderA;
}
- My current solution is using an
Enum
class to representsenderA
andsenderB
. Something like
enum Senders {
senderA, senderB
}
I get a feeling that this is similar to the solution mentioned in point 2, at least functionally. I just hate using enums though.
What is the best, most elegant way to go about this situation? I don't mind refactoring, some level of indirection to solve this.
CodePudding user response:
Why not have an Enum (renamed it a bit, so we know it's an enum, not a class) like this:
enum SenderType {
SENDER_A, SENDER_B
}
And then have your class like this:
public abstract class SenderBase {
public final SenderType myType;
public SenderBase(SenderType pType) {
myType = pType;
}
// optional getter
public SenderType getType() {
return myType;
}
public void send() {
// here, send myType to socket.
// best is to send myType.name(), because ordinal WILL change when you re-order the enums in their enum class.
// or, if you have different send() implementations for A and B, make this method abstract (and empty, remove body) so you FORCE A and B to implement it.
}
}
and your class implementations like this:
class SenderA extends SenderBase {
public SenderA () {
super(SenderType.SENDER_A);
}
}
class SenderB extends SenderBase {
public SenderB () {
super(SenderType.SENDER_B);
}
}
and construct via:
SenderA senderA = new SenderA();
SenderB senderB = new SenderB();
and your Wrapper:
public abstract class SenderWrapper {
public final SenderA mySenderA;
public final SenderB mySenderB;
public SenderWrapper() {
mySenderA = new SenderA();
mySenderB = new SenderB();
}
public void send() {
mySenderA.send();
mySenderB.send();
}
}
actually now that I think about the Wrapper, it might even have an (Array)List where you add all your implementations, and in send()
just iterate over them.
CodePudding user response:
The answer turned out to be anonymous class.
In my Guice module, I do this:
//in Guice module
@Provides
public providesSenderWrapper(final SenderA senderA, final SenderA, senderB){
return new ISenderWrapper {
@Override
public Send() {
senderA.send(); senderB.send();
}
}
}
Neat way to have effective constants in the class.