What is the recommended pattern for 2 classes that are identical apart from constant names?

Viewed 36

I have an interface and 2 classes implementing the interface. The only difference between the classes is the constant name, they are being used for the same thing but from different locations. I just want to count how many times the method is called from each different location. Is there a better way of doing this without the repetition or passing in the metric name as a string?

public interface OldIdResolver {

    Optional<String> getNewIdFromOldId();

}

public class CustomFieldIdResolver implements OldIdResolver {

    Optional<String> getIdFromLegacyId(String oldId) {

        Optional<Id> newIdOptional = idService.getNewIdFromOldId(oldId);
        if (newIdOptional.isPresent()) {
            statsDClient.incrementCounter("customField.oldIdUsed");
        }
        return newIdOptional;
    }
}

public class SearcherIdResolver implements OldIdResolver {

    Optional<String> getIdFromLegacyId(String oldId) {

        Optional<Id> newIdOptional = idService.getNewIdFromOldId(oldId);
        if (newIdOptional.isPresent()) {
            statsDClient.incrementCounter("searcher.oldIdUsed");
        }
        return newIdOptional;
    }
}
1 Answers

Ordinarily you'd simply make one class and make a constructor:

public class AnyMetricIdResolver implements OldResolver {
  private final String metricName;

  public AnyMetricIdResolver(String metricName) {
    this.metricName = metricName;
  }

  Optional<String> getIdFromLegacyId(String oldId) {
     Optional<Id> newIdOptional = idService.getNewIdFromOldId(oldId);
     if (newIdOptional.isPresent()) {
        statsDClient.incrementCounter(metricName);
     }
     return newIdOptional;
  }
}

If for some reason that's not good enough (you were rather vague with 'passing the metric name as a string'), you can make an actual class for each kind of metric string, but still do some code reuse. Keep the IdResolver from above (you may want to make it package private if you must), then start subclassing that:

public class SearcherIdResolver extends AnyMetricIdResolver {
  public SearcherIdResolver() {
    super("searcher.oldIdUsed");
  }
}

You can't make a bunch of classes without actually writing them all, unless you use code generation tools such as Annotation Processors which is certainly possible, but I doubt that's what you're looking for here.

Related