Home > Net >  Trying to avoid code duplication when implementing abstract methods
Trying to avoid code duplication when implementing abstract methods

Time:10-06

I have the following abstract class defined here:

@Slf4j
public abstract class PublishMappingService {
    @Autowired
    private ErpPackageRepository erpPackageRepository;

    @Autowired
    private PubSubClient pubSubClient;

    @Autowired
    private RequestInfo requestInfo;

    public abstract void publishMappingUpdateEvent(MappingsEntity mappingsEntity);
    public abstract void publishMappingUpdateEvent(List<MappingsEntity> mappingsEntityList);

    public void publishEvent(String companyId) {
        ErpPackage erpPackage;

        try {
            erpPackage = erpPackageRepository.getSelectedErpPackageForCompanyId(companyId);
            pubSubClient.publishEventAsync(
                    new MappingUpdatedEvent(
                            erpPackage.getPartnerId(), erpPackage.getCompanyId(),
                            erpPackage.getErpId(), this.requestInfo.getCorrelationId(),
                            null
                    )
            );
        } catch (NotFoundException e) {
            log.error("MappingsRepository::publishEvent: This entity is not registered with ECP - companyId: {}", companyId, e);
        } catch (Exception e) {
            log.error("MappingsRepository::publishEvent: Failed to publish MappingUpdatedEvent for {}", companyId, e);
        }
    }
}

Let's say I have two classes (A and B) that inherit from the abstract base class

public class A extends PublishMappingService {
// public class B extends PublishMappingService {
    @Override
    public void publishMappingUpdateEvent(MappingsEntity mappingsEntity) {
        // Identical in Class B
        if (mappingsEntity != null) {
            String companyId = mappingsEntity.getCompanyId();

            publishEvent(companyId);
        }
    }

    @Override
    public void publishMappingUpdateEvent(List<MappingsEntity> mappingsEntityList) {
        // Identical in Class B
        if (mappingsEntityList != null && !mappingsEntityList.isEmpty()) {
            String companyId = mappingsEntityList.get(0).getCompanyId();

            publishEvent(companyId);
        }
    }
}

Essentially, the problem is that when I override and implement the abstract methods defined in my subclasses, these methods will be identical across every subclass.

Since I'm not avoiding code duplication with my abstract class, I thought of just making a utility class instead. However, from what I've read, utility classes should only be created if every method can be declared as static which I can't do so as seen in the behavior of the publishEvent method.

I also thought about using an interface with default methods but that approach also wouldn't work since then my instance variables would be need to be static and final, which isn't possible with autowired fields.

Thus, I'm asking to see if there's any alternative ways I can approach refactoring my code to avoid duplication here? Thanks!

CodePudding user response:

If all implementations of an abstract method are identical, then there's no need to have the abstract method in the first place. Move the implementation to the base class.

An abstract method forces all derived classes to implement this method (or be abstract themselves). If child classes are free to implement or override the method, it doesn't have to be abstract.

  • Related