Java Generics, extended Generics and abstract classes - java

I've got the following classes set up:
public abstract class Process<T,S> {
...
}
public abstract class Resource<T, S extends Process<T, S>> {
protected S processer;
...
}
public class ProcessImpl<EventType1, EventType2> {
...
}
public class ResourceImpl extends Resource<EventType1, ProcessImpl> {
processer = new ProcesserImpl();
...
}
Everything is fine until I get to the ResourceImpl. I'm told that ProcessImpl is not a valid substitute for the bounded parameter <S extends Process<T,S>> of the type Resource<T,S>.
I've tried various ways of getting around this and keep hitting a wall.
Does anyone have any ideas?

public class ProcessImpl<EventType1, EventType2> {
...
}
Because ProcessImpl doesn't extend Process. Your ProcessImpl is not derived from Process, which is what you're declaring that parameter should be.

You might want to do something like this:
public abstract class Process<T, S> {
}
public abstract class Resource<T, S extends Process<T, S>> {
S processor;
}
public class ProcessImpl extends Process<EventType1, ProcessImpl> {
}
public class ResourceImpl extends Resource<EventType1, ProcessImpl> {
}
If you constrain the S parameter of the Resource to be a processor you also need to properly declare it on the ProcessImpl class. I don't know what EventType2 is but it should be implementing Process interface. I assumed you actually want to say ProcessImpl.

I can't see a way to edit the original version, or comment on given answers without a better rep.
This code will exist on a web layer, the eventtype2 is defined on the persistence layer and accessible only in the core layer which exists below this level.
So unfortunately without having a tight coupling, which I would like to avoid, I don't have access to EventType2.

If you don't want your code to depend on some existing package, which contains the Process, you could also introduce some new interface package depending on nothing in the very bottom of the class hierarchy. (If you are able to change the constrains of the inheritance of course.)

Related

Java polymorphism through injection at runtime

