how to minimize number of classes to modify when interface is changed - java

There is an interface Accountable which has 2 methods. There are 9 classes which implement the Accountable interface.
public interface Accountable{
boolean isAccountable();
float getWorth();
}
We have got a new requirement as follows:
Two more methods declarations to be added to the interface. But we need to minimize the effect on the existing classes.
I was told that we can use Adaptors to resolve the issue. But I am not sure how to do it.
Could anyone please help me solve the issue?

Using java 8 you can declare default implementation just in interface:
public interface Accountable{
boolean isAccountable();
float getWorth();
default int someMethod() {return 0;}
}
If you use old java the only way is to add an abstract class as a middlware, but since java don't support multiple inheritance it could be painful.

Avoid adding a method to the interface by instead creating a new interface which inherits from that first interface.Now your new class will implement new interface.So there is minimal change.

I guess the goal is to learn about Adapters. In order to use an Adapter you firstly need to create one:
public class AccountableAdapter implements Accountable{
#Override
boolean isAccountable(){ return false; }
#Override
float getWorth(){ return (float)0.0 }
}
Your classes then extend that Adapter. You see, they automatically will implement all methods of the interface inheriting the default-implementations from the Adapter.
If later the interface is added a method, you will have to add an implementation in the Adapter, only. All extending classes won't break.
Of course until here you only have Default-Implementations. Now you will override all methods that need to have a special implementation in your concrete classes.
Personally I find this is a rather bad example to learn about Adapters. A better and "real-life" example would be event handlers. For example MouseInputAdapter. It supplies you with a variety of possible callbacks from mouse-events. By using an Adapter, you can resort to implement only the Listener you really need and don't have to implement the whole interface.

I love this, most people do not know the power of interfaces and its purpose, interfaces is the best thing for the development already invented solution for your problem used design patterns
Your Interface transformed
public interface Accountable <E> {
//method commun all class
public boolean isAccountable();
public float getWorth();
//method commun all class
public int someMethod();
//method commun all class
public E getSameCommun();
}
That a generic implementation
public abstract class Generic<T extends Serializable> implements<T>{
private boolean accountable;
#Override
public boolean isAccountable(){
return
}
#Override
public int someMethod(){
System.out.println("do samethink");
}
#Override
public E getSameCommun(){
System.out.println("do samethink");
}
}
use in your class
public class Class1 extends Generic<Class1> implements Accountable<Class1>{
//that moment you bring 3 method of the Generic
// you need implement specific method of class
#Override
public float getWorth(){
//so something
}
}
//other class
public class Class2 extends Generic<Class2> implements Accountable<Class2>{
//that moment you bring 3 method of the Generic
// you need implement specific method of class
#Override
public float getWorth(){
//so something
}
}
//other class
public class Class3 extends Generic<Class3> implements Accountable<Class3>{
//that moment you bring 3 method of the Generic
// you need implement specific method of class
#Override
public float getWorth(){
//so something
}
//that case you need overred same method commun
#Override
public E getSameCommun(){
System.out.println("do other samethink");
}
}
//other class, you need additional functionality for method
public class Class3 extends Generic<Class3> implements Accountable<Class3>{
//that moment you bring 3 method of the Generic
// you need implement specific method of class
#Override
public float getWorth(){
//so something
}
//that case you need overred same method commun
#Override
public E getSameCommun(){
super.getSameCommun();
System.out.println("additional functionality");
return e;
}
}
that same objective of the "Design Patterns"

Related

Java polymorphism: finding the right design pattern

