Java Relationship between interfaces/abstract classes - java

I am trying to build an algorithm that works in different ways depending on a traversal strategy and an update strategy. However, not every update Strategy works with every traversal strategy. Hence, I figured that an update strategy must only be instantiated with a corresponding traversal strategy. I wanted to force a constructor for that (see below). So that the subclasses would have to check if they support the strategy.
I am currently having an Interface
public interface TraversalStrategy {
...
}
And an (invalid) abstract class
public abstract class UpdateStrategy {
protected TraversalStrategy travStrategy;
public abstract UpdateStrategy(TraversalStrategy travStrategy);
}
What is the correct way to imply such a dependency? I could of course add an empty body to this constructor but that seemed wrong to me.
Update:
Inspired by the Answer of #Kayaman, I created a new class TestcaseGenerator that is used to construct a valid combination.
public TestcaseGenerator(TraversalStrategy travStrategy, UpdateStrategy updStrategy){
if (updStrategy.supports(travStrategy)){
this.travStrategy = travStrategy;
this.updStrategy = updStrategy;
}
}
What I don't like about this yet is, that it would now be unnecessary to give the instance of TraversalStrategy to the UpdateStrategy in order to check if it is supported. I would rather only need the class name. Can you tell me how to achieve that? Experiments with .getClass().getName() seemed horrible. Currently I am doing:
public boolean supports(TraversalStrategy travStrategy){
if(travStrategy instanceof UpstreamTraversalStrategy){
return true;
}
return false;
}

Even an abstract class must have a valid constructor. Even through it is not possible to create an instance of an abstract class, a non abstract subclass always calls the constructor of the super class first. Therefore your constructor on the abstract class needs a body to initialize the TraversalStrategy.

One common way is to have the superclass constructor call an abstract method such as isSupported(TraversalStrategy t); and fail if it's not true.
The subclasses would then implement the method accordingly by using instanceof or any other way to determine if the strategy is a supported one.
One approach would be to create a third class with a Builder pattern approach. Instead of providing TraversalStrategy as a parameter to UpdateStrategy, they would both be included in the third object (and they could be checked at build() to prevent incompatible strategies).
You could then have general functionality in the third class, with the strategy classes becoming lighter.

Related

Invoke Method of Subclass with Matching Regex

I am trying to call a method, convert(), based upon the return value matching the class' regex() method, both of which are defined in the below base class:
public abstract class BaseClass {
public abstract BaseClass convert(String value);
public abstract String regex();
}
I also have several subclasses that have implementations of those methods. I want to be able to do something like the below method (which will reside in BaseClass):
public static BaseClass parseNew (String value) {
// I use a switch statement to convey the idea of what I want to
// do, not for functionallity. Any non-constant cases raise
// compiler errors.
switch (value) {
case new Subclass1().regex():
return new Subclass1().convert(value);
case new Subclass1().regex():
return new Subclass1().convert(value);
// Repeat for all known and possibly unknown subclasses
}
}
I was thinking about using reflection, but I am very afluent in it. How would I get this functionality using reflection or some other concept?
The problem with this design is that it breaks abstraction (base aware of sub classes), making it a terrible idea.
A little about abstraction:
Abstraction is a process of hiding the implementation details from the user. Оnly the functionality will be provided to the user.
Instead you could make a different class which will contain this logic, and will act as a sort of factory.
Basically, you provide a base which exposes operations. This base is at the top of your inheritance tree. From it you provide implementations. The base in not aware of those implementations, they are not connected, they are specific. So the base class should know that sub exists, this just causes the code to be coupled and makes it non-modular and hard to maintain.
This mostly relates to creating a clean code.
So a quick look into factories... We want an object which will receive a value and parse it into an instance of BaseClass.
public class Parser {
private final Collection<BaseClass> implementations;
public Parser(Collection<BaseClass> implementations) {
this.implementations = implementations;
}
public BaseClass parseNew(String value) {
for (BaseClass implementation : implementations) {
if (implementation.regex().equals(value)) {
return implementation.convert(value);
}
}
throw new IllegalArgumentException("unsupported value");
}
}
The Parser class above is a factory which contains a collection of known BaseClass implementations. Using those, it may determine which implementation is wanted.
This is a pretty dynamic implementation. You would want to create an instance of this factory once, with the known implementations, and use it wherever.
General Design Note
There is also something weird about the the fact that BaseClass.convert returns BaseClass. I would expect it to return something else. BaseClass seems like a converter, and convert should return a value.
But that's just a general note.
Some reading resources:
https://www.geeksforgeeks.org/design-patterns-set-2-factory-method/
https://www.tutorialspoint.com/design_pattern/factory_pattern.htm
https://javatutorial.net/java-abstraction-example
http://www.javawithus.com/tutorial/relation-between-a-super-class-and-a-class

How to declare abstract method in non-abstract class

