I'm trying to learn how to use generics, but I am having a hard time with implementing a factory pattern. I want my DataFactory interface to have a method that returns an object of a class that extends Data. I believe the following code will work, but I'm having a hard time understanding something. Is there a way to avoid having to explicitly specify the second type in the DataFactory interface? Message extends Data<String>, so if T extends Data<U>, shouldn't the U be implied already?
Data class:
public abstract class Data<T> {
private final long id;
private final T content;
private final User sender;
...
}
Message class:
public class Message extends Data<String> {
...
}
DataFactory Interface:
public interface DataFactory<T extends Data<U>, U> {
T newInstance(U content, User sender);
}
MessageFactory Class:
public class MessageFactory implements DataFactory<Message, String> {
#Override
public Message newInstance(String content, User sender) {
return new Message(content, sender);
}
}
Why can't I just write:
public class MessageFactory implements DataFactory<Message>
I'm sorry if this is not a well worded question, I'm not exactly sure how to express it. Originally I didn't want to add type parameters to the class itself, just to the method, but I had more issues trying to make that work. I'm not even sure if I am implementing this correctly. Any help would be appreciated.
Because the type system itself doesn't know that, in the general case, you won't write GenericData<T> extends Data<T>. In this specific case, your Message class has a specific class for the generic type, but you could supply other parameters that wouldn't.
Even though the OP selected already an answer, I want to share additional, relevant information to help others that will come here looking for answers.
Why use generics?
First, we need to understand what is the reason to use generics in the first place. Generic type parameters provide a way for you to re-use the same code with different inputs. For example, you can use generic code to handle a collection of strings, or a collection of widgets with the same code. Before generics, the way we used to handle similar cases was by casting objects. For simplification, let us use OP example and make the Data class non-abstract.
public void doSomethingWithThisInput (Object o) {
if (o instanceof MyClass) {
MyClass myCls = (MyClass) o;
// do something here
}
}
If you ever dealt with Java Collection before generics, you are aware of how painful this used to be. Part of the problem of the old approach was that, in many cases, you didn't discover issues with casting during development. Almost 100% of these cases were discovered at runtime which everyone can agree is very bad. With generics, these issues of object incompatibility are discovered at compile time.
Use cases for generics
The main reason why you would want to use generics is to create a collection of similar "things" inside a class. Examples of this can be found all over the Java language with Set, List, Map, etc.
public abstract class Data<T> {
private T content;
// other methods and attributes omitted;
}
With such a class, you refer to the contents of the Data object generically. The data content can be literally anything: An Email object, a File object, or simply a String. Obviously, the intent here is that if you have a collection of data contents, each object should be of the same type. Creating a collection of disparate contents makes little sense and it is actually counterproductive.
PECS
This is probably the most important lesson you need to learn to how to use generics properly. **PECS** is an acronym that stands for Producers Extend Consumers Super. What does this mean? The best answer I can give you can be found here [https://stackoverflow.com/questions/2723397/what-is-pecs-producer-extends-consumer-super][1]. The link is to an answer here on SO about PECS.
Additional resource
Oracle Java Lesson: Generics
Related
I have the following interface:
public enum AggregatorType{
DATA_BASE,
GLOBAL_CACHE,
//etc
}
public interface DataAggregator<T>{
public AggregatorType getType();
public Collection<T> getData();
}
My question is about putting different types in the same enumeration. To me, it smells like not a good thing at least (because two separate type put in the same place). But I can't see what potential problems it can lead to. Couldn't you help me understand?
Typically using enum types is not a good practice to explicitly define the type of a class because in some other part of your code you want must have a control structure (if-else/switch-case) on this type to separate the way of aggregation.
If I were you I would put an aggregate method in this interface and I would let the Polymorphism mechanism do the magic for me. DataBaseAggregator and CacheAggregator can be to implementation of this interface to define different behaviors in the aggregation of those data.
The subject says it already:
I am thinking right now about following design-problem: I define an interface for a specific type of object that contains various methods.
Now i have the problem, that different implementations of this interface, need additional/different method-parameters (because the way they are implemented makes this necessary), which i cannot incorporate into the interface because they are not common to all interface-implementations.
Now i realize that interface implementations could come with their own property-files, loading their additional parameters from there, but what if these parameters need to be passed in at runtime?
Currently i can only think of passing in a Map<String, Object> parameters to overcome this problem - since JDK-Classes like DocumentBuilderFactory are doing something very similar by providing methods like setAttribute(String attName, Object attValue) this
seems like a feasible approach to solve this problem.
Nevertheless i would be interested in how others solve issues like this, alternative ideas?
I dont want to derive from the interface and add additional methods, since in my case i would then have to throw NotImplementException from the methods of the base interface.
UPDATE:
What could be eventual problems of the Map-approach? Implementing classes are free to ignore it completely if they cant make use of additional parameters.
Others might check if the Map contains the desired parameter-names, check the type of their values and use them if valid, throw an exception if not.
I have also seen this being used for the abstract class JAXBContext, so it seems to be a common approach..
UPDATE:
I decided to go for the map-approach, since i dont see any obvious disadvantages and it is being used in the JDK as well (yes, i know this does not necessarily mean much :)
Since i cannot accept an answer on this question, i will just upvote. Thanks for your input!
regards,
--qu
You should just initialize each inheritor with its own specific required parameters and let the interface method remain parameter-less, as in:
Interface Runnable:
public interface Runnable {
public abstract void run();
}
Implementation:
public class MyRunnable {
private final String myConcreteString;
public MyRunnable(String myConcreteString) {
this.myConcreteString = myConcreteString;
}
public void run() {
// do something with myConcreteString
}
}
The point of the interfaces is to have something that is common to all implementations. By trying to do this you destroy the whole reason why interfaces exists.
If you absolutely must do that there is a simple enough way that I have used before.
My answer is in C++ because I'm just not that fluent in other languages. I'm sure there are ways to implement this in java as well.
SomeMethod(void* parameterData);
void* parameterData is a pointer to a struct containing your data. In each implementation you know what you are receiving. You can even have a enum to tell you what kind of data you are receiving.
SSomeData* data = (SSomeData)parameterData
EDIT:
Another approach would be to create a new interface for the parameters: IParameterData.
Inside that interface you have 2 methods: GetParameter(name) and SetParameter(name).
For each implementation of your primary interface you create a implementation of IParameterData.
I hope it helps
couldn't you design subinterfaces that extend your (super)interface?
anyhow I see a design problem if you need a method with different parameters depending on the implementation!
edit: code to clarify
interface CommonBehaviour
{
void methodA(int aParam);
}
interface SpecificBehaviour extends CommonBehaviour
{
void methodB(int aParam, int anotherParam);
}
class SpecificBehaviourImpl implements SpecificBehaviour
{
void methodA(int aParam)
{
//do something common
}
void methodB(int aParam, int anotherParam)
{
//do something specific
}
}
CommonBehaviour myObj = new SpecificBehaviourImpl();
EDIT: You may benefit from the Command pattern:
"Using command objects makes it easier to construct general components that need to delegate, sequence or execute method calls at a time of their choosing without the need to know the owner of the method or the method parameters."
(source: wikipedia)
I don't think the Map approach to be any good, I may accept it as a fix of existing code that would allow you to have any parameter number and type, but without formal checks! You're trying to define a common behavior (interface methods) given a variable, runtime, state.
You should introduce parameter object representing a super-set of possible arguments.
In your place, I would consider finding appropriate design pattern to your problem, rather then try to bend the interface methods to suit your needs. Look into Strategy Pattern for starters.
Can you invert the problem, and implement an interface on the user of these objects which they can query for the additional parameters?
So, when you instantiate these objects implementing the common interface, you also pass in (e.g. to their constructor) an object which provides a way of accessing the additional parameters they might require.
Say your interface has a method 'doSomething' taking parameter 'a', but you have an implementation that needs to know what 'b' is inside this 'doSomething' method. It would call 'getB' on the object you provided to it's constructor to get this information.
I have seen that if I have interface named interfaceABC.
Example:
public class ABController extends AbstractCOntroller {
private interfaceABC inter;
I am confused that why we make object from interface not from class that implemented it.
private interfaceABC inter;
i am confused that why we make object from interface not from class that implemented it
We haven't created an object/instance yet. We simply declared a variable to hold it. We don't make objects from interfaces (you have to use a concrete class to do that), but we will often use interface types instead of the actual concrete class for variable declarations, method parameter types, and method return types.
Take this for exmaple:
List<Example> examples = new ArrayList<Example>();
...
public List<Example> getExamples() { return examples; }
Using the interface List here instead of the concrete class ArrayList follows a common best practice: to use interfaces instead of concrete classes whenever possible, e.g. in variable declarations, parameters types, and method return types. The reason this is considered a best practice is:
Using the interface for declarations and for return types hides an implementation detail, making it easier to modify in the future. For example, we may find that the code works better using a LinkedList rather than ArrayList. We can easily make this change in one place now, just where the list is instantiated. This practice is especially key for method parameter types and method return types, so that external users of the class won't see this implementation detail of your class and are free to change it without affecting their code.
By using the interface, it may be clearer to a future maintainer that this class needs some kind of List, but it does not specifically need an ArrayList. If this class relied on some ArrayList-specific property, i.e. it needs to use an ArrayList method, than using ArrayList<Example> examples = ... instead of List<Example> examples = ... may be a hint that this code relies on something specific to an ArrayList.
It may simplify testing/mocking to use the more abstract List than to use the concrete class ArrayList.
We haven't made an object, we've made a reference.
By using a reference to the interface rather than a concrete class, we are free to swap in a different implementation of the interface, with no changes to this code. This improves encapsulation, and also facilitates e.g. testing (because we can use mock objects). See also dependency injection.
This is actually very useful. Take the example that we're using a list.
public class A {
private List<String> list;
public A(List<String> list) {
this.list = list;
}
}
This allows class A to work with all operations defined by the list interface. The class constructing A can now give any implementation without changing the code of class A, hence promoting encapsulation, code reuse, testing etc. For instance:
new A(new ArrayList<String>());
For a private field, it does not really matter too much, as that's an implementation detail anyway. Many people will still on principle use the interface everywhere they can.
On the other hand, protected fields (and of course the parameters of public methods) form an API that becomes much more flexible by using interfaces, because that allows subclasses/clients to choose which implementation class they want to use, even classes they supply themselves and which didn't even exist when the API was created.
Of course, if you have a public set method or constructor that sets the private field, then you have to use the interface type for the field as well.
Imagine a gift-wrapping stall in a shop that has a machine which will wrap any box.
The machine is simply designed and built to wrap a rectangular box, it shouldn't matter whether there's chocolate in the box or a toy car. If it mattered, the machine would quite obviously be flawed.
But even before you get to that stall, you have to buy that gift: so the cashier scans the barcode first. The barcode scanner is another example of the same principle: it will scan anything as long as it has a recognisable barcode on it. A barcode scanner that only scanned newspapers would be useless.
These observations led to the concept of encapsulation in software design, which you can see in action when a class refers to an object by an interface only, and not its concrete class.
I have a little problem understanding the Java language
public class PhonebookEntryList extends List<PhonebookEntry>
{
public PhonebookEntryList(String filename) throws IOException
{
//loadListFromFilename(filename);
}
public void saveListToFilename(String filename) throws IOException
{
//Do something to save it to a file
}
}
I can't do this, because List is a generic Type (of course). I know what that means, but at the moment I can't think of a Solution for this problem.
Can you help me to solve it? Thanx!
No, your only problem is that you're extending an interface; you must implement it instead.
public class PhonebookEntryList implements List<PhonebookEntry>
should work; or you might prefer to extend a concrete class:
public class PhonebookEntryList extends ArrayList<PhonebookEntry>
or
public class PhonebookEntryList extends LinkedList<PhonebookEntry>
You can't do that because List is an interface. But!
You shouldn't extend or implement a List class to make a PhonebookEntryList, it's a design error.
You should do:
public class PhonebookEntryList
{
private List<PhonebookEntry> entries;
public PhonebookEntryList(String filename) throws IOException
{
//loadListFromFilename(filename);
}
public void saveListToFilename(String filename) throws IOException
{
//Do something to save it to a file
}
}
I.e. your PhonebookEntryList should contain a list instead of inheriting it.
List<T> is an interface, not a class, so you can't inherit from it. You can, however, inherit from a generic type, supplying the type argument, if you wish to create, e.g. a collection for a specific type with some behaviour specific only to that type.
Your Problem is that you are trying to extend an interface rather than implement it.
Composition is what you want. Create a class that wrapps a List (or something that iplements that interface)
and add functionality.
Should I mention that List is an Interface and not a Class? Nah. I think you got the point by now.
I would like to point out, however, that it's usually better NOT to embed the persistence mechanism within the list class. There's this thing called the Visitor pattern that works better. By placing the actual persistency code in a seperate class, the overall logical complexity of the app gets reduced (at the expense of an extra class), and your phonebook becomes liberated to be used in places where having dependencies on the persistency mechanism that looked good when you first designed the code don't look so good anymore. For example, if you wanted to make the Phonebook be an item in an ORM-referenced database.
List<T> is an interface.
If you want to extend a class you'll have to choose an implementation (ArrayList<T> maybe): extends ArrayList<PhonebookEntry>
If you want to implement a List change your code to: implements List<PhonebookEntry>
If you look at the JavaDoc for List, you'll see (as others mentioned) that it's an interface, not a class. What you most likely want to do is look on the same JavaDoc page at "All Known Implementing Classes" and you'll see AbstractList. Extend this. Alternatively, extend one of the non-abstract List implementations.
Note: Most of the time when someone starts to extend one of the Java Collection classes, you're going down the wrong route. Usually, it's better to use one of the existing collections in your class and proxy any collections-style requests that you need. Or return an unmodifiable proxy of your collection:
public class MyClass {
private final List<PhonebookEntry> myList = new LinkedList<PhonebookEntry>();
public List<PhonebookEntry> getList() {
return Collections.unmodifiableList(myList);
}
}
Usually, it's best to extend a class only if you intend to have different behavior than the class you are extending. Inheritance is more brittle than composition.
Closed. This question is opinion-based. It is not currently accepting answers.
Closed 4 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
Let's say I wanted to define an interface which represents a call to a remote service. Now, the call to the remote service generally returns something, but might also include input parameters. Suppose that an implementing class will typically only implement one service method. Given the above information, is the following a poor design (it doesn't quite feel right):
public interface IExecutesService<A,B>
{
public A executeService();
public A executeService(B inputParameter);
}
Now, let's say that I implement this interface with a class that executes a remote service with an input parameter:
public class ServiceA implements IExecutesService<String,String>
{
public String executeService()
{
//This service call should not be executed by this class
throw new IllegalStateException("This method should not be called for this class...blabla");
}
public String executeService(String inputParameter)
{
//execute some service
}
I have two questions regarding the above:
Is the use of a generic interface (IExecutesService<A,B>) good in the case where you want to provide subclasses which require different input parameters and return types for the interface methods?
How can I do the above better? I.e. I want to group my service executors under a common interface (IExecutesService); however, an implementing class will typically only implement one of the methods, and the use of an IllegalStateException feels really ugly. Also, the B type parameter in IExecutesService<A,B> will be redundant for an implementing class that calls a service without any input parameters. It also seems overkill creating two separate interfaces for the two different service calls.
Here's one suggestion:
public interface Service<T,U> {
T executeService(U... args);
}
public class MyService implements Service<String, Integer> {
#Override
public String executeService(Integer... args) {
// do stuff
return null;
}
}
Because of type erasure any class will only be able to implement one of these. This eliminates the redundant method at least.
It's not an unreasonable interface that you're proposing but I'm not 100% sure of what value it adds either. You might just want to use the standard Callable interface. It doesn't support arguments but that part of the interface has the least value (imho).
Here's another suggestion:
public interface Service<T> {
T execute();
}
using this simple interface you can pass arguments via constructor in the concrete service classes:
public class FooService implements Service<String> {
private final String input1;
private final int input2;
public FooService(String input1, int input2) {
this.input1 = input1;
this.input2 = input2;
}
#Override
public String execute() {
return String.format("'%s%d'", input1, input2);
}
}
I'd stay with two different interfaces.
You said that 'I want to group my service executors under a common interface... It also seems overkill creating two separate interfaces for the two different service calls... A class will only implement one of these interfaces'
It's not clear what is the reason to have a single interface then. If you want to use it as a marker, you can just exploit annotations instead.
Another point is that there is a possible case that your requirements change and method(s) with another signature appears at the interface. Of course it's possible to use Adapter pattern then but it would be rather strange to see that particular class implements interface with, say, three methods where two of them trow UnsupportedOperationException. It's possible that the forth method appears etc.
As an answer strictly in line with your question, I support cleytus's proposal.
You could also use a marker interface (with no method), say DistantCall, with several several sub-interfaces that have the precise signatures you want.
The general interface would serve to mark all of them, in case you want to write some generic code for all of them.
The number of specific interfaces can be reduced by using cleytus's generic signature.
Examples of 'reusable' interfaces:
public interface DistantCall {
}
public interface TUDistantCall<T,U> extends DistantCall {
T execute(U... us);
}
public interface UDistantCall<U> extends DistantCall {
void execute(U... us);
}
public interface TDistantCall<T> extends DistantCall {
T execute();
}
public interface TUVDistantCall<T, U, V> extends DistantCall {
T execute(U u, V... vs);
}
....
UPDATED in response to OP comment
I wasn't thinking of any instanceof in the calling. I was thinking your calling code knew what it was calling, and you just needed to assemble several distant call in a common interface for some generic code (for example, auditing all distant calls, for performance reasons).
In your question, I have seen no mention that the calling code is generic :-(
If so, I suggest you have only one interface, only one signature. Having several would only bring more complexity, for nothing.
However, you need to ask yourself some broader questions :
how you will ensure that caller and callee do communicate correctly?
That could be a follow-up on this question, or a different question...
If I understand correctly, you want to have one class implement multiple of those interfaces with different input/output parameters? This will not work in Java, because the generics are implemented via erasure.
The problem with the Java generics is that the generics are in fact nothing but compiler magic. At runtime, the classes do not keep any information about the types used for generic stuff (class type parameters, method type parameters, interface type parameters). Therefore, even though you could have overloads of specific methods, you cannot bind those to multiple interface implementations which differ in their generic type parameters only.
In general, I can see why you think that this code has a smell. However, in order to provide you with a better solution, it would be necessary to know a little more about your requirements. Why do you want to use a generic interface in the first place?