Disclaimer: I know there are a lot of questions about polymorphism out there, but I couldn't find a suitable answer for my problem. If your Google-fu is better than mine, please forgive the dupe.
I have a model using inheritance, such as in the example below.
public abstract class Base {
// ...
}
public class ConcreteA extends Base {
private String someString;
// ...
}
public class ConcreteB extends Base {
private boolean someBool;
// ...
}
And I also have a List<Base>, which is composed of objects that are either ConcreteAs or ConcreteBs.
I need to generate a graphical view for each object in the list, but the resulting element is not the same for ConcreteAs and ConcreteBs. From the example above, the view for ConcreteA would be a text field, while the view for a ConcreteB would be a check box.
How can I achieve this using OO principles?
The problem that you have is that you somewhere return a List<Base> when the caller must know the concrete type.
Usually this is caused because one tried to make a method more generic. E.g. if someone has this service methods
public List<ConcreteA> doSomethingA(){ ... }
public List<ConcreteB> doSomethingB(){ ... }
he might think it is a better idea to introduce a superclass, Base so that both methods can be substituted by
public List<Base> doSomething(){ ... }
This is a good idea if the caller is only interessted in a Base object. This means that ConcreateA and ConcreteB have some common behavior that the caller only depends on.
But in your case it seems that the caller needs the concrete type information that is not available anymore, because of the more generic method.
So you either must preserve or reconstruct the type information.
Preserve the type by using a custom return type instead of making the method generic
public class Result {
private List<ConcreteA> concreteA;
private List<ConcreteB> concreteA;
}
public Result doSomething();
Recunstruct the type information using instanceof
Reconstruct the type information by introcucing a visitor pattern.
Not a pattern - this is what abstraction is all about. Declare a method you want all subclasses of Base to implement and each must implement it in their own way.
Obviously you would pass parameters and/or get results of the methods.
public abstract class Base {
abstract void graphicalView();
}
public class ConcreteA extends Base {
#Override
void graphicalView() {
}
}
public class ConcreteB extends Base {
#Override
void graphicalView() {
}
}
public void test() throws IOException {
List<Base> bases = new ArrayList<>();
for ( Base b : bases ) {
b.graphicalView();
}
}
I think you're looking for Visitor Design Pattern.
From Wikipedia :
In object-oriented programming and software engineering, the visitor
design pattern is a way of separating an algorithm from an object
structure on which it operates. A practical result of this separation
is the ability to add new operations to extant object structures
without modifying the structures. It is one way to follow the
open/closed principle.
In essence, the visitor allows adding new virtual functions to a
family of classes, without modifying the classes. Instead, a visitor
class is created that implements all of the appropriate
specializations of the virtual function. The visitor takes the
instance reference as input, and implements the goal through double
dispatch.
In such cases, I usually use generics something like this
public abstract class Base <T extends Shape>{
public abstract T drawShape();
}
public class ConcreatA extends Base<Circle> {
#Override
public Circle drawShape() {
return null;
}
}
public class ConcreatB extends Base<Square> {
#Override
public Square drawShape() {
return null;
}
}
So now you can use list of Shapes

Implementing one interface using multiple classes

