Implementing interface with many methods = huge class. Patterns come to rescue? - java

I have an interface with a lot of methods. (which i cannot split into different interfaces)
When i create a class that implements the interface i get a lot of methods in 1 class file.
Things get worst when the body of all these methods get larger -> the class file becomes huge and quite difficult to navigate.
Even with ide's like eclipse because the Outline window containing all classes get a vertical scrollbar because not all methods can fit in the outline.
Is there a pattern that prevents this from happening?

No there is no way to split the implementation in many classes.
But you can delegate from the implementing class to any other classes.
This will reduce the code in the implementation but the number of methods stay the same.

I am posting this reply after an answer is accepted, hoping that future comers might find it useful.
As simas_ch said:
No there is no way to split the implementation in many classes. But
you can delegate from the implementing class to any other classes.
This will reduce the code in the implementation but the number of
methods stay the same.
Once I worked on a rather huge application in which I had to define a Lifecycle interface, which contained many states and many functions that could create a hassle, so I came around with something like this:
You can create a class and make it abstract and implement most of the common functions.
public interface TheBigFunctional {
public void functionalA();
public void functionalB();
public void functionalC();
//....
public void functionalZ();
}
public abstract class FunctionalBase implements TheBigFunctional {
public void functionalA() {
aInternal();
}
protected abstract void aInternal();
// Rest of methods implementations.
// You may choose to skip those if you want child classes to implement them.
}
public class FunctionalTypeFoo extends FunctionalBase {
// Implementations.
}
public class FunctionalTypeBar extends FunctionalBase {
// Implementations.
}
There are many (good) ways to come around the sitation, but I am sharing what I did.

I do not quite understand why you cannot split the interface into multiple ones...
I surely would try to use inheritance, like:
First interface:
public interface FatherInterface {
String methodOne(String var);
String methodTwo(String var);
String methodThree(String var);
}
Second interface:
public interface SonInterface extends FatherInterface {
String methodFour(String var);
String methodFive(String var);
}
Third interface:
public interface SecondSonInterface extends SonInterface {
String methodSix(String var);
String methodSeven(String var);
}
And so on... Each interface inheriting from the preceding one.
As for class files becoming large, go with inheritance too.
Father class:
public class Father implements FatherInterface
Son class:
public class Son extends Father implements SonInterface
And so on...
Edit
If you cannot split the interface (as when given by third party), I would do the implementations of the methods by parts. That is, only some of them implemented in each class. Using abstract classes if needed (or leaving blank methods). Each class inheriting from the above and implementing some of the remaining methods.

Perhaps you could employ the strategy pattern on the big interface by implementing some of those methods from different classes. Then, when you wish to use any of those methods, simply call it from the class that implements your 'large' interface.
More on strategy pattern here: https://www.tutorialspoint.com/design_pattern/strategy_pattern.htm

In this case i would consider whether all methods in your class are well designed. Probably they do not have clear purpose and should be splitted per few.
You have to define clear purpose of some particular interface.
Besides, if you are using Java 8, consider ability to provide some default implementation for some methods.

Is there a pattern that prevents this from happening?
In Java:
Subtyping: If you can group sets of methods into different interfaces such that a clear hierarchical relation makes sense. This is what the accepted answer is assuming.
Interface Segregation: If you can group sets of methods into different sibling "domains" or "categories". Take a look at this example from jcabi-github. See how Github is this API's entrypoint, while exposing different sets of functionalities via successive "grouping" interfaces.

Related

Why the Class Adapter Design Pattern Can't Use an Interface Instead of Multiple Inheritance?

