2
\$\begingroup\$

I wrote this method that does the job and passes the assertion tests for a large java backend project but I'm not all happy with the way it reads, perhaps you can tell me how to refactor and/or improve this method?

public Set<ProductOfferingJsonDto> getJsonProductOfferings() {
 Set<ProductOfferingJsonDto> set = new HashSet<ProductOfferingJsonDto>();
 ProductOfferingJsonDto pjson = null;
 Iterator iter = productOfferings.iterator();
 while(iter.hasNext()){
 ProductOfferingDto pdto = (ProductOfferingDto) iter.next();
 if(pdto instanceof BundledProductOfferingDto) {
 Set<ProductOfferingDto> tmp = ((BundledProductOfferingDto) pdto).getProductOfferings();
 Iterator piter = tmp.iterator();
 Set<ProductOfferingJsonDto> tmpset = new HashSet<ProductOfferingJsonDto>();
 while(piter.hasNext()){
 SimpleProductOfferingDto piterdto = (SimpleProductOfferingDto) piter.next();
 tmpset.add(new SimpleProductOfferingJsonDto(piterdto.getId(), piterdto.getName(), piterdto.getDescription(), piterdto.getStatus(),
 piterdto.getBrand(), piterdto.getValidFor(),
 piterdto.getProductSpecification(),
 piterdto.getDescriptorId(), piterdto.getTags(), piterdto.getProductOfferingPrice()));
 }
 BundledProductOfferingDto bpod = (BundledProductOfferingDto) pdto;
 pjson = new BundledProductOfferingJsonDto(bpod.getId(), bpod.getName(), bpod.getDescription(), bpod.getStatus(),
 bpod.getBrand(), bpod.getValidFor(),
 tmpset,
 bpod.getDescriptorId(), bpod.getTags(), bpod.getProductOfferingPrice());
 }
 if(pjson != null) {
 set.add((ProductOfferingJsonDto) pjson);
 }
 }
 return set;
}
Caridorc
28k7 gold badges54 silver badges137 bronze badges
asked Nov 1, 2013 at 7:43
\$\endgroup\$
2
  • \$\begingroup\$ What's the problem of this code? Why you thing it is hard to reader and need refactor? You need a goal for reflector code, so other people can help you. \$\endgroup\$ Commented Nov 1, 2013 at 13:57
  • \$\begingroup\$ @ZijingWu I think the code is difficult to understand what it does. I wanted to make it with smaller units that are more clear what they do. I'm converting between backend object and object suitable for JSON. The goal is to add a flad for leaf at leaf nodes and generated unique IDs over classes while IDs now are unique only within a class, therefore I'm making specific objects for the json requirement. \$\endgroup\$ Commented Nov 1, 2013 at 17:56

2 Answers 2

7
\$\begingroup\$

I would move the construction of the JSON objects into factory methods like this:

public class BundledProductOfferingJsonDto
{
 ....
 public static BundledProductOfferingJsonDto fromDto(BundledProductOfferingDto dto, Set<ProductOfferingJsonDto> productOfferings)
 {
 return new BundledProductOfferingJsonDto(dto.getId(), dto.getName(), dto.getDescription(), dto.getStatus(),
 dto.getBrand(), dto.getValidFor(),
 productOfferings,
 dto.getDescriptorId(), dto.getTags(), dto.getProductOfferingPrice());
 }
}

Similar for SimpleProductOfferingJsonDto

Also, is there a reason why your are using the while loops with the iterators instead of for example for (ProductOfferingDto piter : tmp)?

The method could then read something like this:

public Set<ProductOfferingJsonDto> getJsonProductOfferings() {
 Set<ProductOfferingJsonDto> set = new HashSet<ProductOfferingJsonDto>();
 ProductOfferingJsonDto pjson = null;
 for (ProductOfferingDto pdto : productOfferings) {
 if (pdto instanceof BundledProductOfferingDto) {
 Set<ProductOfferingDto> tmp = ((BundledProductOfferingDto) pdto).getProductOfferings();
 Set<ProductOfferingJsonDto> tmpset = new HashSet<ProductOfferingJsonDto>();
 for (ProductOfferingDto piter : tmp) {
 SimpleProductOfferingDto piterdto = (SimpleProductOfferingDto)piter;
 tmpset.add(SimpleProductOfferingJsonDto.fromDto(piterdto));
 }
 BundledProductOfferingDto bpod = (BundledProductOfferingDto) pdto;
 BundledProductOfferingJsonDto pjson = BundledProductOfferingJsonDto.fromDto(bpod, tmpset));
 set.add(pjson);
 }
 }
 return set;
}
answered Nov 1, 2013 at 8:09
\$\endgroup\$
3
  • \$\begingroup\$ I'm giving you an upvote. Even though we got the same answer (and mine slightly faster :P) I think your snippet reads better. \$\endgroup\$ Commented Nov 1, 2013 at 8:17
  • \$\begingroup\$ @user1021726: hehe, funny, same idea :) \$\endgroup\$ Commented Nov 1, 2013 at 9:20
  • 1
    \$\begingroup\$ You can eliminate the last if condition by putting set.add(ProductOfferingJsonDto) pjson) into the first condition, when the JSON instance is created. This would eliminate the need for json as well and so this method could be reduced to 15 lines. \$\endgroup\$ Commented Nov 1, 2013 at 10:25
3
\$\begingroup\$

You could add a factory method for SimpleProductOfferingJsonDto and BundledProductOfferingJsonDto which only takes a piterdto and a bpod object.

It could look something like:

public Set<ProductOfferingJsonDto> getJsonProductOfferings() {
Set<ProductOfferingJsonDto> set = new HashSet<ProductOfferingJsonDto>();
ProductOfferingJsonDto pjson = null;
Iterator iter = productOfferings.iterator();
while(iter.hasNext()){
 ProductOfferingDto pdto = (ProductOfferingDto) iter.next();
 if(pdto instanceof BundledProductOfferingDto) {
 Set<ProductOfferingDto> tmp = ((BundledProductOfferingDto) pdto).getProductOfferings();
 Iterator piter = tmp.iterator();
 Set<ProductOfferingJsonDto> tmpset = new HashSet<ProductOfferingJsonDto>();
 while(piter.hasNext()){
 SimpleProductOfferingDto piterdto = (SimpleProductOfferingDto) piter.next();
 tmpset.add(new NewJSONSPOD(piterdto));
}
 BundledProductOfferingDto bpod = (BundledProductOfferingDto) pdto;
 pjson = new NewJSONBPOD(bpod);
 if(pjson != null) {
 set.add((ProductOfferingJsonDto) pjson);
 }
}
return set;
public static BundledProductOfferingJsonDto NewJSONBPOD(BundledProductOfferingDto bpod) {
 return new BundledProductOfferingJsonDto(bpod.getId(), bpod.getName(), bpod.getDescription(), bpod.getStatus(),
 bpod.getBrand(), bpod.getValidFor(),
 tmpset,
 bpod.getDescriptorId(), bpod.getTags(), bpod.getProductOfferingPrice());
}
public static SimpleProductOfferingJsonDto NewJSONSPOD(SimpleProductOfferingDto piterdto) {
 return new SimpleProductOfferingJsonDto(piterdto.getId(), piterdto.getName(), piterdto.getDescription(), piterdto.getStatus(),
 piterdto.getBrand(), piterdto.getValidFor(),
 piterdto.getProductSpecification(),
 piterdto.getDescriptorId(), piterdto.getTags(), piterdto.getProductOfferingPrice()));
}

You might want to change some names etc, but you get the gist of it

answered Nov 1, 2013 at 8:05
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.