Reputation: 1699
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
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
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
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