I've recently learned the Class Adapter pattern. In order to implement it, the language used must support multiple inheritance since the adapter class must inherit two classes, the Target, and the Adaptee. So in a language like Java, it could not be done.
But why couldn't it use an interface Target instead of a class Target? More inline with the Object Adapter pattern as well. Just switching from object composition (Adapter having the Adaptee) to single inheritance (Adapter inheriting the Adaptee).
By using an interface, I don't see the design difference, and as a result, the pattern can be used in Java.
Link to object adapter and class adapter class diagram
There's generally no reason you can't create a Class Adapter between two interfaces in Java. But first you have to be lucky enough to be in a scenario where the two APIs that need adapting are both interfaces to begin with.
An Adapter is mostly useful to bridge the gap between two existing APIs that don't belong to you. If you control one or both APIs, you can simply change one to match the other. When you need two separate APIs to be compatible, but the APIs don't belong to you, then you have to adapt what you're given, which may not be interfaces.
But why couldn't it use an interface Target instead of a class Target?
you can use interface. But then you will have duplication of code, but multiple inheritance removes duplication of code.
Let me show an example.
Our abstractions:
public interface IDuck
{
void Quack();
}
public interface ITurkey
{
void Gobble();
}
And concrete implementations:
public class Duck : IDuck
{
public void Quack()
{
Console.WriteLine("Quack");
}
}
public class Turkey : ITurkey
{
public void Gobble()
{
Console.WriteLine("Gobble");
}
}
And class adapter would look like this:
public class ClassAdapter : IDuck, ITurkey
{
public void Gobble()
{
// duplication of code
Console.WriteLine("Gobble");
}
public void Quack()
{
Gobble();
}
}
The above ClassAdapter has duplications of code. Sure we can extract this code and provide it through composition or inject Duck and Turkey. However, it brings additional dependencies and some complexity. So it is better to use object adapter pattern. Your code will be simpler. Simple code is almost always the best choice.

How can I restrict arguments of methods in abstract classes for subclasses that use them?

I've been trying to design a set of classes to model a classic RPG. I've found myself confused on how to solve this one issue, however: how do I force the use of character-type (e.g. Tank, Healer, DPS) specific spells/equipment, etc. in an abstract class. The example below better articulates what I mean.
I've got an abstract PlayableCharacter class which all character-types inherit from:
public abstract class PlayableCharacter {
private Set<Spell> mSpells;
...
public void addSpell(Spell spell) {
mSpells.add(spell);
}
}
For example:
public class Healer extends PlayableCharacter { ... }
public class Tank extends PlayableCharacter { ... }
Note the Set of Spell in the abstract class. I would like it if each subclass of PlayableCharacter could use its addSpell method but with the restriction that the type of Spell correspond to the PlayableCharacter subtype.
For example I have these Spell classes:
public abstract class Spell { ... }
public class HealerSpell extends Spell { ... }
public class TankSpell extends Spell { ... }
I only want Healers to use HealerSpells and Tanks to use TankSpells, etc. For example:
PlayableCharacter tank = new Tank();
tank.addSpell(new TankSpell()); // This is fine
tank.addSpell(new HealerSpell()); // I want to prevent this!
I thought of giving each subclass of PlayableCharacter it's own Set of subclass-specific Spells, but that creates a lot of code duplication.
I also tried making PlayableCharacter.addSpell marked as protected, then each subclass would have to implement an interface like this:
public interface Spellable<T extends Spell> { void addClassSpell(T spell); }
and each subclass that implements it would call super.addSpell(spell); but that lead to more code duplication and nothing was forcing those implementations to do the super call.
Is my strategy fundamentally flawed in some way? Any advice? I feel like this issue will keep getting worse as I add more character-type-specific equipment, traits, and so on.
I wouldn't do it that way (via type inheritance). It would be better to add characteristics to a Spell itself because it's a spell, which can be cast by a certain character only. Also, a specific spell can be cast to a certain character type only. These rules belong to a spell, not to a character.
Spell rules can be checked in a runtime by a separate class or by a Spell class itself inside a cast() method or another one.
so far what you have is good
the rest of the stuff, think more strategy pattern than super call
so abstract class can have algorithm that does step1, step2, step3 with possible parent implementation
child classes can override it, but only override parts that is different
when you call algorithm, it performs all steps
Steps themselves could be different class that has logic, if everything becomes too big
maybe have each subclass of playable character store the class (or classes) of subspells that are allowed. then do an if(spell instance of allowedSpell) ...

How to properly design interface

