making it easy to change implementation of an interface later on - java

So in java the way to initialise an interface, such as a collection or list, is to create an instance of a class that implements it, eg:
Collection<Object> moo = new ArrayList();
If I wanted to specify an implementation at a later time in my code, I was thinking of doing this by creating another class like:
class ListList extends ArrayList{
}
and then initialise the variable with
Collection<Object> moo = new ListList();
And then all that's required if I want to change the implementation later on is to change what ListList extends.
So, here's the question.. is there a better way of doing this (I still feel as though I'm inexperienced with this type of thing).

is there a better way of doing this
Yes: use a factory method:
public static Collection<Object> createCollection() {
return new ArrayList<Object>(); // change this later, if need be
}
Then, invoke the factory rather than instantiating:
Collection<Object> moo = createCollection();
Your suggestion of using a "dummy" subclass might appear attractive, but such abuses of inheritance invariably lead to pain and suffering later on. You really don't want to do that.

You could also do it that way
Collection<Object> coll=new ArrayList(){
//bla
};

The basic idea is a good one. Make your variable/field/... an instance of the interface and not of the concrete class you are using. This will force all your code to work against the interface (on the condition that you not start casting somewhere down your code path), and allows to replace the implementation later on with a different class if you feel the need for it.
One can start discussion about how you create that concrete class, like for example using a factory method as #skaffman suggested in his response. However, this might depend on the situation. If it is just for a one-time use like initializing a field you can just create the instance without bothering about factory methods.

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.

Am I using instanceof "wrong"?

So in a simple game engine of mine I use an interface "UpdatedGameElement" to signal that an object having that interface has to be updated every frame through an implementation of an update() method.
Now in my "main"(not THE main) class I iterate through a list of GameElement 's and check if these are an instanceof UpdatedGameElement. If this is the case I cast them, and then call .update().
Now the thing is, I just read that using instanceof is usually a sign of bad coding; and in cases where classes are used as markers when they could be easily replaced with a variable, I agree. But I'm not so sure about my case.
I guess I could let the GameElement class implement UpdatedGameElement, and define a standard empty update() method that needs to be overridden to actually do something, but I'm not sure if and why that would be better than what I have now.
What would you say?
Edit: some code from my main class:
public void process()
{
if (active)
{
for (GameElement GE: elements)
{
if (!GE.isToBeRemoved())
{
//Relevant part
if (GE instanceof UpdatedGameElement)
{
((UpdatedGameElement) GE).update();
}
}
else
{
prepareRemoval(GE);
}
}
processRemovals();
}
}
Following the invitation if the OP:
If use of the interface has no other reason than to add a marker plus the update method to GEs, and if the type UGE isn't used except after this single instanceof, then it is a weak reason for having these extra types. ESpecially when the capability of being updated can be extended to all other GEs, where it is just a NOOP.
An abstract method in the base class forces the programmer to decide whether update needs to be coded for a particular subclass. This approach is rather "safe" from a "defensive design" point of view. But, of course, you write more code.
In contrast to the previous technique: If you forget the interface there's no alarm.
Also, if you code a NOOP update method in the base class and rely on programmers' alacrity to override where necessary: convenient, but risky when you forget to do it.
Summarizing: There are a few subtle pro's and con's - not just the instanceof "smell".
Based on your comments you mentioned that GameElement implements UpdatedGameElement, for now GameElement is the only class which is implementing UpdatedGameElement but it could be more in future. Also I hope you are aware that an interface cannot be instantiated thus you cannot create an instance of UpdatedGameElement thus in real the instances are created of the implementing classes of an interface. Thus during runtime when you create an instance of GameElement and assign it to UpdatedGameElement variable, that doesn't mean the instance is of type UpdatedGameElement now, its actually of type GameElement, now suppose that you have one more class implementing XYZElement implements UpdatedGameElement and create instance as below:
UpdatedGameElement ge = new GameElement();
UpdatedGameElement xyze = new XYZElement();
Do you think it good to use instance of check as below, as in either case it will be true and you never know which kind of instance ge and xyze are of.
if(ge instance of UpdatedGameElement)
instead one should always check for if(ge instance of GameElement)
Similarly for if(xyze instance of UpdatedGameElement)
instead one should always check for if(ge instance of XYZElement)
Hope this helps.
I guess I could let the GameElement class implement
UpdatedGameElement, and define a standard empty update() method that
needs to be overridden to actually do something
Yes, you should definitely do it!
Reason: suppose in the future you'll need to implement another "updateable" class that extends UpdatedGameElement - consider the code changes you'll have to do in every place you've used instanceof...

why attribute from interface is declared in classes

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.

Find info about class in java, software design?

I have a bunch of classes extending an abstract Base class.
Each subclass takes an array as in the constructor, (different length depending on class).
These classes could be written by other people.
What is the best way to figure out the length of the array the class needs?
I could:
(A) Require that each derived class have a static method, returning the length.
However, the base class cannot enforce this, since abstract static methods does not work in java.
(B) Each derived class have a constructor with no arguments, and I construct
such classes just to be able to call the countParameters() method, that
I can enforce from the Base class. This feels "cludgy", since I am not interested in creating such object, but only need some info about it.
The reason is that I am creating a GUI, that gives the user the ability to create
instances of Derived classes, but each Derived class takes different number of parameters.
That is, I need to know how to draw the GUI before I can create the classes.
EDIT:
I could just require that each Derived class have a private
constructor, with no arguments, and using reflection I can call the countParameters() method.
EDIT2: Actually, what I am interested in, is what the names of the parameters are.
That is, if the class Derived have the constructor
public Derived(double name1,double name2,...)
I need a way to generate the String[] array
{name1,name2,...}
I guess this would be impossible to do without creating an instance of the class,
but for the user to be able to create such class, he/she needs the parameter names!
Moment 22.
It sounds like you need the Factory Pattern.
In general, it's a bad idea for a base class to know the set of it's descendant's. So you define another class whose job it is to know that.
If you have something like a Shape, with ThisShape and ThatShape as derived classes, then a ShapeCreator will handle the job of creating the specific set of shapes your program supports, giving each one the arguments it needs.
It's not quite clear what you're trying to achieve, but I wonder: Do the subclasses really have to take a single parameter with an array, as opposed to a list of parameters?
Constructor<?> ctor = Test.class.getConstructors()[0];
int parameterCount = ctor.getParameterTypes().length;
ctor.newInstance(new Object[parameterCount]);
how about this code:
public absract Base {
public abstract int size();
public Base(Object[] objs) {
if (objs.length != size()) {
throw new IllegalArgumentException();
}
//rest of your code.
}
each child class needs to implement size method.
hope its help.
I'd go with method A. You can't get the compiler to enforce the existence of such a method, but you can certainly enforce it in your program - no method, no work!
Seriously, this whole scheme is a bit brittle and I can't think of a way to make it significantly better. An incorrect implementation of those subclasses will bomb out, that's life.
A possible remedy would be for you to provide a set of interfaces for those subclasses, such as
SubClassTaking2Args
SubClassTaking3Args
...
and requiring your sub's to implement one of those as a marker interface. But that's just more bureaucracy with little more effect.

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