I am currently working on a big project that includes three different types of CRUD. My ICrud interface includes the <t> to put in the desired datatype when I implement it.
My problem is that when I implement it in my third class, I wish to make one of the methods (readAll) use another datatype than the 4 other methods (CRUD). Is this possible in any way?
Right now I have the readAll method return the matching data type but returning null because it isn't used, and instead created another method readall2() that does return the correct datatype but isn't part of my interface.
The ICrud interface:
public interface ICrud<T> {
List<T> readAll();
List<T> read(int cvr);
void create(T t);
void delete(int cvr);
void update(T t, int id);
}
how i implement it:
#Service
public class AdminRepository implements Ilogin<Admin>, ICrud<Driver>,
IAdmin<Company>
how i wish to use the readAll:
public List<Company> readAll()
(not Driver, but driver for all other methods in the interface)
And I wanna add; at first, i had the readAll in iAdmin because it takes Company, but I have this readall method in 6 other classes that implements ICrud aswell.
Thanks for any help. :)
You have a design problem, i recommend you read about SOLID principles in the following link:
https://scotch.io/bar-talk/s-o-l-i-d-the-first-five-principles-of-object-oriented-design
In a correct design, you should not at all implement an interface if you will not implement one of its methods (the readAll i your case). this means you are mixing concerns, and your interface must be split into smaller interfaces. perhaps splitting the readall into a separate interface will solve your problem. for example, instead of ICrud, create an interface for write operations alone, and one for read operations, and one for readAll.
there is many ways to solve your problem preserving the interface ICrud as is, such as using object as a retrun type, or generics or dynamics. but what solves your problem from its roots is following a good design as i mentioned above.
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.
I know that it is the purpose of the interface and the class can be declared abstract to escape from it.
But is there any use for implementing all the methods that we declare in an interface? will that not increase the weight and complexity of the code if we keep on defining all the methods even it is not relevant for that class? why it is designed so?
The idea of an interface in Java is very much like a contract (and perhaps seen in retrospect this should have been the name of the concept)
The idea is that the class implementing the interface solemnly promises to provide all the things listed in the contract so that any use of a class implementing the interface is guaranteed to have that functionality available.
In my experience this facility is one of the things that makes it possible to build cathedrals in Java.
What you are critizing is exactly the goal interface achieve.
If you don't want to implement an interface, don't declare your class implementing it.
will that not increase the weight and complexity of the code if we
keep on defining all the methods even it is not relevant for that
class?
When you program against an interface, you want the concrete object behind it to implement all its methods. If your concrete object doesn't need or cannot implement all interface method you probably have a design issue to fix.
When any piece of code receives an instance of an interface without knowing what class is behind it, that piece of code should be assured of the ability to call any method in an interface. This is what makes an interface a contract between the callers and the providers of the functionality. The only way to achieve that is to require all non-abstract classes implementing the interface to provide implementations for all its functions.
There are two general ways to deal with the need to not implement some of the functionality:
Adding a tester method and an implementation that throws UnsupportedOperationException, and
Splitting your interface as needed into parts so that all method of a part could be implemented.
Here is an example of the first approach:
public interface WithOptionalMehtods {
void Optional1();
void Optional2();
boolean implementsOptional1();
boolean implementsOptional2();
}
public class Impl implements WithOptionalMehtods {
public void Optional1() {
System.out.println("Optional1");
}
public void Optional2() {
throw new UnsupportedOperationException();
}
public boolean implementsOptional1() {
return true;
}
public boolean implementsOptional2() {
return false;
}
}
Here is an example of the second approach:
public interface Part1 {
void Optional1();
}
public interface Part2 {
void Optional2();
}
public Impl implements Part1 {
public void Optional1() {
System.out.println("Optional1");
}
}
will that not increase the weight and complexity of the code if we
keep on defining all the methods even it is not relevant for that
class?
Yes you are right it will. That is why it is best practice in your coding to follow the Interface Segregation Principle which recommends not to force clients to implement interfaces that they don't use. So you should never have one "fat" interface with many methods but many small interfaces grouping methods, each group serving a specific behavior or sub-module.
This way clients of an interface implement only the needed methods without ever being forced into implementing methods they don't need.
It may depend on Liskov Substitution Principle
So, having A implements B means that you can use A when B is needed and, to make it work without problems, A must have at least the same methods of B.
Please keep in mind that mine is not a "proper" answer, as it's not based on official sources!
When implementing an Interface,we may not need to define all the method declared in the Interface.We can define the some methods,that we don't need,With nothing inside the body.
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'm working on a tool where users can use their own annotations to describe data processing workflow (like validation, transformation etc).
Besides using ready-to-use annotations, users can user their own: in order to do this they need to declare annotation class itself, and then implement annotation processor (<--it's the main point of this question actualy).
The configured method for data processing may look like this one:
void foo(#Provide("dataId") #Validate(Validator.class) String str) {
doSmth(str);
}
There're naturally three groups of annotations:
those which produce initial values;
those which transforms values (converters);
those which just read values and perform some work (validators, different consumers).
So I need to make a choise: either create one interface for handling all these types of annotations, which can look like this one:
interface GenericAnnotationProcessor {
Object processAnnotation(Annotation annotation, Object processedValue);
}
Or I can add 3 intefaces to the API:
interface ProducerAnnotationProcessor {
Object produceInitValue(Annotation annotation);
}
interface TransformerAnnotationProcessor {
Object transformValue(Annotation annotation, Object currentValue);
}
interface ConsumerAnnotationProcessor {
void consumeValue(Annotation annotation, Object currentValue);
}
The first option is not very clear in use, but the third option pollutes the API with 3 almost similar interfaces.
What would you choose (first of all as an API user) and why?
Thanks!
I would create the first, more general interface, then define the three different implementation classes. Without knowing more about how you will be using this, my first instinct would be to define the Interface and/or a base class (depending upon how much common implementation code was shared between the different processors), and then add specialized processor implementation in derived types, all of whihc share the common interface.
In using the API, I would expect to declare a variable which implements GenericAnnotationProcessor, and then assign the appropriate implementation type depending upon my needs.
It is early here in Portland, OR, but at this moment, at 50% of my required caffeine level, this seems to me like it would provide maximum flexibility while maximizing cade re-use.
Of course, your actual reuirements might dictate otherwise . . .
Hope that was helpful!
Just diving deep into your problem.
As they are executing similar task, with some variance, Strategy pattern #Example should assist you.
Your problem should look like something below.
interface GenericAnnotationProcessor {
Object processAnnotation(Annotation annotation, Object processedValue);
}
interface ProducerAnnotationProcessor implements GenericAnnotationProcessor {
}
interface TransformerAnnotationProcessor implements GenericAnnotationProcessor {
}
interface ConsumerAnnotationProcessor implements GenericAnnotationProcessor {
}
Now you can follow example from Wiki
class Context {
// map of annotation processors
// register(add/remove) annotation processors to the map
public int executeAnnotationProcessor(Annotation annotation, Object processedValue) {
return locateAnnotationProcessor(annotation).processAnnotation(annotation, processedValue);
}
private GenericAnnotationProcessor locateAnnotationProcessor(Annotation annotation) {
// return expected annotation processor
}
}
I believe you can understand.
You can use Interfaces Extending Interfaces More on there
Similar to classes, you can build up inheritance hierarchies of interfaces by using the extends keyword, as in:
interface Washable {
void wash();
}
interface Soakable extends Washable {
void soak();
}
In this example, interface Soakable extends interface Washable. Consequently, Soakable inherits all the members of Washable. A class that implements Soakable must provide bodies for all the methods declared in or inherited by Soakable, wash() and soak(), or be declared abstract. Note that only interfaces can "extend" other interfaces. Classes can't extend interfaces, they can only implement interfaces.
Hope it helps.
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?