我尝试搜索和搜索这个问题,但不知怎么找不到任何相关的问题。我想知道是否有关于何时在类中使用属性以及何时不使用属性的最佳实践指南,而是使用单个方法的参数。
许多案例我都很清楚。
public class Dog
{
private name;
public setName(...) {....}
}但有时我不清楚什么更好用。例如,使用以下两种方法:
public class calculation
XYZ bla;
public calculation(XYZ something)
{
this.bla = something;
}
public void calc1()
{
// some calculations with this.bla
}
public void calc1()
{
// some more calculations with this.bla
}
public XYZ getBla()
{
return this.bla;
}
}或者也许做:
public class calculation
public calculation() {}
public static XYZ calc1(XYZ bla) // maybe static, if not dependant on other attributes/instance-variables etc
{
// some calculations with bla
return bla;
}
public static XYZ calc1() // maybe static, if not dependant on other attributes/instance-variables etc
{
// some more calculations with bla
return bla;
}
}我是说你可以为这两件案子辩护。我看到了这两种不同风格的优点和缺点,但只要不需要太多的参数/参数,我就喜欢第二种风格。当然,如果我需要更多的属性等等,那么第一个属性会更好、更简单等等,因为我不需要将这么多的参数传递给方法。
只是个个人风格的问题?或者如何决定一种方法?谢谢
编辑:一个更好的例子:我正在做很多图像处理,问题是是否将图像内部存储在对象的状态中。我目前没有这样做,因为我使用的是静态方法,并且对每个方法都使用图像本身的I:
public class ImageProcessing
{
/**
*
*/
public static Mat cannyEdges(Mat I, int low, int high)
{
// ...
return I;
}
public static Mat cannyEdges(Mat I)
{
return ImageProcessing.cannyEdges(I, ContourDetection.CANNY_LOWTHRES, ContourDetection.CANNY_HIGHTHRES);
}
/**
*
*/
public static Mat getHoughLines(Mat Edges, ...some_conf_vars...)
{
// ...
return I;
}
}然后我从外面这样称呼它,例如:
// here: read image to I...
Mat edges = ImageProcessing.cannyEdges(I, 20, 100);
Mat lines = ImageProcessing.getHoughLines(I);
// draw lines...问题是:I是否属于对象的状态?如果转换为非静态的,然后使用例如:
// here: read image to I...
ImageProcessing IP = new ImageProcessing(I);
IP.cannyEdges(20, 100); // CHANGE OF cannyEdges: Also save `edges` internally as property!?
IP.calcHoughLines(); // also save the lines internally maybe?
Mat lines = IP.getLines();
// draw lines...这样更好吗?问题再次出现:例如,我是在内部存储getHoughLines() (即lines)的结果,还是应该直接将其返回给调用者!?
发布于 2014-03-27 23:38:36
有几个原因我会选择第一个选项,即一个状态大于静态函数的对象,特别是对于复杂的计算和简单的计算。
至少那是我的2c。
第一个例子中奇怪的部分是,这些calcX方法没有提到幂等性,所以不清楚当它被操作时this.bla是什么。对于具有可选设置的复杂计算,另一种方法是使用构建器模式构造不可变对象,然后提供基于固定对象状态和参数返回结果的calcX方法。但它的适用性实际上取决于用例,所以YMMV。
Update:使用新代码,更多的OOP方法是装饰Mat。更倾向于委托而不是继承,您会得到以下内容
public class MyMat
{
private Mat i;
public MyMat(Mat i) {
this.i = i;
}
public Mat getBackingMat() {
return this.i;
}
public MyMat cannyEdges(int low, int high)
{
// ...
return new MyMat(I); // lets you chain operations
}
public MyMat cannyEdges()
{
return new MyMat(ImageProcessing.cannyEdges(I, ContourDetection.CANNY_LOWTHRES, ContourDetection.CANNY_HIGHTHRES));
}
public MyMat getHoughLines(...some_conf_vars...)
{
// ...
}
}
MyMat myMat = new MyMat(I);
lines = myMat.cannyEdges(20, 100).calcHoughLines();这只是猜测,因为我不知道这些东西是什么意思。:)
发布于 2014-03-27 23:40:03
我可以举一些例子:
public class Multiplier {
private int number;
public Multiplier(int number) {
this.number = number;
}
public int multiply(int other) {
return number * other;
}
} 这个类可以实例化如下:
Multiplier multiplyByTwo = new Multiplier(2);我可以用它将列表中的许多元素乘以2。
但我可能需要乘数对。所以下面的课可以是我所需要的:
public class Multiplier {
public static int multiply(int number, int other) {
return number * other;
}
}我可以使它是静态的,因为不需要状态。
这个示例可以在列表中这样使用:
for (int x:listOfInts) {
print(Multiplier.multiply(x * 2));
}但在这个具体的例子中,第一个例子可能更好。
for (int x:listOfInts) {
print(multiplyByTwo(x));
}或者更好地与Java 8‘映射’一起使用
如果我需要在代码中的许多点得到乘法的元素和结果,我可以这样做。
class Multiplier {
private int x;
private int y;
public int multiply() {
return x * y;
}
// getters and setters for x and y
}在最后一种情况下,我可能考虑不添加setter并在构造函数中传递x,y。
每个结构都可以在某些特定的情况下使用。
发布于 2014-03-28 00:18:50
这不完全是个人风格的问题。但是,尽管如此,我认为这个话题可能有点争议(基于意见),因此不完全适合于问答网站。
然而,显而易见的问题是:相应类的对象是否真的携带状态?也就是说,拥有由实例表示的状态有什么好处吗?如果实例的唯一目的是使用set...调用序列和对execute()方法的最后调用来修改变量的累加器,那么这样的实例通常没有真正的理由--除非避免使用带有“多”参数的静态方法。
我认为静态方法的优点超过了调用具有“多”参数的方法的潜在笨拙性。其中最重要的可能是静态方法不会增加状态空间。每个字段都是状态空间中的另一个维度,正确地记录状态空间可能很困难。静态方法执行一种更“功能”的编程风格:它们没有任何副作用,因此线程安全(这变得越来越重要)。
(注意:所有这些都是指的静态方法,而不是与任何静态状态相关的--无论如何,这些方法都应该避免。当然,这指的是没有涉及或针对任何与多态性相关的方法)。
毕竟,可以很容易地从任何地方调用任何静态方法--甚至从实例方法中调用,并将某些字段作为参数传递。相反的情况并不容易:当您想要调用依赖于许多实例字段的方法时,当您首先必须创建一个对象并适当地设置这些字段(仍然不知道它是否处于调用该方法的有效状态)时,它可能是一个麻烦。我还认为Java8的default方法是一个很好的应用程序案例,静态实用程序方法可以派上用场:default方法可以很容易地委托给实用程序方法,因为不涉及任何状态。
https://stackoverflow.com/questions/22701070
复制相似问题