Suitable design using Generics with Wildcard - java

I am trying to determine if generics would be able to help me with designing a better and scalable solution. In my application, there is a model class which is responsible for loading data from data sources and I use a ModelProxy class to expose some of the methods in the Model class.
public interface ModelProxy {
public int getOrderCount();
public int getCustomerCount();
}
public abstract class AbstractModel {
public abstract ModelProxy loadData(Configuration configuration);
}
public class ConcreteModel extends AbstractModel {
public ModelProxy loadData(Configuration configuration) {
loadInternal();
return new ConcereteModelProxy(this);
}
}
Everything looks good so far, but I am looking to see if generics (with wildcards) can help me design a better solution that would allow to be extend the ModelProxy interface or the Configuration class. For example, in another Concrete Model class I woukd like to use a ExtendedConfiguration class and ExtendedModelProxy.
public ExtendedModelProxy extends ModelProxy {
// Additional methods
public int getTotalCount();
}
public class ConcereteModel2 extends AbstractModel {
public ExtendedModelProxy loadDate(ExtendedConfiguration configuration) {
return new ConcreteExtendedModelProxy(this);
}
}
Will Java Generics help me to achieve something like above?
Or Maybe my design is flawed that I need to re-design it. Any suggestions would be very helpful.
Thanks,
Example Client Code:
public abstract class Service {
public ModelProxy load(Configuration configuration) {
return getModel().loadData(configuration);
}
protected abstract AbstractModel getModel();
}
public class ServiceImpl extends Service {
protected AbstractModel getModel() {
return new ConcreteModel();
}
public static void main() {
Service service = new ServiceImpl();
ModelProxy proxy = service.load(configuration);
System.out.println(proxy.getOrderCount());
}
}
public class ExtendedServiceImpl extends Service {
protected AbstractModel getModel() {
return new ConcreteModel2();
}
public static void main() {
Service service = new ExtendedServiceImpl();
ExtendedModelProxy proxy = (ExtendedModelProxy) service.load(configuration);
System.out.println(proxy.getTotalCount());
}
}
I hope to not have confused with too much. In the ExtendedServiceImpl, you can see I need to cast ModelProxy to ExtendedModelProxy to be able to access the method getTotalCount. My thinking was maybe I can use generics to avoid the casts. Something like
public abstract <M extends ModelProxy, C extends Configuration> M loadData(C configuration);
Maybe I am overcomplicating things and really my current design is all I need. Not sure...

How about this kind of thing
package jj;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.*;
interface Configuration {
}
interface Model {
}
interface OrderModel extends Model {
public int getOrderCount();
public int getCustomerCount();
}
interface CustomerModel extends Model {
public int getName();
public int getAddress();
}
abstract class AbstractModel<M extends Model> {
#SuppressWarnings("unchecked")
public M loadData(Configuration configuration) {
// connect to stuff
Object connection = null;
loadInternal(configuration, connection);
// do some other stuff
return (M) Proxy.newProxyInstance(null, new Class<?>[]{getModelClass()}, null);
}
protected abstract void loadInternal(Configuration configuration,
Object connection);
protected abstract InvocationHandler getInvocationHandler(Object connection);
protected abstract Class<M> getModelClass();
}
class ConcreteOrderModel extends AbstractModel<OrderModel> {
public void loadInternal(Configuration configuration,
Object connection) {
}
protected InvocationHandler getInvocationHandler(Object connection) {
return null;
}
protected Class<OrderModel> getModelClass() {
return OrderModel.class;
}
}
class ConcreteCustomerModel extends AbstractModel<CustomerModel> {
public void loadInternal(Configuration configuration,
Object connection) {
}
protected InvocationHandler getInvocationHandler(Object connection) {
return null;
}
protected Class<CustomerModel> getModelClass() {
return CustomerModel.class;
}
}

Related

Can a class abstract class have a atribute that is a interface in Java?