I have two classes. Let's call them PostClass and CommentClass. Both classes implement the Reportable interface:
public interface Reportable {
void report();
boolean isReported();
. . .
Now I need to add two additional methods to each one of the classes. These methods logically fit into the same interface but needs to have different names. For example:
PostClass will have methods -> remove(), restore()
CommentClass will have methods -> hide(), show()
Question: What would be the preferred way to design this change? The options are as I see it:
Create an additional interface which will extend the Reportable interface. Problem: Too many interfaces
Add all four new methods into the Reportable interface and then just leave the irrelevant two methods unimplemented in each class. Problem: Untidy/ugly
Don't worry about having a few more interfaces, as long as their use and purpose is clear. These 2 options are valid:
PostClass implements RemovableReportable, which extends Reportable; And
CommentClass implements HideableReportable, which extends Reportable.
PostClass implements both Reportable and Removable; And
CommentClass implements both Reportable and Hideable.
But adding all four new methods into the Reportable interface and leaving two methods unimplemented in each class is very wrong, since it does not lead to code which is clean and easy to understand and use. The developer would have to learn which method to use in each case, thus making your code more difficult to use and modify. And what happens if some developer calls the wrong method? If the wrong method does nothing, bugs may go unnoticed. If it throws an exception, this will only catch bugs at runtime. And if it calls the other method then you have two ways of doing the same thing, which is also bad and confusing.
Unused methods in an interface are a code smell, and may indicate a design flaw.
If they do the same thing, then make up names that encompass the function; although that doesn't sound like what you want given the existing names.
Option 3: Create two new interfaces, Removable and Hideable and have each class implement the appropriate interface(s).
On second thought, I would probably recommend using hide() and show() since that seems to capture what's happening best.
While the question would likely be classified as opinion based, my approach would be to still add two methods (show(),hide()) to the interface and have the classes implement it.
Below are few other options :
If you are using JDK8 you can try adding the above two methods as default-methods in the interface so that it does not immediately break the existing implementation.
Also, apparently its possible to invoke the abstract method from a default method in the interface so it would technically be possible to have two generically named abstract methods and two (or four more) that are specifically named default methods but that would be overkill and would only add to the confusion.
You could consider having a total of six new methods. show and hide being abstract and also showPost/hidePost and showComment and hideComment being default classes which in turn invoke the abstract show and hide respectively. That way even if some implementation class calls the wrong alias by mistake it would still invoke the correct implementation (in theory).
Whatever I am going to describe in this answer is purely my opinion and subjective.
The following points must be kept in mind when designing this:
Any method added to Reportable (or in general any supertype) should be applicable to all subtypes regardless.
A method should describe a behaviour of the class, something that the class is capable of 'doing'.
Point 2 explanation
Think of the method postClass.remove(), which can be read as 'A PostClass knows how to remove...'. But remove what? Itself? From where?
For me, 'removing' and 'restoring/adding' seems like something that can be done on a Collection of PostClass or CommentClass by and not something that these classes do themselves. If I guess correctly, this is indeed how you must be using PostClass and CommentClass in your application (i.e. as a Collection of some sort). Now, a PostClass or CommentClass can get a callback onRemove(), onRestore(), onHide() or onShow() to do what's necessary for each of this actions when being removed/restored/hidden/shown.
The advantage of callbacks is that a class can choose to call super if they don't intend to do something special during the action.
Design 1 - Reportable has the behaviour of being hidden,shown,restored and removed
So, for all 'reports' of your application, you can add these callbacks to the Reportable interface itself.
public interface Reportable {
void report();
boolean isReported();
void onRestore();
void onRemove();
void onHide();
void onShow();
}
Usage could be something like this
public class User {
private List<Reportable> reports;
//... more User related code
public void deleteReport(Reportable report) {
//give report a chance to cleanup
report.onDelete();
//delete from user's list of reports
this.reports.remove(report);
//more code
}
Design 2 - Having separate interfaces
public interface Viewable {
void onHide();
void onShow();
}
public interface Disposable {
void onRemove();
void onRestore();
}
public class PostClass implements Reportable, Disposable {
}
public class CommentClass implements Reportable, Viewable {
}
Usage for this is pretty self explanatory I guess.
I prefer Design 2 as it seems more clean and adheres to 'SOLID' design principles.
Hope this helps.

java - unique difference between abstract class and concrete class

I know few differences between abstract class and concrete class. I know that you can't create an instance with abstract class unlike concrete class, abstract class can have 'abstract' methods.
But i have an example like the following. A lot of times, we see the following examples at work. I will just skip some common methods that can be defined in the Parent class.
public abstract class Parent {
public void init() {
doInit();
}
public abstract void doInit();
}
public class Child extends Parent {
public void doInit() {
// implementation
}
}
I think that we can do the same thing with a concrete class like the following.
public class Parent {
public void init() {
doInit();
}
public void doInit() {
// Empty
}
}
I am curious to see if there is any unique situation that we have to use abstract class. Is there any significant difference during runtime with the above example?
Thank you.
The reason to use abstract class in this situation is to force everyone inheriting your base class to override the abstract doInit method. Without the class and the method being abstract, they may forget to do so, and the compiler would not catch them.
In addition to this pragmatic purpose, abstract classes provide a powerful way to communicate your design idea to the readers of your code. An abstract class tells the reader that the methods inside provide some common implementation for a group of related classes, rather than implementing a single concept that you are modeling. Very often communicating your intent to your readers is as important as it is to write correct code, because otherwise they might break something while maintaining your code.
It is customary in Java to call abstract classes Abstract...; in your example that would be AbstractParent.
Of course you can do it that way, but it all depends on the right business logic.There might arise a situation where you'd want to enforce a policy on people extending your code.
For example, I write an Employee class and you extend my class for writing a ProjectManager class. But suppose the business does not allow direct instantiation of Employee (like I said, just an example). So I declare my Employee class as abstract, thereby enforcing upon all extenders (read:you) of my class the rule that they can't instantiate Employee directly. (It will happen indirectly through the inheritance chain, of course, i.e. parent objects are created before child objects.)
Used properly, a person at place A controls how another person at place B will code.
A concrete class is one which has implementation (code inside) for all the methods. It does not matter whether it is derived from some other class.
public abstract class IAmAbstract{
public void writeMe(){
System.out.println("I am done with writing");
}
}
public class IAmConcrete extends IAmAbstract{
public void writeMe(){
System.out.println("I am still writing");
}
}
Abstract classes have a variety of useful properties in use with software design.
Other than the obvious differences, such as being unable to be instantiated and being able to hold abstract methods. They are useful for defining common, yet overridable, functions, holding static methods that deal with it's children in a logical manner.
My favorite is the abstract factory pattern though.
By making a factory that is the parent of all the classes it may create, it can force functionality required for creation, this actually causes an odd artefact where technically tighter-coupled code is actually easier to maintain.

Why java interfaces can't contain static methods implementations?

I'm just curious, wouldn't it be more convinient to allow interfaces to contain implementations of static methods? Such methods could contain short commonly used(by this interface implementors) logic.
Because an interface describes what. It doesn't describe how.
If you really want to add (hide) some logic inside an interface, you may consider adding an inner class (Note: never do it, this just shows what is possible from a pure technical perspective):
public interface Person {
public String getFirstName();
public String getLastName();
public class Util {
public String getName(Person person) {
return person.getFirstName() + " " + person.getLastName();
}
}
}
If you use this, it "feels" a bit like having static method code in the interface:
String fullName = Person.Util.getName(this);
As I said - it's pure technically and I don't see any reason to actually do it. A static method can be located in any class, no need to add it to an interface.
An interface is a contract. It says what an implementing object will have (at minimum), but that's all. It says "this house will have a door, a window, and a chimney".
An abstract class is more like a prefab house. It's not complete (you have to add your own siding, for example) but it has parts already there (there is a space for the door, but the whole fireplace is already setup.
The problem with giving code in interfaces is multiple inheritance. Java doesn't allow it. You can have a class implement many interfaces, because interfaces only promise there will be a method with a given signature.
If interfaces held code, then you could implement 3 of them, each with a method body for myUsefulFunction(String thing)... and now you don't know which one gets called.
That's why abstract classes can have method bodys (because you can only extend one class), but interfaces can't (because you can implement multiple interfaces).
I agree that a static method doesn't make sense in an interface. But i don't understand why java allows static members in an interface. Seems a bit inconsistent.
It's the abstract class or regular class which should implement something. Interfaces are not supposed to have any implementations, but they contain the interface of communicating. So static methods are not allowed.
An interface is a special abstract class with all abstract methods.
You can feel free to create an abstract class of your own that contains (non-abstract) static methods, but then you can only inherit from one of them.
Better yet, create a separate helper class with your static methods.

Categories

Resources