I want to declare a couple of abstract methods (so the implementation is required in the classes that inherit from this one) to fit my situation, which is:
I am making a puzzles solver program. So far I have 3 packages:
games.puzzles
games.puzzles.rivercrossing
games.puzzles.rivercrossing.wolfgoatcabbage
I don't want to get too specific but in the games.puzzles.rivercrossing package I have two classes that represent a bank and a state: GenericBank and GenericState.
Now, they define some behavior, but there are some methods that the classes that inherit from these must have, like move() to move one element from one bank to the other or isPermitted() and isFinal() to check the states.
For example, in the last package I have the WolfGoatCabbageGame class and it must have its own Bank and State classes which will inherit from the generic ones. These particular Bank and State classes must implement the methods I mentioned above, for example in the Wolf, Goat and Cabbage game, to check if the goat and the wolf are not in the same bank, etc.
So initially I declared the generic classes as abstract, and these methods to be implemented abstract as well:
public abstract class GenericBank {
// more members ...
public abstract boolean move(Element element, GenericBank dst);
// more members...
}
public abstract class GenericState {
// more members...
public abstract boolean isPermitted(GenericBank bank);
public abstract boolean isFinal(GenericBank bank);
// more members...
}
And this looked like it'd work until I found out I had to instantiate GenericBank and GenericState objects, which of course can't be done if these classes are abstract.
So I had to remove the abstract qualifier from the classes.
So... what can I do? How can I declare abstract methods (or achieve the same behavior) in a non-abstract class?
How to declare abstract method in non-abstract class?
Answer: You can't. It's kind of the definition of abstract. It's the same reason you can't instantiate an object as an abstract class.
Either:
A) You need to use Interfaces
B) Leave the methods empty in the parent class:
//technically this needs to return a value, but it doesn't need to *do* anything
public boolean isPermitted(GenericBank bank){ return false; }
C) Refactor your code so that you aren't instantiating abstract objects. I cannot advise how to do this as you haven't provided any code regarding this.
You could replace the abstract methods with empty methods that do nothing and return the default value of their respective return type (and, if necessary, make it part of the generic classes contract, that subclasses must override these methods).
Alternatively, you could keep your abstract Generic*-classes and add Null*-classes with abovementioned empty implementations, following the Null object pattern.
You cannot declare abstract methods in a non-abstract class, final dot.
That would simply defile the concept of abstract methods.
What you can do is have your class hierarchy implement interfaces dictating the required methods to implement.
If you found your formerly abstract classes were actually better designed as concrete classes, do convert them to concrete classes and implement the methods, even with a default, general implementation.
You can then fine-tune the overrides in your child classes.
Remove the abstract qualifier and add a empty body, or throwing some runtime exception.
Or instantiate these generic classes as anonymous sub classes
You cannot, the very definition of an abstract class is that it has abstract methods.
What you can do, is define default behaviour, that can be overruled by subclasses.
However, I would carefully consider your class hierarchy before doing this. The fact that you need to instantiate some classes before their actual implementations are known, suggests that your design may need re-thinking.
If you're going to re-design, you will want to look at the time of instantiation - and underlying that, the reasons for instantiating.
Right now, you want to use some of the common behaviour of a class, before the actual instance of that class is known.
It goes a bit beyond the scope of answering the question, but: consider explaining the design of the code to a friend. Or to a rubber duck. This may help you to find a fresh approach.
You can use Virtual instead!
internal class ClassA
{
public void Print()
{
Console.WriteLine("A");
PrintVirtual();
Console.WriteLine("--------------------------------------------------");
}
protected virtual void PrintVirtual()
{
Console.WriteLine("Virtual");
}
}
internal class ClassB : ClassA
{
protected override void PrintVirtual()
{
Console.WriteLine("B");
}
}
internal class ClassC : ClassA
{
protected override void PrintVirtual()
{
Console.WriteLine("C");
base.PrintVirtual();
}
}
and you can run the test
new ClassA().Print();
new ClassB().Print();
new ClassC().Print();

Possible design pattern instead of instanceof?