I am working with the DAO pattern on Java, for the implementation I use a DAO interface that is implemented by a "ItemDAO" abstracted class witch then leads to classes like "ItemDAOTxt" and "ItemDAOXml". This same logic is used on classes like "OrderDAO" and "EmployeesDAO; I am working on a abstract class that will use a DAO in a particular way, "ClassA". So is there a way to make some different classes extends "ClassA" in a way that I can use any DAO I want?
public abstract class ClassA
{
private DAO<T> dao;
//...
}
maybe this:
interface Foo<T> {
T getValue();
}
abstract class Bar<T,U> implements Foo<T> {
Bar(T t,U u) {
this.t=t;
this.u=u;
}
#Override public T getValue() {
return t;
}
T t;
U u;
}
class Baz<T,U>extends Bar<T,U> {
Baz(T t,U u) {
super(t,u);
}
}
public class So56811426 {
public static void main(String[] args) {
Baz<Integer,Character> baz=new Baz<Integer,Character>(42,'x');
System.out.println(baz.getValue()+" "+baz.u);
}
}

How to enforce the concrete class take a concrete instance as argument?

Here is my use case,
public interface dataModel {
//nothing
}
public interface dataRepo {
public doIt(dataModel a);
}
public class concreteDataModel implements dataModel {
public doIt(dataModel a);
}
public class concreteDataRepo implements dataRepo {
public doIt(dataModel a);
}
I feel like i am doing this wrong. I have several datarepo and datamodel. I want the repo takes the datamodel of its own kind. Is there any design pattern to make this clean?
You can use generics.
public interface dataModel {
//nothing
}
public interface dataRepo<T extends dataModel> {
public doIt(T a);
}
public class concreteDataModel implements dataModel {
public doIt(dataModel a);
}
public class concreteDataRepo implements dataRepo<concreteDataModel> {
public doIt(concreteDataModel a);
}
You could try generics:
interface dataModel { }
class concreteDataModel implements dataModel { }
interface dataRepo<E extends dataModel> {
public void doIt(E a);
}
class concreteDataRepo implements dataRepo<concreteDataModel> {
#Override
public void doIt(concreteDataModel a) {
}
}

Avoid casting when using generics

In a project, I have a service and a class using that service. In this example case a repair service that will be used by vehicles. A repair service can only repair a certain type of vehicle: The garage can only repair cars. I need a method in the vehicle to repair it with an applicable service, repairUsingService(..).
My goal is to have a clean Vehicle base class and clean RepairService implementations. I have tried two ways of designing the repair method of the repair service:
repair(Vehicle<T> vehicle): This is ugly because implementations would need to do repair(Vehicle<Car> car) but it is obvious that a car is a vehicle.
repairSimple(T vehicle): Is nice with that but cannot be called from the Vehicle class without an ugly cast.
Is there a way to avoid casting but still only use the generic parameter type T (like in repairSimple(T))?
public class Vehicle<T extends Vehicle<T>> {
public void repairUsingService(RepairService<T> obj) {
obj.repair(this);
obj.repairSimple((T) this);
}
}
public class Car extends Vehicle<Car> {
}
public interface RepairService<T extends Vehicle<T>> {
void repair(Vehicle<T> vehicle);
void repairSimple(T vehicle);
}
public class Garage implements RepairService<Car> {
#Override
public void repair(Vehicle<Car> car) {
System.out.println("Car repaired.");
}
#Override
public void repairSimple(Car car) {
System.out.println("Car repaired.");
}
}
Could you use this implementation? This way both the vehicle knows, what repair service can repair it, and the service knows, what vehicles it can repair.
public interface RepairService<T extends Vehicle<?>> {
public void repair(T vehicle);
}
public interface Vehicle<T extends RepairService<?>> {
public void repairUsingService(T service);
}
public class Car implements Vehicle<Garage> {
#Override
public void repairUsingService(Garage service) {
}
}
public class Garage implements RepairService<Car>{
#Override
public void repair(Car vehicle) {
}
}
public class AuthorizedGarage extends Garage {
}
public class Train implements Vehicle<TrainDepot> {
#Override
public void repairUsingService(TrainDepot service) {
}
}
public class TrainDepot implements RepairService<Train> {
#Override
public void repair(Train vehicle) {
}
}
public class Test {
public static void main(String[] args) {
// this works:
new Car().repairUsingService(new Garage());
new Train().repairUsingService(new TrainDepot());
// and this works
new Garage().repair(new Car());
new TrainDepot().repair(new Train());
// but this does not (which is ok)
//new Garage().repair(new Train());
//new Car().repairUsingService(new TrainDepot());
// this also works
List<Car> cars = new ArrayList<>();
cars.add(new Car());
cars.get(0).repairUsingService(new Garage());
// this also works, if you have an expensive car ;)
new Car().repairUsingService(new AuthorizedGarage());
}
}
You could even have a base class for all your repair services to avoid code repetition:
public abstract class BaseRepairService<T extends Vehicle<?>> implements
RepairService<T> {
#Override
public void repair(T vehicle) {
}
}
Then your Garage would extend a BaseRepairService with a Car type parameter.
One way is to ask the subclass for itself:
abstract class Vehicle<T extends Vehicle<T>> {
public void repairUsingService(RepairService<T> obj) {
obj.repair(this);
obj.repairSimple(getThis());
}
abstract T getThis();
}
class Car extends Vehicle<Car> {
#Override
Car getThis(){
return this;
}
}
Let me present two reasonable alternatives.
The first is a variation of Gafter's Gadget:
public abstract class Vehicle<V extends Vehicle<V>> {
private boolean validate() {
Class<?> cls = getClass();
for(Class<?> sup;
(sup = cls.getSuperclass()) != Vehicle.class;
cls = sup
);
Type sup = cls.getGenericSuperclass();
if(!(sup instanceof ParameterizedType))
return false;
Type arg = ((ParameterizedType)sup).getActualTypeArguments()[0];
if(!(arg instanceof Class<?>))
return false;
return ((Class<?>)arg).isInstance(this);
}
protected Vehicle() {
assert validate() : "somebody messed up";
}
}
Since Vehicle is always parameterized by a subclass, it's OK to use this idiom. During development you run with assertions on and the constructor will throw an error if somebody extends the class incorrectly.
Now the unchecked cast is always safe.
The second is that RepairService no longer carries a type parameter. Instead, you keep a listing of Class<? extends Vehicle> the RepairService can repair.
public interface RepairService {
boolean canRepair(Vehicle v);
// if v can't be repaired, perhaps repair
// throws an exception or returns boolean instead of void
void repair(Vehicle v);
}
public class ServiceStation implements RepairService {
private final List<Class<? extends Vehicle>> types;
public ServiceStation(Class<? extends Vehicle>... types) {
this.types = Arrays.asList(types);
}
#Override
public boolean canRepair(Vehicle v) {
for(Class<? extends Vehicle> c : types) {
if(c.isInstance(v))
return true;
}
return false;
}
#Override
public void repair(Vehicle v) {
if(!canRepair(v))
throw new IllegalArgumentException();
// impl
}
}
At least for the Vehicle/RepairStation analogy this is probably much more usable than trying to force generics in to the design. Vehicle probably doesn't need a type parameter either anymore.
Maybe your actual program is different but you should always consider whether straight program logic solves the problem before introducing a parametric design. Trying to force generics to work in a situation where they are a suboptimal solution gets very awkward.

