Java Factory Pattern With Generics - java

I would like my BallUserInterfaceFactory to return an instance of a user interface that has the proper generic type. I am stuck in the example below getting the error:
Bound mismatch: The generic method getBaseballUserInterface(BASEBALL)
of type BallUserInterfaceFactory is not applicable for the arguments
(BALL). The inferred type BALL is not a valid substitute for the
bounded parameter
public class BallUserInterfaceFactory {
public static <BALL extends Ball> BallUserInterface<BALL> getUserInterface(BALL ball) {
if(ball instanceof Baseball){
return getBaseballUserInterface(ball);
}
//Other ball types go here
//Unable to create a UI for ball
return null;
}
private static <BASEBALL extends Baseball> BaseballUserInterface<BASEBALL> getBaseballUserInterface(BASEBALL ball){
return new BaseballUserInterface<BASEBALL>(ball);
}
}
I understand that it cannot guarantee that BALL is a Baseball, and so there is a parameter type mismatch on the getBaseballUserInterface method call.
If I cast the ball parameter in the getBaseballUserInterface method call, then I get the error:
Type mismatch: cannot convert from BaseballUserInterface<Baseball>
to BallUserInterface<BALL>
Because it can't guarantee that what I am returning is the same type of BALL.
My question is, what is the strategy for dealing with this situation?
(For completeness, here are the other classes required in the example)
public class Ball {
}
public class Baseball extends Ball {
}
public class BallUserInterface <BALL extends Ball> {
private BALL ball;
public BallUserInterface(BALL ball){
this.ball = ball;
}
}
public class BaseballUserInterface<BASEBALL extends Baseball> extends BallUserInterface<BASEBALL>{
public BaseballUserInterface(BASEBALL ball) {
super(ball);
}
}

This is a wrong design pattern. Rather than using one generic method and an if ladder, you should instead use overloading. Overloading eliminates the need for the if ladder and the compiler can make sure the correct method is invoked rather than having to wait till runtime.
eg.
public class BallUserInterfaceFactory {
public static BallUserInterface<Baseball> getUserInterface(
Baseball ball) {
return new BallUserInterface<Baseball>(ball);
}
public static BallUserInterface<Football> getUserInterface(
Football ball) {
return new BallUserInterface<Football>(ball);
}
}
This way you also get the added benefit of compile time errors if your code cannot create a BallUserInterface for the appropriate ball.
To avoid the if ladder you can use a technique known as double dispatch. In essence, we use the fact that the instance knows what class it belongs to and calls the appropriate factory method for us. For this to work Ball needs to have a method that returns the appropriate BallInterface.
You can either make the method abstract or provide a default implementation that throws an exception or returns null. Ball and Baseball should now look something like:
public abstract class Ball<T extends Ball<T>> {
abstract BallUserInterface<T> getBallUserInterface();
}
.
public class Baseball extends Ball<Baseball> {
#Override
BallUserInterface<Baseball> getBallUserInterface() {
return BallUserInterfaceFactory.getUserInterface(this);
}
}
To make things a little neater, it's better to make getBallUserInterface package private and provide a generic getter in BallUserInterfaceFactory. The factory can then manage additional checks like for null and any thrown exceptions. eg.
public class BallUserInterfaceFactory {
public static BallUserInterface<Baseball> getUserInterface(
Baseball ball) {
return new BallUserInterface<Baseball>(ball);
}
public static <T extends Ball<T>> BallUserInterface<T> getUserInterface(
T ball) {
return ball.getBallUserInterface();
}
}
The Visitor Pattern
As pointed out in the comments, one problem of the above is it requires the Ball classes to have knowledge of the UI, which is highly undesirable. You can, however, use the visitor pattern, which enables you to use double dispatch, but also decouples the various Ball classes and the UI.
First, the necessary visitor classes, and factory functions:
public interface Visitor<T> {
public T visit(Baseball ball);
public T visit(Football ball);
}
public class BallUserInterfaceVisitor implements Visitor<BallUserInterface<? extends Ball>> {
#Override
public BallUserInterface<Baseball> visit(Baseball ball) {
// Since we now know the ball type, we can call the appropriate factory function
return BallUserInterfaceFactory.getUserInterface(ball);
}
#Override
public BallUserInterface<Football> visit(Football ball) {
return BallUserInterfaceFactory.getUserInterface(ball);
}
}
public class BallUserInterfaceFactory {
public static BallUserInterface<? extends Ball> getUserInterface(Ball ball) {
return ball.accept(new BallUserInterfaceVisitor());
}
// other factory functions for when concrete ball type is known
}
You'll note that the visitor and the factory function have to use wildcards. This is necessary for type safety. Since you don't know what type of ball has been passed, the method cannot be sure of what UI is being returned (other than it is a ball UI).
Secondly, you need to define an abstract accept method on Ball that accepts a Visitor. Each concrete implementation of Ball must also implement this method for the visitor pattern to work correctly. The implementation looks exactly the same, but the type system ensures dispatch of the appropriate methods.
public interface Ball {
public <T> T accept(Visitor<T> visitor);
}
public class Baseball implements Ball {
#Override
public <T> T accept(Visitor<T> visitor) {
return visitor.visit(this);
}
}
Finally, a bit of code that can put all this together:
Ball baseball = new Baseball();
Ball football = new Football();
List<BallUserInterface<? extends Ball>> uiList = new ArrayList<>();
uiList.add(BallUserInterfaceFactory.getUserInterface(baseball));
uiList.add(BallUserInterfaceFactory.getUserInterface(football));
for (BallUserInterface<? extends Ball> ui : uiList) {
System.out.println(ui);
}
// Outputs:
// ui.BaseballUserInterface#37e247e2
// ui.FootballUserInterface#1f2f0ce9