This question was asked to me in an interview. Tired of googling here I am.
I have an interface with 100 methods. I don't want to implement all those 100 methods in a single class. Is there any way I could implement these 100 methods by using more than one class and not repeating the implementation ?
For Example :
Class A implements first 10 methods(only).
Class B implements next 10 methods(only) and so on.
Note :
1. All the classes which implements the interface must be concrete.
As far as my knowledge on java this isn't possible. He mentioned about adapter when he asked me this question. That made me think that there's a way to do it.
Can anybody clarify me on this ?
Write an adapter with empty implementation of the 100 methods
class Adapter{
//write your empty implementations here as similar to KeyListener in Java
// They have written a keyAdapter and make use of key adapter.
}
ie) class Adapter implements interface1{
public void method1(){}
public void method2(){}
.....
}
You can extend the adapter class in some other class and just override the methods.
class A extedns Adapter{
public void method1(){
}
}
ie)
The concept you describe is called partial classes and Java does not have such a concept.
Here is a similar answer: A way to implement partial classes in java
If you use Java 8 , you can define default implementations in the interface for the 100 methods like :
public interface MyInterface{
void methodA();
int methodB();
default boolean methodC(String name) {
return name.equals("Default");
}
}
Then in your concrete classes you only implements the methods you want. All other not overriden methods will use the default implementation from the interface.
You will have to write 100 default implementations in the interface but it will save you the need to also write 100 implementations in every concrete class implementing that interface.
Again, this is only available since Java 8.
Write all the classes (A, B, C, D, E each implement 20 methods) witch extend one another without implementing the interface I:
I
|
A <- B <- C <- D <- E
And only the last one implements the interface.
Simpler exemple with only 2 methods:
public interface I {
void a();
void b();
}
public class A {
public void a() {
}
}
public class B extends A implements I {
public void b() {
}
}
If the interface methods defined with default implementation ;
public interface I {
default void a(){
//implementation
}
default void b(){
//implementation
}
default void c(){
//implementation
}
//97 more
}
public class A implements I{
#override
public void a() {
}
}
public class B extends A {
#override
public void b() {
}
public class C extends B {
#override
public void c() {
}
}
Even without inheritance classes can be independent from each other and they can provide implementation for different methods
You are correct - any concrete class must implement all methods, so the only way you can not do it is either extend the class that implements given interface and override some of the methods in subclass or implement methods calling implementations from other classes

Set Content inside Interface Java

I'm just learning this interface and now I'm faced with the problem of how to give content inside interface.
I read this article
http://pixelscientists.com/blog/posts/drag-and-drop-inventory-with-libgdx-part-i
and its content made me think about something - when he uses interface inside that
public interface SlotListener {
void hasChanged(Slot slot);
}
and he also creates this
private void notifyListeners() {
for (SlotListener slotListener : slotListeners) {
slotListener.hasChanged(this);//this is Slot class
}
}
How do I give that hasChanged() method content?
I really don't grasp the idea of that interface...
I mean, no content inside hasChanged() (of course because it's am interface) but why does it point back into Slot class? and what content does that method take and how?
Maybe you need to see the link above about this problem.
I already take Googled to learn about interfaces but I only found basic tutorials, not cases like this. I also already asked about this problem in some communities with no result.
An interface is not a real class. It just has some method signatures in it. Real classes implement an interface by implementing all the methods in an interface.
SlotListener is an interface. When you want to implement this interface you should create a class that has hasChanged(Slot slot) method.
public class realClass implements SlotListener {
public void hasChanged(Slot slot){
//Some code here...
}
}
Read for more information about Interfaces.
Interfaces Tutorial by Oracle
This is the typical case of the Observer Design Pattern. In this design pattern you have a collection of listeners (your SlotListener) and an object (your Slot) that will notify to his listeners when something has changed.
Your Slot class should also contain a method addListener(SlotListener sl) that will add a listener to your slotListeners list.
After that you just have to create a class that implements the SlotListener
public class MyListener implements SlotListener{
void hasChanged(Slot slot){
System.out.println("Slot " + slot.toString() + " has changed");
}
}
Have a look here: what is an interface.
When you an an interface, somewhere else you have a class that is implementing the interface. The implementing class is then providing concrete methods for the interface methods.
Have a look at the class : SlotActor.java it #Override and implements the interface method:
public class SlotActor extends ImageButton implements SlotListener {
// some other code
#Override
public void hasChanged(Slot slot) {
setStyle(createStyle(skin, slot));
}
}

Usings abstract class to add a method to an interface

I want to add a method to an interface, but i do not want to rewrite all the implementations (i only need to use it in one or two implementation). I read that i can achive this with the use abstract classes, but i cant quite figure out how its done?
Inteface:
public interface Animal {
public void doSound();
}
Classes:
public class Cat implements Animal {
#Override
public void doSound() {
System.out.print("meow");
}
}
public class Dog implements Animal{
#Override
public void doSound() {
System.out.print("bark");
}
}
What i want is to be able to call
animal.doSomethingElse()
but i dont want to add this method to every implementation. Can this be done?
EDIT:
Should have mentioned this before, i am not using java 8.
You could change Animal into an abstract class. This will enable you to selectively implement methods:
public abstract class Animal {
public abstract void doSound();
public void doSomethingElse() {
}
}
It is possible in Java 8 with help of default method in interface.
public interface Animal {
void doSound();
default void doSomethingElse(){
// do something
}
}
In case of default methods, your implemented classes from Animal doesn't have to override them.
prior to java 8, you have to make your Animal class abstract and add method implementation there.
It is not possible with Java including versions to 7.
You can define interface Animal as abstract class and implement new method within it. Sample code as follows:
public abstract class Animal {
public abstract void doSound();
public void doSomethingElse() {}
}
However if you are using Java 8 you have mechanism which is called default methods. Example below
public interface Sample {
public abstract void doSound();
public default void doSomethingElse() {};
}
default methods do not have to be implemented by classes. Mechanism is very useful when it comes to interfaces with large number of classes implementing certain interface. You can extend it without changing all classes
Unfortunately, no: you cannot add a method to an interface without having to recompile all implementations of the interface.
You can add a method to the abstract class, and change all references to the interface with references to your abstract class. That, however, defeats the purpose of having the interface in the first place.
Finally, in Java 8 you can address this problem by providing a default implementation of a method in an interface. If Java 8 is an option, I would definitely recommend this route.
If you would like to avoid problems like this in the future, you could follow the interface + adapter pattern that Java designers have been following in the AWT framewrok (among other places). They would provide a pair of an interface and its default, do-nothing implementation. Everyone would be encouraged to program to the interface, and base their implementations of the interface on its default implementation counterpart (the adapter). This way Swing designers were free to add more methods to their interface without breaking existing implementations.
For reference, see MouseListener interface and MouseAdapter class.
You can extend Animal as a separate interface or an abstract class.
public interface Pet extends Animal {
public void fetch();
}
or
public abstract class Pet implements Animal {
public abstract void fetch();
}

Java Interface\abstract class constriction

Today, our team has the problem.
There is a class AClass that implements the interface AInterface. To date, we need to introduce a new entity(BClass) that would use only part of the interface A.
The first thing about which we think - split interface AInterface into 2 components (composition)
The problem is that the logic AClass->AInterface - is a model prom pattern MVC. And we extremely do not want to cut it into several interfaces.
We know that Java provides a mechanism for inheritance to extend a class or interface.
But is there any way to constrict the implementation? Or maybe exist another way?
Note : we doesn't want use UnsupportedMethodException. Our goal - clean API.
Update :
Next solution - not for us.
GOAL :
Put your restricted subset into one interface, and have the larger interface extend it. Then have A implement the child (larger) interface, and B implement the parent (smaller) one. Then both A and B implement the smaller interface, while only A implements the larger. Use the smaller interface for coding to whenever you can.
public interface AInterface {
void add();
void remove();
}
public interface ASubInterface extends AInterface {
void invalidate();
void move();
}
public class AClass implements ASubInterface { /* 4 methods */ }
public class BClass implements AInterface { /* 2 methods */ }
The very fact that you have a usecase which only requires half of the methods exposed in the original interface tells you that you can further break that interface down. If you think about the design - how do your objects behave in your usecase scenarios, will tell you how it should be designed.
Just by looking at the names of the methods you have given, I'd expect them to be 2 different interfaces where AClass implements both the interfaces while BClass only implements the second interface.
You cannot "disable" polymorphism in certain cases, it's a major feature of the Java language.
If BClass shouldn't have those methods, then it shouldn't implent the interface.
AClass does more than BClass, so it should be another type. Why would you want them to be interchangeable?
On another note, many libraries use UnsupportedMethodException (like even the Java SDK with List collections). It just needs to be documented properly. So if you need ro use that to achieve your goal, go for it.
Your needs seem a little strict but perhaps a abstract class could help.
public interface AInterface {
public void add();
public void remove();
public void invalidate();
public void move();
}
public abstract class BBase implements AInterface {
#Override
public abstract void add();
#Override
public abstract void remove();
#Override
public void invalidate() {};
#Override
public void move() {};
}
public class BClass extends BBase {
#Override
public void add() {
}
#Override
public void remove() {
}
}
Here I create a BBase which stubs out the two methods you want removed but leaves the other two abstract. BClass demonstrates how it would be used.
You can do this if you compile AClass and BClass separately. I.e. compile AClass with the full version of the interface, then modify the interface (remove the methods) and compile BClass with this modified version of the interface.
P.S. By no means this is a painless approach.

Categories

Resources