OOP-Design: Interface-Methods with implementation-dependent parameters - java

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.

Related

Java - static method in an interface - What do I need to do?

The details:
I have been given a Java program in which I need to fill in some code. The main idea of the program is to get used to interfaces and static methods in them. For the past 6 hours I have been watching countless of videos regarding interfaces and static interfaces and I still feel somewhat clueless to what I am supposed to do.
public interface Util {
static Util create() {
//TODO: this line needs to be replaced with the constructor of a concrete implementation
throw new IllegalStateException("Not implemented yet!");
}
Instruction forSymbols(Symbol first, Symbol last);
Symbol forToken(String token);
Supplier<Integer> buildPipe(InputStream input);
Consumer<Integer> buildPipe(OutputStream output);
String getInstructionCode(Instruction instruction);
Optional<Instruction> getInstruction(String code);
}
This is a snippet of the util interface for a program that will be relevant for having a Ook! translator and is supposed to have a lot of useful tools for other classes.
Now, my goal is to understand what I am supposed to do.
What I tried:
Considering I don't know what I need to do, I don't know what I have to code. I understand that an interface is a sort of template for classes. A static method in an interface is the part that I don't understand yet: I have been told that a static method in an interface is something that doesn't have to be implemented in other classes. In my case, the static method create() is "supposed to be a concrete instance of the util object". So, if I get this right, due to it being static, there would be one shared instance of util.
Afterwards, if a class has the prompt "Instruction instruction = util.forSymbols(Symbol.Point, Symbol.Point);" after Util.create() has been used, I would have defined instruction using util's forSymbols method.
I do not know if I am good at conveying just what I need. I per sé understand what a constructor is, I understand what an interface is, I understand what static does, but I don't understand what I have to insert into the create() method. Heck, I don't even want a direct code solution to my problem, I just want to understand what I am supposed to code.
That being said, if anyone could give me an example of an interface working in a similar fashion as my code above that makes it clear just what exactly the static part in an interface does aswell as help me out with my describes issues, I would be tremendously thankful. Also, I hope that my issue description is alright.
That being said, thank you for trying to help me and thanks to all possible answers.
No, the interface can't keep state, so there isn't anywhere for the shared instance to hang out. This is not a way to implement a singleton. It must be a factory method. I think adding a method like this is confusing and probably a bad idea because it ties together the interface and the implementation in an inflexible way. you're expected to create something that implements Util, so there is going to be a constructor call for that class implementing Util. Otherwise it's not clear.
Another sign this is a bad idea is obviously Util doesn't have any instance methods so isn't usable as an object; either a) there is no state and creating an object is pointless or b) the object returned has to be cast to something else to be useful. Casts are bad, for the most part; they mean we're not benefiting from using the type system.
An interface is like a mask an object wears to keep users of it from seeing anything on it except what is on the interface. But allowing static methods is kind of a bolted-on feature that doesn't have much to do with interfaces (except that classes that implement the interface can call them without having to reference the interface).
Originally in Java you could put static methods only in classes, not in interfaces. There was an idea of a utility class, which was just a dumping ground for people to put static methods, and which didn't have any purpose as a class otherwise. Then there was a change to the language so you can put static methods on interfaces and not have to have a class involved. That's all putting static methods on an interface buys you, you can add only static methods because there is no mutable state allowed.
These methods outlined for you should all be things you can implement with only passed in arguments and local variables, without keeping any state outside of the scope of the method implementation.
I've tried to give you some idea of what is possible and what isn't, once that is clear you can ask your instructor some more focused questions about what you need to do.
I agree with Nathan Hughes. This an ill-conceived design, on the face of it.
But to cut to the chase, here is an example of you could complete that static method:
static Util create() {
return new OookUtil();
}
where
public class OookUtil implements Util {
public OookUtil() { ... }
// methods implementing the Util API for the Oook case.
}
Reviewing this we can immediately see one of the problems with the interface design. We have hard-wired a specific implementation class into the interface. That is most likely a bad idea.
Could we do any better? Well ... maybe ...
The Java SE class libraries have a concept of a Java Service Provider Interface or SPI. An SPI allows different providers to be selected depending on what is available at runtime, and so on. The idea is that SPI code does a runtime classpath search looking for all classes that implement the SPI (e.g. your Util). Then it selects the "best" according to (typically) runtime configurable criteria.
That logic would be implemented in your create method. The method would then instantiate the chosen class reflectively and return the instance. In its simplest form (ignoring the classpath search aspect) it might be something like this:
static Util create() {
String classname = System.getProperty("yourapp.utilclass");
Class<?> clazz Class.forName(className);
return (Util) clazz.newInstance();
}
In this illustration are getting a classname from the system properties. It could be set by running the application with a -D option; e.g. -Dyourapp.utilclass=yourapp.OookUtil.
The above code needs some exception handling ... which I will leave for you to figure out.
Maybe that is what your instructor is getting at. But if so, he or she should have explained more clearly what was expected.

