I am beginning to learn Guice, but I have already encountered a problem. When I try to bind TypeLiteral I receive Cannot resolve method 'to(anonymous com.google.inject.TypeLiteral<>. I tried to look for cause of the problem, but no effect. Maybe anyone knows how to solve it?
Here is the class where I want to use bind().
public class MainModule extends AbstractModule {
protected void configure(){
bind(DeckFactory.class).to(BlackjackDeckCreator.class);
bind(CardFactory.class).to(BlackjackCardCreator.class);
bind(PointsCalculator.class)
.to(BlackjackPointsCalculator.class);
bind(Logic.class)
.toProvider(CompositeGameLogicStrategyProvider.class);
// Problem
bind(new TypeLiteral<Randomizer<BlackjackCard>>() { })
.to(new TypeLiteral<BlackjackCardRandomizer>() {});
//
bind(DecisionTaker.class)
.toProvider(CompositeDecisionTakerProvider.class);
bind(StatisticPrinter.class)
.to(ConsoleStatisticPrinter.class);
bind(HitGameLogicStrategy.class)
.toProvider(HitGameLogicProvider.class);
bind(StandGameLogicStrategy.class)
.toProvider(StandGameLogicProvider.class);
install(new FactoryModuleBuilder().build(GameFactory.class));
install(new FactoryModuleBuilder()
.build(PlayerFactory.class));
bind(StatisticsTemplate.class)
.toProvider(StatisticsTemplateProvider.class);
}
}
Randomizer.java
public interface Randomizer<T extends Card> {
T randomizeCard(List<T> deck);
}
BlackjackCardRandomizer.java
public class BlackjackCardRandomizer implements Randomizer {
private static final Random RANDOM = new Random();
#Override
public Card randomizeCard(List deck) {
Integer randIndex = RANDOM.nextInt(deck.size());
return (Card) deck.get(randIndex);
}
}
Thanks in advance!
You should use the following instead:
bind(new TypeLiteral<Randomizer<BlackjackCard>>() { })
.to(BlackjackCardRandomizer.class);
Just because you have a TypeLiteral as interface doesn't mean you have to use type literals as implementation.
Also, change your extends:
public class BlackjackCardRandomizer implements Randomizer<BlackjackCard> {
private static final Random RANDOM = new Random();
#Override
public BlackjackCard randomizeCard(List<BlackjackCard> deck) {
Integer randIndex = RANDOM.nextInt(deck.size());
return (Card) deck.get(randIndex);
}
}
Related
Best way to implement factory pattern in Spring boot.
I've an interface and multiple implementations of it. During a request, I need to return the bean based on an input string.
There are multiple ways I can do it.. But whats the best way?
interface vehicle {
void drive();
string getVehicleName();
}
#Component
public class Car implements vehicle {
private static string prop = "car";
#Override
string getVehicleName() { return prop;}
#Override
void drive() {}
}
#Component
public class Bike implements vehicle {
private static string prop = "bike";
#Override
string getVehicleName() { return prop;}
#Override
void drive() {}
}
#Service
public class VehicleFactory {
#Autowired
private List<vehicle> vehicles;
private static final HashMap<String, vehicle> requestVehicleMap = new HashMap<>();
#PostConstruct
public void initVehicleFactory() {
for(vehicle vehicle : vehicles) {
requestVehicleMap.put(vehicle.getVehicleName(), request);
}
}
public static vehicle getVehicleImpl(String vehicleName) {
return requestVehicleMap.get(vehicleName);
}
}
This does give me correct class.
Also there is "qualifier" that can be used as Implementing custom factory pattern in Spring.
But is there better approach?
Interface and it's Implementation are good, I would just change the Factory class alone because you already I got the List of Implementation then Why again to initialise it in a Map
I will also comment the suggestions in the code
VehicleFactory
#Service
public class VehicleFactory {
#Autowired
private List<Vehicle> vehicles;
public Vehicle getVehicleImpl(String vehicleName) { // You have already declared as #Service then why use static
return vehicles.stream()
.filter(vehicle -> vehicle.getVehicleName().equalsIgnoreCase(vehicleName)) // This will filter the Impl you needed from others
.findFirst()
.orElseThrow(() -> new RuntimeException(String.format(" Invlaid Vehicle Name - %s", vehicleName))); // Incase Impl is not found it should throw an error or handle in some other ways
}
}
So give it a try
I have a utility class OldRemote which has been deprecated now, but still it will be used for a while till the new class NewRemote is stable. And both the utility classes has the same method names and parameters, But the return type pojo classes are different. Even return type pojo structure is same, but naming is different.
In simple, both the function return types are pojo's with different field names.
Is there any generic way to handle this below usecase ?
I have created a service interface which has the generic method contract of both old and new class.
public interface RemoteService {
//contract [ return type is object to receive all/any Pojo classes ]
Object turnOnTV();
static Service GetRemoteservice(boolean isOldRemote){
if(isOldRemote){
return new OldRemote();
}
return new NewRemote();
}
}
OldRemote Class
public class OldRemote implements RemoteService{
#Override
public OldPojo turnOnTV() {
OldPojo oldPojo = new OldPojo();
System.out.println("OldPojo");
return oldPojo;
}
}
NewRemote Class
public class NewRemote implements Service{
#Override
public NewPojo turnOnTV() {
NewPojo newPojo = new NewPojo();
System.out.println("NewPojo");
return newPojo;
}
}
Demo usage of above implementation.
public class DemoTvRemote {
public static void main(String[] args) {
RemoteService remoteService1 = RemoteService.GetRemoteservice(true);
OldPojo oldRemote = (OldPojo) remoteService1.turnOnTV();
RemoteService remoteService2 = RemoteService.GetRemoteservice(false);
NewPojo shr = (NewPojo) Service2.test();
}
}
This above code works fine. But the problem is I don't want to type cast in all the places where turnOnTV() is used in my entire code base. Even If I have to do that, I will have to write a condition to switch between OldPojo and NewPojo where ever the turnOnTV() is invoked.
Is there any way to solve this problem ?
You could create a base class or interface they both extend/implement.
public abstract class RemoteServiceBase<E> {
public abstract E turnOnTv();
}
public class NewRemoteService extends RemoteServiceBase<NewRemotePojo >{
public NewRemotePojo turnOnTv() {
return new NewRemotePojo();
}
}
public class OldRemoteService extends RemoteServiceBase<OldRemotePojo >{
public OldRemotePojo turnOnTv() {
return new OldRemotePojo();
}
}
This would still only work if you know the service type. Otherwise you work with the common generic type as one would expect.
We can deal with this with the following approach :
1) We can create a dummy POJO class in a common location with having the reference of both OldPojo and NewPojo as data members
public class CommonPojo {
OldPojo oldPojo;
NewPojo newPojo;
public void setOldPojo(OldPojo oldPojo){
this.oldPojo=oldPojo;
}
public void setNewPojo(NewPojo newPojo){
this.newPojo=newPojo;
}
public OldPojo getOldPojo(){
return oldPojo;
}
public NewPojo getNewPojo(){
return newPojo;
}
}
2)We can write a Utility method as follow which can give an object of commonpojo :
public class CommonRemote {
public static CommonPojo turnOnTv(Boolean isOldRemote){
CommonPojo commonPojo = new CommonPojo
if(isOldRemote){
OldPojo oldPojo =new OldPojo();
commonPojo.setOldPojo(oldPojo);
}else{
NewPojo newPojo =new NewPojo();
commonPojo.setNewPojo (newPojo);
}
}
}
3) Use this method as turnOnTv() as Follows :
public class DemoTvRemote {
public static void main(String[] args) {
CommonPojo remote1 = CommonRemote.turnOnTv(true);
OldPojo oldRemote = remote1.getOldPojo();
CommonPojo remote2 = CommonRemote.turnOnTv(false);
NewPojo newRemote = remote2.getNewPojo();
}
}
with this approach with little changes in code We can achieve your requirement without any typecasting.
I have a small problem which I can't figure out to save my life.
Basically I need to register classes anytime dynamically using guice and then loop through them all.
Lets say this is my class to register Strategies but these strategies can be added anytime through the application running.
// Strategy registration may happen anytime, this is just an example
strategyManager.register(ExampleStrategy1.class);
strategyManager.register(ExampleStrategy2.class);
StrategyImpl class
public class StrategyImpl implements Strategy {
#Override
public void register(Class<? extends StrategyDispatcher> strat) {
//Add this class into provider or create an instance for it and add it into guice but how?
}
#Override
public void dispatchStrategy() {
//Find all strategies and execute them
}
}
I've tried using a Provider but have no idea how i'd add the registered class into the provider and retrieve them all?
#Override
protected void configure() {
bind(Strategy.class).toProvider(StrategyProvider.class);
}
My provider class always gets the same instance
public class StrategyProvider implements Provider<StrategyDispatcher> {
public LogManager get() {
return new StrategyDispatcherImpl();
}
}
The strategies that I add extend the StrategyDispatcherImpl class so i could cast them?
I need to add multiple binds to a same instance but it needs to be done dynamically and not using the bind method in configure but another way then be able to find all these strategies and execute them.
If you truly need it to happen at "any time" during the application life cycle then Guice then I think you will need some sort of Guice-aware Factory. I.e.
public class TestStuff {
#Test
public void testDynamicCreation() {
Injector injector = Guice.createInjector();
StrategyManager manager = injector.getInstance(StrategyManager.class);
Hello hello = injector.getInstance(Hello.class);
manager.doStuff();
assertThat(hello.helloCalled, is(false));
manager.register(Hello.class); // DYNAMIC!!
manager.doStuff();
assertThat(hello.helloCalled, is(true));
}
}
interface Strategy {
void doStuff();
}
#Singleton
class Hello implements Strategy {
boolean helloCalled = false;
public void doStuff() {
helloCalled = true;
}
}
class StrategyManager {
private final Collection<Strategy> strategies = new ArrayList<>();
private final StrategyFactory factory;
#Inject
StrategyManager(StrategyFactory factory) {
this.factory = factory;
}
public void register(Class<? extends Strategy> strat) {
strategies.add(factory.create(strat));
}
public void doStuff() {
for (Strategy s : strategies) {
s.doStuff();
}
}
}
class StrategyFactory {
private final Injector injector;
#Inject
StrategyFactory(Injector injector) {
this.injector = injector;
}
public Strategy create(Class<? extends Strategy> clazz) {
return injector.getInstance(clazz);
}
}
If it is not "dynamic" after the initialization phase then you are after the "multibinder" I think.
I have this class
public class ClusterMapPresenter<T extends ClusterItem>{
private ClusterMapView<T> clusterMapView;
public ClusterMapPresenter(ClusterMapView<T> clusterMapView){
this.clusterMapView = clusterMapView;
}
public void createView() {
setItems(getMockItems());
}
private List<T> getMockItems() {
List<T> items = new ArrayList<>();
items.add( new SpeditionClusterItem(new Spedition(Constants.MOCK)));
return items;
}
public void setItems(List<T> clusterItems){
clusterMapView.setMarkers(clusterItems);
}
}
Where SpeditionClusterItem implements ClusterItem.
I only managed to make it work by adding the casting to T to
items.add((T)new SpeditionClusterItem(new Spedition(Constants.MOCK)));
However I don't really like this approach, is there a better way to design this class?
I'll add the next pieces of code:
public interface ClusterMapView<T extends ClusterItem> extends BaseView {
public void setMarkers(List<T> markers);
}
This interface is implemented in the follow activity:
public class Activity implements ClusterMapView<SpeditionClusterItem> {
private ClusterMapPresenter<SpeditionClusterItem> mClusterMapPresenter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
mClusterMapPresenter = new ClusterMapPresenter<>(this);
...
}
#Override
public void setMarkers(List<SpeditionClusterItem> markers) {
mMapFragment.addItemsToMap(markers);
}
}
The point is, I want the activity to show the method with the parameter set in the implementation.
Well, I kind of resolved it by separating the list retrieval from the presenter, adding the list in the constructor.
public ClusterMapPresenter(ClusterMapView<T> clusterMapView, List<T> clusterItems){
this.clusterMapView = clusterMapView;
this.clusterItems = clusterItems;
}
I am not really sure this is good design, but it works. Any suggestion on how to improve it are welcome.
I am getting a compilation error. I want my static method here to return a factory that creates and return Event<T> object. How can I fix this?
import com.lmax.disruptor.EventFactory;
public final class Event<T> {
private T event;
public T getEvent() {
return event;
}
public void setEvent(final T event) {
this.event = event;
}
public final static EventFactory<Event<T>> EVENT_FACTORY = new EventFactory<Event<T>>() {
public Event<T> newInstance() {
return new Event<T>();
}
};
}
Generic parameters of a class do not apply to static members.
The obvious solution is to use a method rather than a variable.
public static <U> EventFactory<Event<U>> factory() {
return new EventFactory<Event<U>>() {
public Event<U> newInstance() {
return new Event<U>();
}
};
}
The syntax is more concise in the current version of Java.
It is possible to use a the same instance of EventFactory stored in a static field, but that requires an unsafe cast.
You have:
public final class Event<T> {
...
public final static EventFactory<Event<T>> EVENT_FACTORY = ...
}
You cannot do this. T is a type that is associated with a specific instance of an Event<T>, and you cannot use it in a static context.
It's hard to give you good alternate options without knowing more about what exactly you are trying to do, as this is sort of an odd-looking factory implementation. I suppose you could do something like (put it in a method instead):
public final class Event<T> {
...
public static <U> EventFactory<Event<U>> createEventFactory () {
return new EventFactory<Event<U>>() {
public Event<U> newInstance() {
return new Event<U>();
}
};
};
}
And invoke it like:
EventFactory<Event<Integer>> factory = Event.<Integer>createEventFactory();
Or, if you don't want to be explicit (you don't really need to be, here):
EventFactory<Event<Integer>> factory = Event.createEventFactory();
Why don't you get rid of the whole static member of Event thing and either keep the factories separate, e.g.:
public final class GenericEventFactory<T> extends EventFactory<Event<T>> {
#Override public Event<T> newInstance() {
return new Event<T>();
}
}
And use, e.g., new GenericEventFactory<Integer>() where appropriate?