Implementing guice Provider with a parameterised type

So I am trying to implement the guice Provider interface,
public interface Provider<T> {
T get();
}
and I have another interface called Creator
public interface Creator {
void create();
}
and I want to create a Provider to bind different types of Creator when creating a number of CreatePhases.
private static final class CreatePhaseProvider<T> implements Provider<CreatePhase<T extends Creator>>
{
#Override
public CreatePhase<T> get(){
return null;
}
}
This gives me an error "Syntax error on token "extends" ,,". Any suggestions?
private static final class CreatePhaseProvider<T extends Creator> implements Provider<CreatePhase<T>>
{
#Override
public CreatePhase<T> get(){
return null;
}
}
Oops put the extends in the wrong place!

How can I get the benefits of implementation inheritance without tying my class to a particular implementation?

I'm developing an application which builds on a class written by another developer (for which I do not have the source).
I wish to use all of the functionality of said class but also to extend it with additional functionality. Ordinarily to achieve this I would have defined an interface (MyInterface) and have extended the external class (TheirClass) from my own (MyClass) while implementing MyInterface.
public interface TheirClassInterface {
public void theirMethod1();
public void theirMethod2();
}
public class TheirClass implements TheirClassInterface {
public void theirMethod1() { ... }
public void theirMethod2() { ... }
}
public class TheirOtherClass {
public void theirOtherMethod1(TheirClassInterface o) { ... }
}
public interface MyInterface() {
public void myMethod1();
}
public class MyClass extends TheirClass implements MyInterface {
public void myMethod1() { ... }
}
public class MyNewClass extends MyClass {
public void MyNewClassMethod() { ... }
}
The problem is complicated by the fact that:
I now wish to create a new class (MyNewClass) which adds additional functionality to MyClass but I don't want my code to be dependent on TheirClass.
I wish to be able to use my class as a parameter to the method of TheirOtherClass.
To combat this I refactored my code to instead use composition over inheritance and implementing TheirClassInterface. This works but requires me to implement many methods and delegate them to theirClassObject (in reality TheirClassInterface contains a very large number of methods).
public interface TheirClassInterface {
public void theirMethod1();
public void theirMethod2();
}
public class TheirClass implements TheirClassInterface {
public void theirMethod1() { ... }
public void theirMethod2() { ... }
}
public class TheirOtherClass {
public void theirOtherMethod1(TheirClassInterface o) { ... }
}
public interface MyInterface() {
public void myMethod1();
}
public class MyClass implements TheirClassInterface, MyInterface {
private TheirClass theirClassObject;
public void myMethod1() { ... }
public void theirMethod1() { theirClassObject.theirMethod1(); }
public void theirMethod2() { theirClassObject.theirMethod2(); }
}
public class MyNewClass extends MyClass {
public void MyNewClassMethod() { ... }
}
My question is whether my approach is appropriate in this case and whether it could be improved upon as it seems to me that my code uses an excessive amount of delegation to get the job done.
Many thanks for any guidance anyone can give on this.
Danny
First, as java is a strongly-typed single inheritance language, you cannot escape the delegation.
But you can avoid having to write a lot of delegation CODE, by using a dirty little trick with Proxies and reflection.
Code follows
public interface Interface1 {
void m1();
}
public interface Interface2 {
void m2();
}
public class Class1 implements Interface1 {
public void m1() {
System.out.println(1);
}
}
public class Class2 implements Interface2 {
public void m2() {
System.out.println(2);
}
}
public interface MixinInterface extends Interface1, Interface2 {
}
And this is how the magic happens
package j.with.pseudo.multiple.inheritance;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MixinBuilder {
public static Object buildMixed(Class _interface, Object... impls){
InvocationHandler h = new MixinHandler(_interface.getInterfaces(), impls);
return Proxy.newProxyInstance(MixinBuilder.class.getClassLoader(),
new Class[]{_interface}, h);
}
public static void main(String[] args) {
Class1 o1 = new Class1();
Class2 o2 = new Class2();
MixinInterface almost_like_multiple_inheritance_guy =
(MixinInterface) buildMixed(MixinInterface.class, o1, o2);
almost_like_multiple_inheritance_guy.m1();
almost_like_multiple_inheritance_guy.m2();
}
private static class MixinHandler implements InvocationHandler{
private Class[] interfaces;
private Object[] impls;
public MixinHandler(Class[] interfaces, Object[] impls) {
this.interfaces = interfaces;
this.impls = impls;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
int i=0;
for(Class _interface : interfaces){
if(method.getDeclaringClass().isAssignableFrom(_interface)){
return method.invoke(impls[i], args);
}
i++;
}
// TODO Auto-generated method stub
throw new RuntimeException("Method not found: "+method);
}
}
}
Pretty cool huh? :-)
You can't not-depend on a class if you're extending it; it's like having a definition of Human, which does not depend on the definition of Mammal, your optinos are to rewrite everything in the parent, or depend on it.
Many thanks for the answers so far. I've come up with a solution which I think seems reasonable and allows me to fully encapsulate the foreign class.
At the moment I've returned to the method discussed in the first block of code (repeated and extended below) and am now implementing my MyInterface interface for MyNewClass and delegating all interface operations to a composed object. The object to delegate to is decided at runtime by calling a static method on a Factory.
public interface TheirClassInterface {
public void theirMethod1();
public void theirMethod2();
}
public class TheirClass implements TheirClassInterface {
public void theirMethod1() { ... }
public void theirMethod2() { ... }
}
public class TheirOtherClass {
public void theirOtherMethod1(TheirClassInterface o) { ... }
}
public interface MyInterface() {
public void myMethod1();
}
public class MyClass extends TheirClass implements MyInterface {
public void myMethod1() { ... }
}
public class MyNewClass implements MyInterface {
private MyInterface myObject;
public MyNewClass() {
myObject = MyClassFactory.createMyClass();
}
public void myMethod1() {
myObject.myMethod();
}
public void MyNewClassMethod() { ... }
}
Once again, thanks for the ideas. I'm now going to look into them all and see if I can use them to improve my code.
Cheers,
Danny

Categories