java subclass or field, good semantics

Please help me to decide which approach is reasonable in the following case. Object:
public class FunctionCall {
private String functionName;
private List<Exp> args;
...
}
In one very particular case/check the object need to be identified somehow.
Possible approaches:
FunctionCall class becomes an attribute, but there is a doubt that this would pollute overall semantics, as the attribute should not be visible "globally".
SpecialFunctionCall inherits the FunctionCall and with instanceof can be identified in the very special case. This would be ideal, the only doubt that it would misuse purpose of inheritance?
Any other suggestions are very welcome.
Thanks in advance.
From what you wrote, it seems that the FunctionCall object is just a value object with data, not some object that evaluates itself and returns value. With multiple types of such objects, you need to have a way to disambiguate what type of object you are using.
For that part, I can advise you using enums to disambiguate rather than using instanceof operator or class reflections. You can create nice switch-case commands with it, too.
public class FunctionCall {
// ...
public MyType getType() {
return MyType.BASIC_FUNCTION_CALL;
}
}
Another nice thing about enums is, it is a class that can have its own fields. Have some final fields for the enum constants, put in values that describe some trait of it, and you can use this information in the logic that handles it, to your advantage.
As for the actual answer to your question though, it's not quite possible from knowing so little about your problem. In some cases, inheritance is better, in some other cases, composition is better. In both cases, some kind of interface is nice, and it could declare the getType method.
What you actually need is to use two of the main three principles of Java,polymorphism and 'inheritance' combined together. Polymorphism is one of the OOPs feature that allows us to perform a single action in different ways. This means that the behavior of an object could be changed depending on particular circumstances or cases.
In your case you could create two classes, a FunctionCall and a SpecialFunctionCall. Latter should extends the first one with its one spexial behavior.
Then when your special case comes up you would use the second class which would have a different behavior than the first.
By this way you guarantee that there is a per-case functionality of the parent class FunctionCall.
See below an example of use:
public class SpecialFunctionCall extends FunctionCall{
//your special logic goes here
...
}

What is the advantage of using interfaces [duplicate]

