Mapping object properties to another object property using enum? - java

just wondering if anyone can help me out with something.
Basically I have two objects from different places for example two different car classes. I want to map the properties of class carA to the properties of class carB using a mapper I have created. This is simple enough in most scenarios as can be seen below.
public carB carMapper(carA car){
carB carb = new carB();
carb.weight = car.weight
carb.size = car.size
}
However, there are some scenarios where class CarA stores the corresponding values in a slightly different format to that of CarB, ie, for a model of car which is a Ford carA stores this as Frd but carB stores it as Ford. Is there an easy way (perhaps using enums or something) that I can map these correctly? I know I could do
if (carA.model = frd)
then carB.model = Ford
etc but I dont want to do this for every scenario.... I know the possible values of both carA and carB, could I use an enum in some way to help me out here?
Thanks.

It appears that you are looking for something like a mapping constructor. There is already a well-known concept called a copy constructor which helps you create a copy of an object of a given class. In your case, you want to create an instance of some class given an instance of another class.
I do not think enums can be (or should be) used for this purpose, mainly because they are not designed for this purpose.
It's not very clear if such a construct is immensely useful (and generic). For instance, would you want to create a Turtle given a Car? There isn't much common between them, so providing such a facility seems to be of little value. You are taking an example of CarA and CarB as classes, but since they are two different classes, they are to be assumed entirely different things, any commonality should be assumed purely coincidental.
If you do want to externalize this operation, then you may consider using some kind of serialization for your mapping in a format like JSON or XML and then one can imagine generic processing of that format to create objects of classes involved:
<map from="CarA" to="CarB">
<property>model</property>
<override>Ford</override>
</map>
In this case, you create an instance of CarB and reflectively set the fields on it based on the mappings. You can make an assumption that all the other fields are copied verbatim. Of course, you will need to flush out all the details of your specification for it to be generically useful.
Otherwise, I don't see anything wrong with the if-else construct you have alluded to, since its usefulness is decidedly limited.

Thanks for the feedback guys, appreciate the responses, sorry I haven't had a chance to reply sooner. I have found a solution to my problem using an enum. It suits exactly what I was looking for, maybe for some reason it isnt ideal but if anyone can think of some reason I shouldn't be using an enum in this way I am more than happy to hear it. Anyway, my solution is below and allows me to add multiple values etc:
public enum ModelMapper
{
Ford("Ford", "frd"),
Renault("Renault", "rnlt");
private final String carAValue;
private final String carBValue;
ModelMapper(String carA_value, String carB_value)
{
carAValue = carA_value;
carBValue = carB_value;
}
public static String getCarAValue(String carB_value)
{
for (ModelMapper m: ModelMapper.values()) {
if (m.carBValue.equals(carB_value)) {
return m.carAValue;
}
}
throw new IllegalArgumentException(carB_value);
}
}

Related

Possible real life reasons of adding a custom list object in the same class as a field in java?

I hope the question is not too vague or broad to answer.
I can create the list itself wherever I need it; if I need it as a static field I can make it that too in another classes.
Why would I add a custom list as a field in the very same class?
What are the strengths and weaknesses of this approach in OOP?
Can you explain the differences of the outcomes of these approaches?
Edit: I generally use custom lists as suggested to store multiple instances of a class. I examine other people's code, and I see these approaches where the classes have no parent-child relations with others, yet it's defined as a list object in the same class as a field for to store multiple instances of the class itself. It reminds me infinity mirror effect. So, I wanted to know what I'm missing here.
class Record {
String name;
String surname;
String phoneNumber;
ArrayList<Record> phoneBook;
}
class Main {
String x;
String y;
ArrayList<Record> phoneBook;
}
Based on what you say, suppose you have 10 instances of the Record class and assuming that in each class you stored a list of all those 10 instances then you would actually have 100 and depending on what you do, the performance of your application may be affected.
On the other hand, let's say you have the 10 instances of the Record class but you only store the instance itself in the list, it doesn't make sense, it won't be useful at all.
Finally, the logical thing would be that when creating a list it is to store several instances of the class and then you can access the data of each one, therefore the use of a list in the class itself is not useful in this case.

Most efficient way to remove duplicated code from multiple strategies

