4
\$\begingroup\$

Use Case

The third party library that I am working with implements its data model in this fashion.

Interface
  - Implementation (24 different implementations)
     - Interface
         - Implementation (variable number of implementations)
              - etc...

Unfortunately, none of the interfaces have definitions for any of the common methods in the implementations... which has been interesting. As well, many of the implementations come in two flavours - required and optional. For whatever reason, this was not implemented as a flag, but as two separate classes.

This has lead to some interesting code, which I feel has some code smell it, but I'm not sure how to improve it.

Code

This code essentially fetches a deeply nested list of items buried inside this third party library. Oddly, all implementations will eventually produce this list of items all with the same bean. Since all implementations are essentially the same, I moved it an abstract class:

public abstract class AbstractAdapter<ChoiceClass, OptionalClass, RequiredClass, EntryBeanClass, BeanClass> {

    Class<ChoiceClass> choiceClass;
    Class<OptionalClass> optionalClass;
    Class<RequiredClass> requiredClass;
    Class<EntryBeanClass> entryBeanClass;
    Class<BeanClass> beanClass;

    {
        initializeClasses();
    }

    abstract void initializeClasses();
    abstract List<ChoiceClass> optionalToEntry(OptionalClass optional);
    abstract List<ChoiceClass> requiredToEntry(RequiredClass required);
    abstract BeanClass entryToBean(EntryBeanClass entry);

    List<BeanClass> getCcdBeans(MagicRequestBean requestBean) {
        List<Component3Choice> components = requestBean.getComponent();

        List<ChoiceClass> entries = Lists.newArrayList();
        for (Component3Choice component : components) {
            if (optionalClass.isInstance(component)) {
                entries = optionalToEntry(optionalClass.cast(component));
                break;
            }
            if (requiredClass.isInstance(component)) {
                entries = requiredToEntry(requiredClass.cast(component));
                break;
            }
        }

        return entries.stream()
                .filter(entryBeanClass::isInstance)
                .map(entryBeanClass::cast)
                .map(this::entryToBean)
                .collect(Collectors.toList());
    }
}

Questions

  • Is there a cleaner solution to model this adapter?

Any other advice to improve this code would be appreciated.

\$\endgroup\$
  • \$\begingroup\$ May I ask what 3rd party library this is? \$\endgroup\$ – Simon Forsberg Mar 18 '15 at 0:10
  • 1
    \$\begingroup\$ It's a library for reading HL7 messages. Basically, it's a SOAP message for communication if healthcare information, but it's extremely verbose. The library itself is proprietary and we have to license it to use it. \$\endgroup\$ – Pete Mar 18 '15 at 0:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.