I am writing an object conversion class, used to convert domain layer objects into UI objects and vice versa. The problem is that my UI objects are organized into a hierarchy and as a result my object conversion class contains "instanceof" statements. There is a definite code smell here but I'm not sure what the solution is.
So my UI hierarchy contains a RuleDTO as follows:
public class RuleDTO {
protected long ruleID;
protected long rowID;
protected AttributeDTO leftCondition;
protected AttributeDTO rightCondition;
protected OperationTypeDTO operationType;
protected boolean isActive;
// etc...
}
My RuleDTO can then be subclassed by AssignmentRuleDTO as follows:
public class AssignmentRuleDTO extends RuleDTO {
protected String assignedToTeam;
protected String assignmentOperator;
// etc...
}
RuleDTO can also be subclassed by EvaluationRuleDTO:
public class EvaluationRuleDTO extends RuleDTO {
protected String successAction;
protected String failureAction;
// etc...
}
The problem is reached then in my ObjectConversionHelper class which contains the following type of logic:
{
// Perform logic common to RuleDTO such as setting ruleID, isActive etc
if(ruleDTO instanceof AssignmentRuleDTO) {
// Set assignedToTeam and assignmentOperator etc
}
else if (ruleDTO instanceOf EvaluationRuleDTO) {
// Set successAction and failureAction etc
}
}
What would be a good solution here instead? I've read about the visitor pattern, but not sure how it applies here.
Thanks
Your RuleDTO class should have a method called setStuff() or something similar.
Then you override it in AssignmentRuleDTO and in EvaluationRuleDTO to set the relevant fields.
This way your ObjectConversionHelper can just call
ruleDTO.setStuff();
I think using a Visitor pattern would be a reasonable approach here. So you'd have the Visitor interface
interface RuleDTO {
void visit(RuleDTO theRule);
void visit(EvaluationRuleDTO theEval);
void visit(AssignmentRuleDTO theAssign);
... and so on ...
}
And you'd add a method to these concrete classes to handle the double dispatch
public void accept(RuleDTOVisitor theVisitor) {
theVisitor.visit(this);
}
Lastly, you'd create some class which implements the visitor, say SettingPropertiesVisitor, and for each method, you can do the implementation where the appropriate fields for each object are set accordingly to your application requirements.
So then to use it
aRuleDTO.accept(new SettingPropertiesVisitor());
This way the appropriate visitor method will get invoked for each type, and then within the methods for your SettingPropertiesVisitor, you can do the appropriate assignments. This will get around the instanceof checks, and decouples that setter logic from the objects.
Of course, that might be overkill if this is the only visitor you ever create, in that case, instanceof isn't like killing kittens. But the obvious drawback here is each time you extend the API, you need to modify the visitor interface, and then probably all the concrete visitors to support the new method.
Visitor looks like overkill here IMHO.
There is no iteration over a graph of objects.
There is no requirement for double dispatch.
Remember KISS and YAGNI.
Just add an abstract method or leave it as-is.
You can always refactor later - assuming you have tests in place ;)
In your case, the visitor pattern could be applied by writing a convertToOtherClass method in RuleDTO, which is then overridden by its subclasses. You would then have, in your object conversion class, a method along the lines of convertRuleDTO (called in RuleDTO's convertToOtherClass method), which executes the relevant code, secure in the knowledge that it is operating on an instance of RuleDTO which has not been subclasses, because otherwise the subclass would override the convertToOtherClass method.
Take out the "else"... what's the problem?
There are a couple of plausible approaches. The two I would consider are using either an interface which all of your classes implement or using an enum that corresponds to your different classes.
If you have an interface (let's call it public interface DTO, you can have a method signature in it called setFields() or something similar which each of the implementing classes must implement. Then, through the magic of polymorphism, you can now treat all of your objects as DTO using typecasting and call setFields() on them without worrying what the actual object is. The setFields() method in each of the individual classes will take care of it for you.
Alternatively, you can make an enum that is essentially an ID for each of your classes and make each class have a global variable of that type (complete with getters and setters) in order to identify it. This is a somewhat "hacky" workaround but still a doable one.
How about creating a single ObjectConversionHelper class for each DTO class? Each of them could implement a common conversion interface differently, call inherited members etc. You could then make use of some object creation factory that would create relevant Helper for DTO and vice-versa (i.e. using reflection mechanizms).

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

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.

Can I create static methods on #MappedSuperclasses?

I have an abstract TemporalModel class (annotated with #MappedSuperclass) that adds created and updated fields to all extending models. I want to add a getLatest() static method to it:
public static TemporalModel getLatest() {
return find("order by created").first();
}
When I put this method on the base class, and call it through a concrete class (Transaction.getLatest()), I get an error:
UnsupportedOperationException occured : Please annotate your JPA model
with #javax.persistence.Entity annotation.
I suspect this is because JPA doesn't in fact know I'm calling this method "through" the base class (there is no real static method inheritance in Java).
Is there another way to implement this method once, instead of repeating it on all entity classes?
Update - one way to achieve this (which I'm using in another heavier app) is described here (gist). In my current app, however, I wouldn't like to use repositories, and I wondered if there's another, lighter solution.
Constructors and static methods can never be abstract. The idea behind an abstract class
is to create blueprints of methods, that have to get worked out in the subclass(es). I suggest trying an interface TemporalModel instead of an abstract class, in which you create the method public static TemporalModel getLatest();
I haven't used this Play framework, so I'm not sure about the details here, but usually, when one does the stuff you want to do, in Java, one simply specifies the concrete class as a parameter to the static method in question. It's kind of ugly, of course, but it is Java.
I assume that this find method is a static method that is added somehow (by annotation processing?) by this framework on every extending class, right? In that case, I think your only recourse is to do something like this:
public static <T extends TemporalModel> T getLatest(Class<T> cl) {
try {
/* I don't know what type the find() method returns, so you'll have to fix the casting */
return(cl.cast(cl.getMethod("find", String.class).invoke("order by created").first()));
} catch(AllThosePeskyReflectionExceptions e) {
throw(new Error(e));
}
}
I think that's the best way available given the premises. I know it's ugly, so I'd be happy to be wrong. :)

Categories