We have 3 types of attributes in our project: CategoryAttribute, ProductAttribute and ProductTypeAttribute. These are outside of our control as they come from autogenerated classes and may contain attribute values of different types e.g. text, number or image. Now, each attribute has its own strategy to retrieve attributeValue. For simplicity, let's assume that all 3 of them have TextStrategy, NumberStrategy and ImageStrategy.
Example strategy:
#Component
public class CategoryImageAttributeStrategy implements CategoryAttributeStrategy {
#Override
public boolean isApplicable(CategoryAttribute attribute) {
return attribute.getImage() != null;
}
#Override
public Object getAttributeValue(CategoryAttribute attribute) {
//return attribute value here
//may be different or may be the same
//for ProductImageAttributeStrategy and ProductTypeImageAttributeStrategy
}
}
While getting image value may be different for all of them, getting text value is the same and we end up with 3 classes of almost the same code and I really really really don't like duplicating code.
I thought about creating an abstract class/default interface for each strategy type e.g. DefaultTextStrategy that all 3 text strategies would inherit from and either use default code provided higher or override it with own implementation, however I'm not really satisfied with this approach as it requires to create even more classes for such a simple task.
Maybe is it even possible to combine strategies of the same type (e.g. image) into one?
I would really like to hear what more experienced folks have to say in this matter as I would like to learn and improve.
Thanks in advance for your time.
There should be only 3 strategies. TextStrategy, NumberStrategy and ImageStrategy which extend the base strategy. Mixing attributes and strategy will make it confusing as both are actually independent and have many to many relationship with one another.
Let the 3 attributes extend a single Attribute class : CategoryAttribute, ProductAttribute and ProductTypeAttribute.
Let the strategies decide on what needs to be done based on the Attribute class object being passed to it. For Text strategy there would be single implementation. For Image strategy, you may require special handling for the one class.
Here's what I did:
First, I created an interface for all types of strategies named "AttributeValueStrategy". Then added 3 callbacks (type specific, e.g. NumberValueCallback etc.). Now, each strategy implements callback interface of its type and AttributeValueStrategy interface. Then there's DefaultStrategyMethods class that contains default "getAtrribute" for each type and the actual strategy call the defaultStrategyMethods (like below) or just implements its own code.
#Override
public Object getAttributeValue(Object attribute) {
return defaultStrategyMethods.getNumberValue(attribute, this);
}
Callbacks are created because only the actual strategy knows which class should it cast to (and has a method to do that), and DefaultStrategyMethods needs to use it so that's why I pass "this" as second argument (which is the callback itself).
No more duplicates, everything is clear and clean.

How can I initialize interdependent final references?

I have a class and a factory function that creates new anonymous class objects extending that class. However, the anonymous class objects all have a method in which there are references to other objects. In my full program, I need this to create and combine parsers, but I've stripped down the code here.
class Base{
public Base run(){
return null;
}
static Base factory(final Base n){
return new Base(){
public Base run(){
return n;
}
};
}
}
public class CircularReferences{
public static void main(String args[]){
final Base a, b;
a = Base.factory(b);
b = Base.factory(a);
}
}
I get CircularReferences.java:17; error: variable b might not have been initialized. That's true, it wasn't, but can't I set aside space for these variables and then initialize them using references to these spaces, which will be filled with the proper values before they are ever actually used? Can I perhaps use new separately from the constructor? How can I create these variables so they reference each other?
The quick answer is that you can't do this. If you absolutely must do something like this, then use a private setter on the class and bind things together after they are constructed (i.e. use enforced immutability instead of final fields). Hopefully it's obvious that I don't think this is a good idea - I just wanted to provide a answer to your actual question before I answer the way that I really want to.
OK - now that is out of the way, here's the real response that is called for here:
Generally speaking, this sort of situation is a strong indicator that refactoring is needed to separate concerns. In other words, the Base class is probably trying to be responsible for too many things.
I realize that the example is contrived, but think about what functionality requires the circular dependency, then factor that functionality out into a separate class/object that then gets passed to both of the Base constructors.
In complex architectures, circular dependency chains can get pretty big, but strictly forcing final fields is great way to look for those types of refactoring opportunities.
If you have a concrete example, I'd be happy to help with some refactoring suggestions to break a dependency like this.
concrete example provided - here's my suggestion:
It seems like there is a concern of obtaining an appropriate ParseStrategy based on a token. A ParseStrategyProvider. So there would be a TopLevelParseStrategy that reads the next token, looks up the appropriate parse strategy, and executes it.
TopLevelParseStrategy would hold a final reference to the ParseStrategyProvider.
The ParseStrategyProvider would then need to have a registration method (i.e. registerStrategy(token, parseStrategy) ).
This isn't functionally much different from doing this with enforced immutability via a private setter (the registerStrategy method is for all intents and purposes the same as the private setter), but the design is much more extensible.
So you'd have:
public ParseStrategy createParser(){
ParseStrategyProvider provider = ParseStrategyProvider.create();
TopLevelParseStrategy topLevel = new TopLevelParseStrategy(provider);
provider.registerStrategy("(", topLevel);
// create and register all of your other parse strategies
return topLevel;
}

