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).
Related
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.
Can I somehow move all field values from one object to another without using reflection? So, what I want to do is something like this:
public class BetterThing extends Thing implements IBetterObject {
public BetterThing(Thing t) {
super();
t.evolve(this);
}
}
So, the evolve method would evolve one class to another. An argument would be <? extends <? extends T>> where T is the class of the object, you're calling evolve on.
I know I can do this with reflection, but reflection hurts performance. In this case Thing class is in external API, and there's no method that would copy all the required fields from it to another object.
As #OliverCharlesworth points out, it can't be done directly. You will either have to resort to reflection (though I wouldn't recommend it!) or a series of field-by-field assignments.
Another option though, would be to switch from inheritance to composition:
public class BetterThing implements IBetterObject {
Thing delegate;
public BetterThing(Thing t) {
this.delegate = t;
}
// Thing methods (delegate methods)
String thingMethodOne() {
return delegate.thingMethodOne();
}
// BetterThing methods
}
This is commonly referred to as the decorator pattern.
See: Prefer composition over inheritance?
You should try to minimize the performance impact by using a library that spped up the reflective operations by caching the results. Have a look at Apache common-beanutils or Dozzer.
You may use Reflection in a way which will be less expensive. I made an application where when I run the program for the first time, I save the properties name and getter and setter methods in a map and when I need to extract the properties, I just invoke those same method passing the object to invoke it on. This has good performance than using reflection every time to get method objects when you need to clone.
The other way could be to use a serializer like the Jackson or something but that will be an expensive task to serialize and deserialize.
Java does not allow private or protected methods, so how do we ensure implementors of a bidirectional interface call the necessary methods?
Let's say we have an IModelListener interface as follows:
public interface IModelListener
{
public void handleChannelUpdate(int channel);
}
Then we have a ViewControl client as follows:
public class ViewControl implements IModelListener
ViewControl objects are going to work as long as we remember to have ViewControl call this:
model.registerChannelListener(this);
If Java allowed protected or private methods in an Interface, we could simply modify IModelListener to:
public interface IModelListener
{
public void handleChannelUpdate(int channel);
private void registerChannelListener( );
}
How can this be achieved?
Are there annotations that would do this?
Java does not support multiple inheritance so if Clients/Implementors are already a derived class (typical), then using an abstract class is not an option.
Thanks for helping,
Jeff
You probably miss the concept of interfaces. It can not contain private or protected methods, because the role of an interface is to provide accessible set of methods. You probably might, on the other hand, take look at abstract classes.
What you need is probably this:
public abstract class AbstractViewControler implements IModelListener {
protected abstract void registerChannelListener();
protected AbstractViewControler() {
this.registerChannelListener();
}
}
and then:
public class MyViewControler extends AbstractViewControler {
protected void registerChanelListener() {
//- Do what you need here.
}
}
and after that just:
IModelListener listner = new MyViewControler();
An interface is a way of providing a public contract to users of the class implementing the interface. How the class is implemented doesn't matter, as long as they are adhering to the contract. Therefore, it doesn't make sense to have private methods in an interface.
What you want is to enforce a default behavior on your class - in Java, abstract classes are the place to formulate default behavior inherited by all extending classes (see the template method design pattern for an application of this). Interfaces only describe, how your objects externally behave and how they can be used by others.
Interface in java intended to provide the signature of interface functionality in mean of signature that you implement in your classs so it should not to be private.
your need: you can have abstract method with some default statements that you want.
where you can have all type of access specifire.
In Java, you can't do it using an interface only.
If you want to achieve some sort of "autobinding" (i.e. call model.registerChannelListener(this); automatically on all pertinent objects), then you should have those objects implement an empty interface, retrieve the list of all the instances of classes implementing it via introspection and iterate on them.
You could do this periodically or at some specific point in the program. You could also use an #interface annotation to add a little syntactical sugar.
You might also want to invert the flow and create objects using dependency injection and/or a factory, so that you have that method called "automagically" just after creation (like with #PostConstruct).
Interfaces are the wrong place to look.
The usual solution in Java for problems like this one is to have a method in either object which returns the other:
public class ViewControl {
public IModel getModel() {...}
}
The method can then make sure that the model and the view are correctly hooked up. Now I guess that you don't really want to couple the view and the model. The solution is then to define a new ViewModel type which just delegates to the real model (most IDEs allow to create delegate types with 3-5 mouse clicks):
public class ViewControl {
public ViewModel getViewModel( IModel model ) {...}
}
You should be able to move this code to a base (abstract) view class which all views inherit from.
I have a superclass like this which I expect alot of classes to inherit:
public abstract class Super {
protected Object myField; //Not used anywhere in this class
//a load more code here which does useful stuff
}
All these classes will need to use an instance of myField. However the superclass does not. Have I made a bad design decision somewhere?
Not necessarily. If all the subclasses need the same field for the same reason, then that's no different than providing any other common functionality in a base class. as your classes grow you may find that you add common functionality which uses this field (e.g. referencing it in an equals/hashCode method).
Now, if the field is of type Object and each sub-class shoves something completely different into it, i would consider that a code smell.
Well IMHO, a field should not be present in a class if it's not really used by that class. What it seems to me that you really want here is to have a base class that tells its subclasses "you should ALL have some way of keeping state for X but I (the base class) will not modify that X state, in which case you should make an abstract method in order to convey that message, something like this:
public abstract class Super {
protected abstract Object getMyField();
}
It's hard to say with such a vague description, but it would seem like you could do some generalization and push some common code up into your superclass. If your subclasses are doing something similar with the field then some commonality could be found (using template methods or strategies to handle subclass-specific differences), otherwise if every subclass is doing something different with it then what's the point of using a common field?
No, I don't think so. Abstract class serve that purpose (Have common functionality in base class and let subclass implement only specific required functionality).
So, if you don't use that field in class Super - why do you need it there?
Perhaps your super class would provide an interface to interact with this field in generic way, for example:
public abstract class Super<T> {
protected T myField;
public T getField() {
return myField;
}
}
public class Child extends Super<String> {
public Child( String label ) {
super.myField = label;
}
}
As stated in this tuturial
A protected field or method is accessible to the class itself, its subclasses, and classes in the same package.
This means that the protected fields have been designed precisely to have these characteristics.
Just on a lighter note The only thing common in your hirarchy is one field then you should get rid of abstract class and Create one Marker Interface.
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.