This is a VERY GOOD question.
You could cast brutely
return (BallUserInterface<BALL>)getBaseballUserInterface((Baseball)ball);
The answer is theoretically flawed, since we force BASEBALL=Baseball.
It works due to erasure. Actually it depends on erasure.
I hope there is a better answer that is reification safe.

public class BaseballUserInterface extends BallUserInterface<Baseball> {
public BaseballUserInterface(Baseball ball) {
super(ball);
}
}
You are using the BallUserInterface as a result of the factory method. So, it can be hidden which concrete ball is used:
public class BallUserInterfaceFactory {
public static BallUserInterface<?> getUserInterface(Ball ball) {
if(ball instanceof Baseball){
return getBaseballUserInterface((Baseball)ball);
}
return null;
}
private static BaseballUserInterface getBaseballUserInterface(Baseball ball){
return new BaseballUserInterface(ball);
}
}
If the client is interested in the type of the ball you should offer a factory method with the concrete ball as parameter:
public static BaseballUserInterface getUserInterface(Baseball ball){
return new BaseballUserInterface(ball);
}

Related

Is forcing a constructor signature a valid reason to use an abstract class rather than an interface?

For a project, I have written the following interface:
public interface IManipulation {
void applyManipulation (double value);
}
Since I would like to force all implementing classes to use a certain constructor signature, I have been considering to change the interface into something like the following abstract class:
(edit: I forgot that it's not possible to have an abstract constructor, so I changed the "solution" below a bit)
public abstract class Manipulation {
private Signal signal;
public Manipulation (Signal signal) {
this.signal = signal;
}
public abstract void applyManipulation (double value);
protected Signal getSignal () {
return signal;
}
}
The reason for wanting to force this constructor is because every implentation should have an instance of Signal available. (and it should not be possible to reassign this signal)
Is this a valid reason to replace the interface with an abstract class (and live with the limitations that come with it), or are there any other potential solutions?
instead of an abstract class you should use an init method for that purpose.
public interface MyInterface{
public void init(YourParam p);
//... other methods
}
in the init you check, if the class is allready initialised if yes, just return.
So you have still an interface and can extend from other classes.
Instead of the constructor you will call the init method for your initialization
EDIT:
public interface IManipulation {
void init(Signal s);
void applyManipulation (double value);
}
You should use abstract classes only, if you have implementation details in it, which are shared by all subclasses. For Method signatures use interfaces
You can make empty constructor private in the abstract class:
abstract class AbstractManipulation {
private final Integer signal;
private AbstractManipulation() {
signal = null;
}
public AbstractManipulation (Integer signal) {
this.signal = signal;
}
}
class Manipulation extends AbstractManipulation {
public Manipulation(Integer signal) {
super(signal);
}
// Cannot redeclare
//public Manipulation() {
//}
}
Then:
public static void main(String[] args) {
// Will not work
//Manipulation m = new Manipulation();
// This one will
Manipulation m = new Manipulation(1);
}
You should not choose for technical reasons but rather logical, ie an abstract class is used when you have a realtion with the sub-classes like for example person: student, teacher. An interface is used when you want to impose a service contract for classes that may not have a relationship between them.

Is it possible to make a reference to an abstract class method in a class method that doesn't extend it?

I'm taking a tutorial on building a simple behavior Ai. It's 'brain' class is abstract and contains states as in "running","success","failure". Now in the my ai unit - droid class i have a method to start the brain of the droid up.
public void update(){
if(Routine.getState()==null){
Routine.start();
}
Routine.act(this, board);
}
Now this isn't possible in java because it's a static reference to a non-static method.
The routine abstract class that i'm trying to reference to here goes like this :
public abstract class Routine {
public enum RoutineState{
Success,
Failure,
Running
}
protected RoutineState state;
protected Routine() { }
public void start(){
this.state = RoutineState.Running;
}
public abstract void reset();
public abstract void act(droid droid, board board);
public void succed(){
this.state = RoutineState.Success;
}
public void Fail(){
this.state = RoutineState.Failure;
}
public boolean isSuccess(){
return state.equals(RoutineState.Success);
}
public boolean isFailure(){
return state.equals(RoutineState.Failure);
}
public boolean isRunning(){
return state.equals(RoutineState.Running);
}
public RoutineState getState(){
return state;
}
}
I've tried copying the method to one of the classes that extends the Routine, but that doesn't work either the same problem comes up.
The static requirement is especially difficult on start() and act() that contain this. and are initializers.
I can only make the method update() like it is, in the routine where i initialize the droid and the board it will be acting on - but i don't see this quite like the solution i'd like to have.
For sure, you can reference an abstract class and call its abstract classes, but the object you exactly reference should be an extender of the abstract class.
For example, create a list of different objects, all extending one abstract class.
public abstract class ExAbstract { public abstract void abstractmethod() {...} }
public class ExampleA extends ExAbstract { #Override... }
public class ExampleB extends ExAbstract { #Override... }
...
List<ExAbstract> list = new ArrayList<>();
list.add(new ExampleA());
list.add(new ExampleB());
...
And then, you can call abstract method on it.
for (ExAbstract test : list){
test.abstractmethod();
}
(Or Java 8)
list.forEach(ExAbstract::abstractmethod);
But if object wasn't extending abstact, and it was abstract itself, it would give an error.
EDIT: In your case, with Routine class, you should make a constructor for it, and then make a new object. (I see you have a constructor already...) If you want to use a method without creating an object, use static
In Routine.java:
public Routine(ExampleArg a){
this.a = a;
}
In your Routine call:
Routine r = new Routine(a);
r.start();

Polymorphic uncurried method calls (adhoc polymorphism) in Java

Let me start with an example.
Say I have an abstract Vehicle class.
public abstract class Vehicle {
public Vehicle() {}
public abstract void ride();
}
And classes Car and Bicycle that inherit from this abstract class.
public class Car extends Vehicle {
public Car() {}
#Override
public void ride() {
System.out.println("Riding the car.");
}
}
public class Bicycle extends Vehicle {
public Bicycle() {}
#Override
public void ride() {
System.out.println("Riding the bicycle.");
}
}
When I apply the ride() method to an object of type Vehicle whose actual type can only be determined at runtime, the JVM will apply the correct version of ride().
That is, in a curried method call of the sort v.ride(), polymorphism works the expected way.
But what if I have an external implementation in form of a method that only accepts a subtype of Vehicle as an argument? So, what if I have repair(Bicycle b) and repair(Car c) methods? The uncurried polymorphic method call repair(v) won't work.
Example:
import java.util.ArrayList;
import java.util.List;
public class Main {
private static void playWithVehicle() {
List<Vehicle> garage = new ArrayList<Vehicle>();
garage.add(new Car());
garage.add(new Car());
garage.add(new Bicycle());
garage.forEach((v) -> v.ride()); // Works.
garage.forEach((v) -> {
/* This would be nice to have.
repair(v.castToRuntimeType());
*/
// This is an ugly solution, but the obvious way I can think of.
switch (v.getClass().getName()) {
case "Bicycle":
repair((Bicycle) v);
break;
case "Car":
repair((Car) v);
break;
default:
break;
}
});
}
private static void repair(Bicycle b) {
System.out.println("Repairing the bicycle.");
}
private static void repair(Car c) {
System.out.println("Repairing the car.");
}
public static void main(String[] args) {
playWithVehicle();
}
}
I have to check for the class name and downcast. Is there a better solution to this?
Edit: My actual purpose is that I'm traversing an abstract syntax tree and I happened to notice that I want double dispatch.
Ast is an abstract class from which actual AST nodes like Assign, MethodCall, or ReturnStmt inherit. body is a polymorphic list of Asts.
Code snippet:
List<Ast> body;
body.parallelStream().forEach((ast) -> {
// This one won't work.
visit(ast);
// This one will work.
if (ast instanceof Assign) {
visit((Assign) ast);
} else if (ast instance of MethodCall) {
visit((MethodCall) ast);
} else if (ast instance of ReturnStmt) {
visit((ReturnStmt) ast);
}
// etc. for other AST nodes
});
private void visit(Assign ast) {
}
private void visit(MethodCall ast) {
}
private void visit(ReturnStmt ast) {
}
My only possibilities of achieving double dispatch is either checking the class and downcasting or properly implementing the visitor pattern, right?
Answer: There is no multiple dispatch in Java and it can be simulated by instanceof or by the visitor pattern.
See here:
Java method overloading + double dispatch
See also here: https://en.wikipedia.org/wiki/Multiple_dispatch#Examples_of_emulating_multiple_dispatch
On a sidenote, exactly this is possible in C# with dynamic calls: How to build double dispatch using extensions
And this is also possible in the many languages that are compiled to JVM bytecode, e.g. Groovy was mentioned.

Identify method's signature using inherited classes in Java's abstract methods

I know this is a very simple question, but I have been working in Python for quite a long time and now that I must go back to Java, I seem to have problems changing the chip and wrapping my head around Java's basic polymorphism.
Is it possible to overwrite (implement, to be precise) a class' abstract method in Java using one of the inherited classes as argument?
Let me explain with a very simple example (following the "almost official" example with shapes)
class Shape {}
class Circle extends Shape {}
class Triangle extends Shape {}
abstract class ShapeDrawer {
abstract void draw(Shape s);
}
class CircleDrawer extends ShapeDrawer {
void draw(Circle c){
System.out.println("Drawing circle");
}
}
Is there any way of having Java identifying the draw method in the CircleDrawer class as the implementation of the abstract draw in ShapeDrawer? (The Circle class extends from Shape after all)
Otherwise put: What I'd like is that the draw method of the CircleDrawer class accepts only instances of type Circle, but at the same time, I'd like to tell the Java compiler that the void draw(Circle c) is actually the implementation of the abstract method abstract void draw(Shape s) located in its parent class.
Thank you in advance.
You can solve your problem by means of generics:
public abstract class ShapeDrawer<T extends Shape> {
public abstract void draw(T shape);
}
public class CircleDrawer extends ShapeDrawer<Circle> {
public void draw(Circle circle) { ... }
}
You can't and there is a very good reason why you can't. Take this declaration
public abstract class ShapeDrawer {
public abstract void draw(Shape s);
}
Now take some code that receives a ShapeDrawer and tries to use it:
public void foo(ShapeDrawer drawer, Shape shape) {
drawer.draw(shape);
}
This code should work because the declaration of ShapeDrawer promises that whoever implements it will provide a method called draw() and that method can deal with any Shape.
But if you were allowed to do this:
public class CircleDrawer extends ShapeDrawer {
public void draw(Circle c) {...}
}
That would no longer hold true, your CircleDrawer would be unable to satisfy the promise that it can deal with any Shape.
However imagine this declaration:
public abstract class ShapeCreator {
public abstract Shape create();
}
public class CircleCreator extends ShapeCreator {
public Circle create() {...}
}
Would this work?
Yes, it would(provided that you use Java 5 or later), because unlike the first declaration, what ShapeCreator promises is that it will have a method called create(), which will return a Shape. Since Circle is a Shape, a subclass of ShapeCreator can decide to return only Circles, no promises are broken.
So how do you achieve what you want? See loonytune's answer :)
Not technically, but you can do a hack around it for the functionality you specified.
public abstract ShapeDrawer {
public abstract void draw(Shape s);
}
public CircleDrawer extends ShapeDrawer {
public void draw(Shape s){
if (s instanceof Circle) {
System.out.println("Drawing circle");
}
}
}
No, Java method signatures must match exactly, you can't use subtypes, or you'll overload a method instead of overriding it.
You can return a subtype, but that's it, and return types aren't part of a method signature.

Using Generalization properly

Suppose you have the following Interfaces
public interface Action {
public State execute(State state);
}
public interface State {
public Collection<Action> getPossibleActions();
}
And this method
public static Collection<State> getAllSuccessorStates(State state){
Collection<State> allSuccessors = new HashSet<>();
for (Action action: state.getPossibleActions()){
State successorState = action.execute(state);
allSuccessors.add(successorState);
allSuccessors.addAll(getAllSuccessorStates(successorState));
}
return allSuccessors;
}
A Concrete State could be for example a Chessboard and an Action the movement of a Piece on the board. Obviously the Chess-Actions need to know the concrete State class:
public class ChessAction implements Action {
#Override
public ChessState execute(ChessState state) {...}
}
Which is ofcourse not an allowed way of overriding execute. What would be the correct way of implementing this, so you can have concrete Actions, that operate on concrete States, which you can give as Arguments to getAllSuccessorStates?
I thought about Generics and also got answers pointing to Generics, but that brings about new Problems. If i write the Action class like this:
public interface Action<E extends State> {
public E execute(E state);
}
i will have the following Problem with ChessState class:
#Override
public Collection<Action<State>> getPossibleActions() {
Collection<Action<State>> actions = new ArrayList<>();
actions.add(new ChessAction());
return actions;
}
the line Actions.add causes the following error: The method add(Action) in the type Collection> is not applicable for the arguments (ChessAction)
Now i could declare Actions as
Collection<Action<ChessState>> actions = new ArrayList<>();
but that wont be a permitted return type.
You can use generics (needs java 1.5 or above):
public interface Action<T extends State> {
public T execute(T state);
}
public class ChessAction implements Action<ChessState> {
#Override
public ChessState execute(ChessState state) {...}
}
Hope that helps.
i found a satisfactory Solution now, which works correctly, doesnt need instanceof and yields no compile warnings:
public interface Action<E extends State<?>> {
public E execute(E state);
}
public interface State<E extends Action<?>> {
public Collection<E> getPossibleActions();
}
public static <A extends Action<S>, S extends State<A>> Collection<S> getAllSuccessorStates(S state){
Collection<S> allSuccessors = new HashSet<>();
for (A localAction: state.getPossibleActions()){
S successorState = localAction.execute(state);
allSuccessors.add(successorState);
allSuccessors.addAll(getAllSuccessorStates(successorState));
}
return allSuccessors;
}
Example of using getAllSuccessorStates (i forgo the implementation Details of the concrete classes here, but the Point should be apparent. You can use the method getAllSuccessorStates with any concrete State class, get Instances of this class in return collection and use them)
public class TestState implements State<TestAction> {...}
public class TestAction implements Action<TestState> {...}
public static void main(String[] args) {
TestState initialState = new TestState("1");
Collection<TestState> allSuccessorStates = getAllSuccessorStates(initialState);
for (TestState state: allSuccessorStates){
System.out.println(state.getStateStr());
}
}
This Question arose from the book "AI-A modern approache" by Stuart Russel and Peter Norvig, in case somebody who reads this book has the same Problem and searches for solutions. In the book the Action and State methods are inside a Problem Class, but i think in this way the OO-design is better.
Well, ChessState must have the same signature of execute as in the Action interface. If you require that ChessAction.execute accept only ChessState, you can write :
public class ChessAction implements Action {
#Override
public State execute(State state)
{
if (!(state instanceof ChessState))
throw new SomeException ();
ChessState cs = (ChessState) state;
...
}
}
You need to implement the same inherited method, and it will work since State is a super class for CheesState.
public class ChessAction implements Action {
#Override
public State execute(State state) {...}
}
Inside the execute method, you can use polymorph method (define in State and redefined ChessState), or you can cast to ChessState (ChessState s = (ChessState) state;), then use it as you need

Categories