class 的正确版本遵循所有 SOLID 原则
Correct version of class which follows all SOLID Priciples
我想制作一个 class 将 Activation Function
应用于一个值。 class如下
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)) ) );
}
}
其中Functions
是定义不同函数的enum
。目前只有sigmoid
个功能,以后会陆续添加
问题
我认为它违反了 Open-Closed Principle
,OOP 的 5 条 SOLID
原则之一(可能违反的更多)。那么,这个 class 的正确写法是什么以适应将来添加更多功能?
感谢任何帮助。
您可以将通用接口的实现放在枚举本身中。
像这样:
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);
}
您的 ActivationFunction
然后变得非常容易编写 - 它可能甚至不再有用。
给你的 enum
值这样的行为怎么样?
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);
}
每当您需要更多功能时,定义另一个枚举值,例如FUNC_3
。如果您需要不止一种方法 compute
添加另一种方法 compute2
.
我选择的所有名字都很愚蠢,但我希望你能明白我的意思。还是我完全错过了你问题的目标?
这是我的解决方案:
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);
}
}
您应该为新函数创建一个新的 class 并实现 Function 接口。 callFunction
参数类型 Function
,因此您在添加新函数时无需更改它并且它对于 Open-Closed Principle
是正确的。
我想制作一个 class 将 Activation Function
应用于一个值。 class如下
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)) ) );
}
}
其中Functions
是定义不同函数的enum
。目前只有sigmoid
个功能,以后会陆续添加
问题
我认为它违反了 Open-Closed Principle
,OOP 的 5 条 SOLID
原则之一(可能违反的更多)。那么,这个 class 的正确写法是什么以适应将来添加更多功能?
感谢任何帮助。
您可以将通用接口的实现放在枚举本身中。
像这样:
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);
}
您的 ActivationFunction
然后变得非常容易编写 - 它可能甚至不再有用。
给你的 enum
值这样的行为怎么样?
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);
}
每当您需要更多功能时,定义另一个枚举值,例如FUNC_3
。如果您需要不止一种方法 compute
添加另一种方法 compute2
.
我选择的所有名字都很愚蠢,但我希望你能明白我的意思。还是我完全错过了你问题的目标?
这是我的解决方案:
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);
}
}
您应该为新函数创建一个新的 class 并实现 Function 接口。 callFunction
参数类型 Function
,因此您在添加新函数时无需更改它并且它对于 Open-Closed Principle
是正确的。