Framework to populate common field in unrelated classes

I'm attempting to write a framework to handle an interface with an external library and its API. As part of that, I need to populate a header field that exists with the same name and type in each of many (70ish) possible message classes. Unfortunately, instead of having each message class derive from a common base class that would contain the header field, each one is entirely separate.
As as toy example:
public class A
{
public Header header;
public Integer aData;
}
public class B
{
public Header header;
public Long bData;
}
If they had designed them sanely where A and B derived from some base class containing the header, I could just do:
public boolean sendMessage(BaseType b)
{
b.header = populateHeader();
stuffNecessaryToSendMessage();
}
But as it stands, Object is the only common class. The various options I've thought of would be:
A separate method for each type. This would work, and be fast, but the code duplication would be depressingly wasteful.
I could subclass each of the types and have them implement a common Interface. While this would work, creating 70+ subclasses and then modifying the code to use them instead of the original messaging classes is a bridge too far.
Reflection. Workable, but I'd expect it to be too slow (performance is a concern here)
Given these, the separate method for each seems like my best bet, but I'd love to have a better option.
I'd suggest you the following. Create a set of interfaces you'd like to have. For example
public interface HeaderHolder {
public void setHeader(Header header);
public Header getHeader();
}
I'd like your classes to implement them, i.e you's like that your class B is defined as
class B implements HeaderHolder {...}
Unfortunately it is not. Now problem!
Create facade:
public class InterfaceWrapper {
public <T> T wrap(Object obj, Class<T> api) {...}
}
You can implement it at this phase using dynamic proxy. Yes, dynamic proxy uses reflection, but forget about this right now.
Once you are done you can use your InterfaceWrapper as following:
B b = new B();
new IntefaceWrapper().wrap(b, HeaderHolder.class).setHeader("my header");
As you can see now you can set headers to any class you want (if it has appropriate property). Once you are done you can check your performance. If and only if usage of reflection in dynamic proxy is a bottleneck change the implementation to code generation (e.g. based on custom annotation, package name etc). There are a lot of tools that can help you to do this or alternatively you can implement such logic yourself. The point is that you can always change implementation of IntefaceWrapper without changing other code.
But avoid premature optimization. Reflection works very efficiently these days. Sun/Oracle worked hard to achieve this. They for example create classes on the fly and cache them to make reflection faster. So probably taking in consideration the full flow the reflective call does not take too much time.
How about dynamically generating those 70+ subclasses in the build time of your project ? That way you won't need to maintain 70+ source files while keeping the benefits of the approach from your second bullet.
The only library I know of that can do this Dozer. It does use reflection, but the good news is that it'll be easier to test if it's slow than to write your own reflection code to discover that it's slow.
By default, dozer will call the same getter/setters on two objects even if they are completely different. You can configure it in much more complex ways though. For example, you can also tell it to access the fields directly. You can give it a custom converter to convert a Map to a List, things like that.
You can just take one populated instance, or perhaps even your own BaseType and say, dozer.map(baseType, SubType.class);

Java create dynamic class

I have 2 questions that I was hoping someone could help me with. Is there a way to create a class on the fly with android/java and also add variables to the class? For example I would like to do something like this:
Class c = new Class();
c.name = 'testing';
c.count = 0;
c.getName = new function(){
return c.name;
}
Just wondering if this is possible or if there is another way to do this. Basically I want to build an object that I can use the data from as an object.
No, the syntax you describe is not possible in Java. I'm not sure what you are trying to accomplish there. If you want to create a class to use to hold data on the fly, you can create an anoynmous inner class.
Object object = new Object() {
private String name = testing;
private int count = 0;
public String getName() {
return name;
}
}
In general, I wouldn't use this for a data objects though. This functionality is typically used for anonymous implementations of interfaces to support callbacks, etc.
This is not typically done. It can be done by reflection, but would be a fairly bad idea--This type of code is really annoying to debug, won't interact correctly in the IDE (For instance, ctrl-clicking on an instance of c.getName wouldn't be able to jump to where the method is defined), it would probably be a pretty big performance hit, etc.
However, for some generic tools this is possible. I believe Hibernate might have the ability to create classes from DB tables.
The most common use, however, is in mocking used within testing frameworks--They can do almost exactly what you want. Look at EasyMock with TestNG.
In general, though, you are better off just defining a business class and going with it rather than trying to make some abstract framework that generates your classes for you.

Categories

Resources