Incomplete Library Class

Description (What)

When we use an external library for a method (e.g. Math class), somtimes the functionality offered by the class is not enough for our use case. In such cases we need to in addition to calling the library perform some actions on the output of the library to fit our use case.

How to Locate It (Where)

Look for lines of code where functions from external libraries are called and the output of those methods are modified in the same way similarly throughout the program or class.

How It Manifests (Why)

Libraries can become outdated and stay read-only, in which cases, developers themselves must extend their functionality and since the extension might be small, developers might repeatedly use the same line of code all over their program.

How to Fix It (Possible Treatments)

In Example 1, we use Foreign Method. This treatment introduces a dedicated method in which we call the library and perform the necessary additions and return the expected output for our use case. This way, we limit the scope of the external library to a single method in our program and use this method every we require the use of this library.

In Example 2, Introduce Local Extension is used. The related library exists, but the methods are not quite comprehensive due to version issues.

Developers are restricted to JDK version when they write code, hence, it is reasonable to extend the library of some version.

Other treatments are also possible based on the specific scenario, they can be found here

Examples

Example 1

Before:

Using the Math class, there is no enum for the square root of twice Pi but there is an enum for Pi.

Observed Code Smells:
- Incomplete Library Class (lines 4, 10)

After:

Applied Foreign Method to create a private method to calculate the square root of twice Pi which can be used instead of calculating it everytime.

Refactoring Applied:
- Incomplete Library Class
    - Foreign Method (sqrtTwoPi)
Observed Code Smells After Refactoring:
- None

Example 2

Before:

The BiConsumer interface from the current Java version can only take 2 parameters.

It will be better if we have a TriConsumer to take 3 parameters.

It is impossible for a developer to know every library, so this time the BiConsumer can be extended.

Observed Code Smells:
- Incomplete Library Class(line 36, line 68)

After:

The developer can extend the interface BiConsumer, overwriting the method to accept 3 parameters.


Refactoring Applied:
- Incomplete Library Class:
    - Introduce Local Extension (lines 36-37)
Observed Code Smells After Refactoring:
- None

When to Ignore

In cases where adding the required functionality by extending the library locally generates more additional work than the payoff.

More

More about Incomplete Library Class

001  class DistributionCalculator {
002   public double calculatePDF(double x, double mu, double sigma) {
003   double exponent = -0.5 * Math.pow((x - mu) / sigma, 2);
004   double normalizationConstant = 1.0 / (sigma * Math.sqrt(2 * Math.PI));
005   return normalizationConstant * Math.exp(exponent);
006   }
007  
008   public double calculateNormalDistributionPDF(double x) {
009   double exponent = -0.5 * x * x;
010   double normalizationConstant = 1.0 / (Math.sqrt(2 * Math.PI));
011   return normalizationConstant * Math.exp(exponent);
012   }
013  }
014  
015  public class ILCBE1 {
016   public static void main(String[] args) {
017   DistributionCalculator dcalc = new DistributionCalculator();
018   System.out.println(dcalc.calculatePDF(10, 4, 6));
019   System.out.println(dcalc.calculateNormalDistributionPDF(10));
020   }
021  }
022