I hear that in Java I can achieve polymorphism through injection at runtime. Can someone please show a simple example of how that is done? I search online but I can't find anything: maybe I am searching wrong. So I know about polymorphism through interface and and extension such as
class MyClass extends Parent implements Naming
in such case I am achieving polymorphism twice: MyClass is at once of type Parent and Naming. But I don't get how injection works. The idea is that I would not be using the #Override keyword during injection. I hope the question is clear. Thanks.
So the end result here, per my understanding, is to change the behavior of a method through injection instead of by #Override it during development.
So I know about polymorphism through interface and and extension such as
class MyClass extends Parent implements Naming
This is known as inhertiance and not polymorphism. MyClassis a Parent and MyClass is also a Naming. That being said, inheritance allows you to achive polymorphism.
Consider a class other thanMyClass that also implements Naming :
class SomeOtherClass implements Naming {
#Override
public void someMethodDefinedInTheInterface() {
}
}
Now consider a method that takes a Naming argument somewhere in your code base :
public void doSomething(Naming naming) {
naming.someMethodDefinedInTheInterface();
}
The doSomething method can be passed an instance of any class that implements Naming. So both the following calls are valid :
doSomething(new MyClass());//1
doSomething(new SomeOtherClass());//2
Observe how you can call doSomething with different parameters. At runtime, the first call will call someMethodDefinedInTheInterface from MyClass and the second call will call someMethodDefinedInTheInterface from SomeOtherClass. This is known as runtime-polymorphism which can be achieved through inheritance.
But I don't get how injection works. The idea is that I would not be using the #Override keyword during injection
That's true in the broader sense. To inject something into a class, the class should ideally favor composition over inheritance. See this answer that does a good job in explaining the reason for favoring composition over inheritance.
To extend the above example from my answer, let's modify the doSomething method as follows :
public class ClassHasANaming {
private Naming naming;
public ClassHasANaming(Naming naming) {
this.naming = naming;
}
public void doSomething() {
naming.someMethodDefinedInTheInterface();
}
}
Observe how ClassHasANaming now has-a Naming dependency that can be injected from the outside world :
ClassHasANaming callMyClass = new ClassHasANaming(new MyClass());
callMyClass.doSomething();
If you use the Factory pattern, you can actually chose which subclass gets instantiated at runtime.
Do you think we could have done what we did above using inheritance?
public class ClassIsANaming implements Naming {
public void doSomething() {
someMethodDefinedInTheInterface();
}
#Override
public void someMethodDefinedInTheInterface() {
//....
}
}
The answer is No. ClassIsANaming is bound to a single implementation of the someMethodDefinedInTheInterface method at compile time itself.
`
Taking a contrived example. You have a class Store that stores things:
class Store {
private List l
void store(Object o) {
l.add(o);
}
void setStoreProvider(List l) {
this.l = l
}
}
You can inject the actual List used as the backing storage using setStoreProvider which could be a linked list, array backed list, whatever.
Hence, depending on the injected type your Store class would have the features of the injected type (with regards to memory usage, speed, etc).
This is a kind of polymorphism without the class implementing an interface.

Generics and API design

I am building a library for a product we will be releasing and am trying to design it for compatibility with some design alterations that are presently on the road map. Specifically the library needs to handle different versions of a product which shares the same commands but which have different requirements for the available options for parameters. To accomplish this I have an abstract class for the product with concrete classes for each of the versions. Additionally I have an abstract class for the peripheral which varies and concrete classes for the specific peripherals. I want the concrete versions to implement an abstract method from the abstract class but for a specified type T rather than specifying the super class and then checking instanceof. For example:
class PeripheralA {}
class PeripheralB {}
abstract class AbstractProduct<T> {
public abstract void SomeFunction(T param);
}
class ProductA extends AbstractProduct<PeripheralA> {
public void SomeFunction(T param);
}
class ProductB extends AbstractProduct<PeripheralB> {
public void SomeFunction(T param);
}
The problem is the compiler says I am not implementing the abstract method SomeFunction. My previous design was to not use generics and specify the abstract type. The problem here is that if PeripheralB is passed to ProductA there will be a class cast exception which I can catch, but I would prefer that the code not compile in the first place (and for that matter, not use the class cast). Is there a way to pull off what I am trying to accomplish or am I simply going about the design incorrectly?
Don't use T for the type of the method parameter; use the type you specified for the class, ie PeripheralA, and you must provide a method body for a non-abstract class:
class ProductA extends AbstractProduct<PeripheralA> {
public void SomeFunction(PeripheralA param) {
// your impl here
}

Multiple interfaces in single file

I was just wondering if you can limit the number of interface files on a project. Couple of projects i work with have dozen of interfaces with nothing special in them, and i was thinking can you write all interfaces in single file ? and in specific class point to interface needed ?? i.e:
//interface file
interface InterfaceOne {
}
interface InterfaceTwo{
}
//foo file
public class foo implements InterfaceTwo{
public void foo {
//....
}
}
//foo1 file
public class foo1 implements InterfaceOne{
public void foo {
//....
}
}
or something similar ?
Yes, you can fill a file with interfaces, but those interfaces cannot be public. Thus, they can only be accessible from the package they are defined in. If that's OK with you, you can collect your interfaces into a single file.
Note that this might make your interface definitions harder to find.

Is there a better way to provide a helper methods to test a web application than using a single class?

I'm designing UI Tests for a web application with Selenium in JUnit. I have a base test class with something like this from which I inherit my tests:
public class BaseTest {
protected TestSteps test;
protected Assertions assertion;
// set everything up...
}
and the tests then only look like this:
public class TestX extends BaseTest {
#Test
public testFeature1() {
test.clickSomething().enterSomething(); // method chaining
assertion.assertSomething();
//...
}
}
The problem I'm having: There are different modules in the web app, and Assertions/TestSteps methods that only apply to one module clutter the interface of the Assertions/TestSteps class for the other modules.
Thus I tried to split the Assertions/TestSteps up.
The problem is, the method chaining returns instances of TestSteps. Of course, when I have Module1TestSteps with method doSomethingSpecific() then I would expect test.clickSomething().doSomethingSpecific() to work, but it does not, because clickSomething() would return a TestSteps instance, not a Module1TestSteps instance.
I "solved" this by making an AbstractTestSteps<T extends AbstractTestSteps<T> class (which contains all the base TestSteps methods) protected abstract T getThis();.
I then extend this class like this:
public class BaseTestSteps extends AbstractTestSteps<BaseTestSteps> {
// Constructors
protected BaseTestSteps getThis() {
return this;
}
// that's it, the "base methods" are all inherited from AbstractTestSteps...
}
for the base TestSteps and
public class Module1TestSteps extends AbstractTestSteps<Module1TestSteps> {
// same constructors...
protected Module1TestSteps getThis() {
return this;
}
public Module1TestSteps doSomeThingSpecific() {
// do something
return getThis();
}
}
for my specialized TestSteps. It works for now, but I don't like it because of the following reasons:
All the general methods are in the AbstractTestSteps class, but they are used through an instance of BaseTestSteps
What if I have a submodule of Module1? I can't inherit from Module1TestSteps, only from AbstractTestSteps.
I think it's not trivial to understand the relation of these classes when one of my colleagues tries to add a new TestSteps class.
How can this be made better?
Use the Page Object pattern. That is, create an API for each page so that your tests describe navigating and interacting with pages in a way that describes the user's experience.
It has a few benefits that address your concerns:
It uses composition, not inheritance
It is easy to understand and explain to people maintaining the tests because the tests read like a description of somebody using the application

Java - Using Generics or Inheritance

I have an interface, Resource, which is supposed to wrap something and expose a few operations on the wrapped object.
My first approach was to write the following, with the Strategy pattern in mind.
interface Resource<T> {
ResourceState read();
void write(ResourceState);
}
abstract class AbstractResource<T> implements Resource<T> {
// This is where the Strategy comes in.
protected AbstractResource(ResourceStrategy<T> strat) {
// ...
}
// Both the read and write implementations delegate to the strategy.
}
class ExclusiveResource<T> extends AbstractResource<T> { ... }
class ShareableResource<T> extends AbstractResource<T> { ... }
The two implementations above differ in the locking scheme used (regular locks, or read-write locks).
There is also a ResourceManager, an entity responsible for managing these things.
My idea of usage by the client, would be:
ResourceManager rm = ...
MyCustomObject o = ...
MyCustomReadWriteStrategy strat = ...
rm.newResourceFor(o, "id", strat);
This way, the client would know about resources, but wouldn't have to deal directly with resources (hence the package-private classes). Also, I could make my own implementation of some common resources, like sockets, and the client would only ask for them (ie, I would have to write a SocketStrategy implements ResourceStrategy<Socket>).
ResourceManager rm = ...
rm.newSocketResource("id", host, port);
To access resources, he would request an handler from the manager. This is due to each thread having some specific access privileges, and so the manager would create an handler with the appropriate access privileges.
// This is in the ResourceManager class.
public ResourceHandler getHandlerFor(String id) {
if (!canThreadUseThisResource(id)) throw ...;
if (isThreadReaderOnly()) {
return new ResourceReadHandler( ... );
} else {
return new ResourceWriteHandler( ... );
}
}
This is where the problem kicks in.
This approach seems clean and clear to me, it also seems to be intuitive for the user.
But, as hinted, the manager keeps a mapping from identifiers to resources. How would this be declared, and how would the manager retrieve the resources from the map?
Map<String, Resource<?>> map;
// Can I go around without any specific cast? Not sure yet.
Resource<?> r = map.get(id);
// This could have an enum ResourceType, to check if thread has privileges
// for the specific type.
Is this design acceptable, and/or following good practices?
Alternatively, I could wipe out the generics, and have ExclusiveResource and ShareableResource be abstract and public.
These classes would then be extended, both by me and the client, for every type of resource needed (FileResource extends ExclusiveResource, SocketResource extends ExclusiveResource, ...).
This would probably eliminate the need for the strategy pattern, but would expose more of my package to the user.
Which of these alternatives is the most correct, or widely accepted as good practice?
Edit: After some thought, I think I could be able to remove the generic from the Resource interface, since that's the one causing trouble, and leave it on AbstractResource and its subclasses. The latter could still grant me compile-time verification of the strategies used.
public <T> void newExclusiveResourceFor(
T obj, String id, ResourceStrategy<T> strat) {
ExclusiveResource<T> r = new ExclusiveResource<>(obj, strat);
map.put(id, r);
}
However, following the inheritance way seems to be more correct.
As suggested by dkaustubh and Paul Bellora, as it stands, there is no plausible justification for the generic in the Resource interface. This had gone completely unnoticed by me, at first, since I wanted the implementations to be generic, so I assumed the interface should also be generic. That's not the case.
I still have two options here.
Using Generics
I should remove the generic in the interface. Then, I would end up with the following.
interface Resource {
ResourceState read();
void write(ResourceState);
void dispose();
}
abstract class AbstractResource<T> implements Resource {
/* This is where the Strategy comes in.
* The generic ensures compile-time verification of the
* strategy's type. */
protected AbstractResource(ResourceStrategy<T> strat) {
// ...
}
// Both the read and write implementations delegate to the strategy.
}
class ExclusiveResource<T> extends AbstractResource<T> { ... }
class ShareableResource<T> extends AbstractResource<T> { ... }
// This is the behaviour the client implements, for custom resources.
public abstract class ResourceStrategy<T> {
public abstract ResourceState read(T obj);
public abstract void write(ResourceState state);
public abstract void dispose(T obj);
}
Only ResourceHandler, ResourceManager, ResourceState and ResourceStrategy need to be public, to the client.
Using Inheritance
Using inheritance, I can achieve the same results, with some trade-offs.
public interface Resource {
ResourceState read();
void write(ResourceState);
void dispose();
}
/* These implement only the locking schemes. */
abstract class ExclusiveResource implements Resource { ... }
abstract class ShareableResource implements Resource { ... }
/* The user extends these for custom content and behaviour. */
public abstract class CustomExclusiveResource
extends ExclusiveResource { ... }
public abstract class CustomShareableResource
extends ShareableResource { ... }
Resources are now public to the client.
Conclusions
There are ways to misuse resources with both approaches, bypassing the expected contracts and thread permissions. Both approaches are equal here.
With generics, the inner representation of resources need not be known by the client, since the manager creates the resources in the background. With inheritance, resource creation takes place on the client side, so the manager's API would change to accept provided resources.
Even though Resources are not public, using generics, the client needs to know about the strategies. With inheritance, these are gone, and the public status is assigned to resources instead.
With strategies, the behaviour can be changed in runtime, or there could be different behaviours for the same kind of resource. Without them, the client needs to dispose of a resource, and them re-create it using another subclass that implements different behaviour.
E.g.: small files can be completely read to memory, while large files may require an appropriately sized buffer.
Unless something else is missing, it may just be a matter of choice, and thinking about the desired API and use cases.

Categories

Resources