0

I got the following problem. I want to create SomeObject. This object consists of various nested objects NestedObject1, NestedObject2, ... I created mappers to create those nested objects Mapper1 to create NestedObject1, Mapper2 to create NestedObject2, and so on. Those Mappers call a huge amount of setters, and some of them need information from some entites from the db (and some don't). This is the problem in the java language:

public class MyClass {

    @Inject
    private MyDao dao;

    @Inject
    private Mapper1 mapper1;
    @Inject
    private Mapper2 mapper2;
    @Inject
    private Mapper3 mapper3;
    @Inject
    private Mapper4 mapper4;
    @Inject
    private Mapper5 mapper5;

    public SomeObject map(Integer id) {
        SomeEntity entity = dao.findById(id);

        SomeObject someObject = new SomeObject();
        someObject.setNestedObject1(mapper1.map(entity));
        someObject.setNestedObject2(mapper2.map());
        someObject.setNestedObject3(mapper3.map(entity));
        someObject.setNestedObject4(mapper4.map(entity));
        someObject.setNestedObject5(mapper5.map());
        return someObject;
    }

}

I am thinking of the following refactoring: Make an interface Mapper and have all mappers implement this. Then I could inject the List of mappers. It would be pretty easy to add or remove on mapper, without touching MyClass. I think this is a good idea but the problem is the MyDao. Instead of one DB access I would then need 3.

The interface would then look like

public interface Mapper {

    public void map(SomeObject someObject);

}

Mapper1 would look like

public class Mapper1 implements Mapper {

    private static final Integer VALUTA = 1;

    @Inject
    private MyDao dao;

    @Override
    public void map(SomeObject someObject) {
         SomeEntity entity = dao.findById(id);  // and I have no idea what the id is

         NestedObject1 nestedObject1 = new NestedObject1();
         nestedObject1.setSomeField(entity.getSomething());
         nestedObject1.setSomeOtherField(VALUTA);

         someObject.setNestedObject1(nestedObject1);
    }

}

id is unknown in this context. Include id in the signature? I have no idea... Mapper3 and Mapper4 would have to look up the entity as well.

I was thinking about an abstract class which will look for the entity in the BeforeClass method, but I think this still get's called multiple times.

Btw: I know the title sucks, please feel free to rename it.

Chris311
  • 3,794
  • 9
  • 46
  • 80
  • 3
    Can you please elaborate on `Instead of one DB access I would then need 3.` ? – We are Borg Feb 26 '16 at 12:24
  • @WeareBorg Ok, i edited my initial post. – Chris311 Feb 26 '16 at 12:29
  • So, do you mean because you have different(3) entities implementing one Mapper interface, accessing/creating list requires accessing the database 3 times? If that's what you mean, There is no escape to this. – We are Borg Feb 26 '16 at 12:33
  • @Chris311 Not sure I follow. Why doesn't the mapper interface take the SomeEntity object to map? Call the DAO once, get the entity, and pass it to all mappers. – JB Nizet Feb 26 '16 at 12:35
  • @WeareBorg You said "different(3) entities implementing one Mapper interface". No, none of my entites is implementing a mapper. I will explain the problem in words in my inital post. – Chris311 Feb 26 '16 at 12:39
  • @JBNizet Not every mapper needs to know the entity to create a nestedObject. The different mappers just create the nestedObjects and some of them need some information from an entity. I will explain the problem (in words) in my inital post. – Chris311 Feb 26 '16 at 12:40
  • That's not a problem. They just have to ignore the passed entity. – JB Nizet Feb 26 '16 at 12:41
  • You said `Make an interface Mapper and have all mappers implement this.` . I presumed that's what is about DB access. Sorry, edit your post for better understanding of what do you expect. – We are Borg Feb 26 '16 at 12:44
  • Question isn't clear to me. – vikingsteve Feb 26 '16 at 12:44
  • I edited the question. – Chris311 Feb 26 '16 at 12:44
  • Okay, I just try once, then I leave it to fellow SO members. You don't want DB to be accessed for creating those entities, right? How does having/creating/implementing Mapper/mappers help that? – We are Borg Feb 26 '16 at 12:50
  • It is ok to access the db for creating those instances. The entity is needed to create the objects. But before my refactoring I only had to lookup the entity once; after my refactoring I will have to lookup the entity 3 times. – Chris311 Feb 26 '16 at 12:52
  • @Chris311 Why don't you change your method to `map(SomeObject someObject, SomeEntity someEntity )` to avoid multiple look ups as you said – Pragnani Feb 26 '16 at 13:13
  • @PragnaniKinnera That would be one possible solution, but then `Mapper2` and `Mapper5` don't use the entity, although they got it in the signature. – Chris311 Feb 26 '16 at 13:24
  • @PragnaniKinnera Another issue with your solution is: If I want to add another mapper which needs another entity, every mapper has to change its signature. – Chris311 Feb 26 '16 at 13:40
  • @Chris311 You should take a generic Entity that should accept all types of Entities, I'd suggest you to look at `Strategy Pattern` that suits your requirements – Pragnani Feb 26 '16 at 13:56
  • If you make it an answer with an example I will give you the points. I am not quite sure if this pattern suits here. – Chris311 Feb 26 '16 at 14:48
  • Have a look at http://stackoverflow.com/questions/370258/real-world-example-of-the-strategy-pattern/35180265#35180265 – Ravindra babu Feb 26 '16 at 14:52
  • It is not applicable in this case. We have different signatures. – Chris311 Feb 26 '16 at 15:29

0 Answers0