Waqas Ahmed Ansari
Waqas Ahmed Ansari

Reputation: 1699

Correct version of class which follows all SOLID Priciples

I want to make a class which applies Activation Function to a value. The class is as follows

public class ActivationFunction {

    public static double function(double value, Functions functions) {
        if(functions.equals(Functions.SIGMOID)) {
            return sigmoid(value);
        }
        return 0f;
    }
    public static double derivativeOfFunction(double value, Functions functions) {
        if(functions.equals(Functions.SIGMOID))
            return sigmoidDerivative(value);

        return 0f;
    }

    private static double sigmoid(double value) {
        return 1 / (1 + Math.exp(0 - value));
    }
    private static double sigmoidDerivative(double value) {
        return ( Math.exp(0 - value) / ( (1 + Math.exp(0 - value)) * (1 + Math.exp(0 - value)) ) );
    }

}

Where Functions is the enum in which different functions are defined. There is only sigmoid function now, but more will be added.

QUESTION

I thing it's violating the Open-Closed Principle, one of the 5 SOLID Principles of OOP (may be it's violating more). So, what is the correct way to write this class to accommodate addition of more functions in future?

Any help is appreciated.

Upvotes: 0

Views: 102

Answers (3)

Arif Ulusoy
Arif Ulusoy

Reputation: 244

Here is my solution:

public interface Function {
    double doIt(double value);
}

public class Sigmoid implements Function {
    @Override
    public double doIt(double value) {
        return 0;
    }
}

public class ActivationFunction {
    public static double callFunction(Function function,double value){
        return function.doIt(value);
    }
}

You should create a new class for new functions and implement Function interface. callFunction argument type Function , so you will not need to change it when you add a new function and it is correct for Open-Closed Principle.

Upvotes: 0

Harmlezz
Harmlezz

Reputation: 8078

How about giving your enum values behavior like this?

enum MyFunctions {
    FUNC_1 {
        @Override double compute(double value) {
            return 1 / (1 + Math.exp(0 - value));
        }
    },

    FUNC_2 {
        @Override double compute(double value) {
            return ( Math.exp(0 - value) / ( (1 + Math.exp(0 - value)) * (1 + Math.exp(0 - value)) ) );
        }
    };

    abstract double compute(double value);
}

Whenever you need more functions, define another enum value, like FUNC_3. If you need more than the one method compute add another method compute2.

All the names I selected are silly but I hope you get the point. Or did I missed the target of your question completely?

Upvotes: 0

assylias
assylias

Reputation: 328785

You could place the implementation of the common interface in the enum itself.

Something like this:

public enum Functions {
  SIGMOID {
    public double function(double value) { return 1 / (1 + Math.exp(0 - value)); }
    public double derivative(double value) { return ...; }
  },
  OTHER_FUNCTIONS { ... }

  public abstract double function(double value);
  public abstract double derivative(double value);
}

Your ActivationFunction then becomes very simple to write - it's probably not even useful any more.

Upvotes: 2

Related Questions