This question already has answers here:
Interfaces in Java - what are they for? [duplicate]
(9 answers)
Closed 9 years ago.
Let's say you have an interface
public interface Change {
void updateUser();
void deleteUser();
void helpUser();
}
I've read that interfaces are Java's way to implement multiple inheritance. You implement an interface, then you have access to its methods. What I don't understand is, the methods don't have any body in the interface, so you need to give them a body in your class. So if you an interface is implemented by more than one class, you need to give the method a body in more than one class. Why is this better than just having individual methods in your classes, and not implementing an interface?
My professor in college once gave a great anecdote to describe polymorphism and encapsulation. It went like this.
Does anyone here know how a soda machine works? (Cue confused glances about why we'd even talk about this.) No? Let me tell you.
You drop in your change, and inside the machine is a little monkey who counts all your change to make sure you put in enough money. When you press the button for your soda, a little light comes on telling the monkey which button you pressed, and if you entered the right amount of change, he grabs your choice and throws it into the little hole for you to grab your soda.
This is the concept of encapsulation. We hide the implementation of the soda machine. Unless it's got one of those fancy, clear windows to let you see the inside, you honestly have no idea how it really works. All you know is that you put in some cash, you press a button, and if you put in enough, you get your drink.
To add to that, you know how to use a soda machine's interface, so therefore as long as the machine's interface follows the usual soda machine interface, you can use it. This is called the interface contract. The machine can be bringing the drinks from Antarctica on a conveyor belt for all you care, as long as you get your drink, it's cold, and you get change back.
Polymorphism is the idea that when you use the soda machine interface, it could be doing different things. This is why encapsulation and polymorphism are closely related. In polymorphism, all you know is that you're using a SodaMachine implementation, which can be changed, and as a result, different things can be done behind the scenes. This leads to the driving concept of polymorphism, which is the ability of one object, the SodaMachine, to actually act as both a MonkeySodaMachine and a ConveyorSodaMachine depending on the machine actually behind the interface.
Probably not word-for-word, but close enough. Essentially it boils down to two concepts: polymorphism and encapsulation. Let me know if you want clarification.
Why is this better than just having individual methods in your classes, and not implementing an interface?
Because if a class C implements an interface I, you can use a C whenever an I is expected. If you do not implement the interface, you could not do this (even if you provided all of the appropriate methods as mandated by the interface):
interface I {
void foo();
}
class C1 implements I {
public void foo() {
System.out.println("C1");
}
}
class C2 { // C2 has a 'foo' method, but does not implement I
public void foo() {
System.out.println("C2");
}
}
...
class Test {
public static void main(String[] args) {
I eye1 = new C1(); // works
I eye2 = new C2(); // error!
}
}
It separates what the caller expects from the implementation. You have a pure set of methods you can call without any knowledge of the implementation. In fact some libraries like JMS and JDBC provide interfaces without any implementations.
This separation means you don't need to know the class of any actual implementation.
An interface allows you to guarantee that certain methods exist and return the required types. When the compiler knows this, it can use that assumption to work with unknown classes as if they had certain known behavior. For example, the comparable interface guarantees that an implementing class will be able to compareTo() some similar object and will return an int.
This means that you can compare anything that implements this interface - so you can sort anything that is Comparable instead of writing one method to sort Strings and another to sort Integers and another to sort LabelledBoxesOfBooks
The interface essentially guarentees that all the methods that inherit it will have its methods, so that you can safely call a method in the interface for anything that inherits it.
It makes it easier to define APIs using interfaces, so that all concrete implementations of the interfaces provide the expected methods in each class.
It also provides a way to implement multiple inheritance, which is not possible (in Java) with straight class inheritance.

Why does all the interface methods need to be implemented in a class implementing it in java

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.

Java: extending Object class

I'm writing (well, completing) an "extension" of Java which will help role programming.
I translate my code to Java code with javacc. My compilers add to every declared class some code. Here's an example to be clearer:
MyClass extends String implements ObjectWithRoles { //implements... is added
/*Added by me */
public setRole(...){...}
public ...
/*Ends of stuff added*/
...//myClass stuff
}
It adds Implements.. and the necessary methods to EVERY SINGLE CLASS you declare. Quite rough, isnt'it?
It will be better if I write my methods in one class and all class extends that.. but.. if class already extends another class (just like the example)?
I don't want to create a sort of wrapper that manage roles because i don't want that the programmer has to know much more than Java, few new reserved words and their use.
My idea was to extends java.lang.Object.. but you can't. (right?)
Other ideas?
I'm new here, but I follow this site so thank you for reading and all the answers you give! (I apologize for english, I'm italian)
If it is only like a "research" project in which you want to explore how such extension would work, you could provide your own implementation of the Object class. Simply copy the existing object implementation, add your setRole method etc, and give -Xbootclasspath:.:/usr/lib/jvm/java-6-sun/jre/lib/rt.jar as parameter to the java command. (I will look for api-classes in . before looking in the real rt.jar.)
You should consider using composition rather than inheritence to solve this problem; that way you can provide the functionality you need without using up your "one-shot" at inheritence.
For example, the JDK provides a class PropertyChangeSupport, which can be used to manage PropertyChangeListeners and the firing of PropertyChangeEvents. In situations where you wish to write a class that fires PropertyChangeEvents you could embed a PropertyChangeSupport instance variable and delegate all method calls to that. This avoids the need for inheritence and means you can supplement an existing class hierarchy with new functionality.
public class MyClass extends MySuperClass {
private final PropertyChangeSupport support;
public MyClass() {
this.support = new PropertyChangeSupport(this);
}
public void addPropertyChangeListener(PropertyChangeListener l) {
support.addPropertyChangeListener(l);
}
protected void firePropertyChangeEvent() {
PropertyChangeEvent evt = new ...
support.firePropertyChangeEvent(evt);
}
}
you can extend Object - every class extends it.
you seem to need something like multiple inheritance - there isn't such a thing in Java
if you want to add functionality, use object composition. I.e.,
YourClass extends Whatever implements ObjectWithRoles {
private RoleHandler roleHandler;
public RoleHandler getRoleHandler() {..} // defined by the interface
}
And then all of the methods are placed in the RoleHandler
If you're talking about adding a role to all your objects I would also consider an annotation-based solution. You'd annotate your classes with something like #Role("User"). In another class you can extract that role value and use it.
I think it would need an annotation with runtime retention and you can check, run-time, whether the annotation is present using reflection and get that annotation using getAnnotation. I feel that this would be a lot cleaner than extending all your classes automatically.
I believe there are some frameworks which use exactly such a solution, so there should be example code somewhere.
If you are doing what you are doing, then inheritance is probably not the correct idiom. You may want to consider the decorator pattern, whereby you construct a class that takes as its parameter some other class with less functionality, and adds some additional functionality to it, delegating to the existing class for functionality that already exists. If the implementation is common to many of your decorators, you may want to consider putting that functionality in class that can be shared and to which you can delegate for all your decorators. Depending on what you need, double-dispatch or reflection may be appropriate in order to make similar but not quite the same decorators for a large variety of classes.
Also, as has been pointed out in the comments, String is declared "final" and, therefore, cannot be extended. So, you should really consider a solution whereby you delegate/decorate objects. For example, you might have some object that wraps a string and provides access to the string via getString() or toString(), but then adds the additional functionality on top of the String class.
If you just want to associate some objects with additional attributes, use a Map (e.g. HashMap).
What you really want to do would be monkey patching, i.e. changing the behaviour of existing classes without modifying their code.
Unfortunately, Java does not support this, nor things like mixins that might be used alternatively. So unless you're willing to switch to a more dynamic language like Groovy, you'll have to live with less elegant solutions like composition.

Categories