Java:何时使用属性,何时使用方法参数?

tim*_*tim 5 java oop api-design class

我尝试谷歌搜索并搜索这个问题,但不知何故找不到任何相关的信息。我想知道是否有关于何时在类中使用属​​性以及何时不使用的最佳实践指南,而是使用单个方法的参数。

许多情况对我来说很清楚,例如

public class Dog
{
 private name;
 public setName(...) {....}
}
Run Code Online (Sandbox Code Playgroud)

但有时我不清楚使用什么更好。例如以下,要么使用:

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;
  }
}
Run Code Online (Sandbox Code Playgroud)

或者也许这样做:

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;
  }
}
Run Code Online (Sandbox Code Playgroud)

我的意思是你可以为这两种情况争论。我看到了两种不同风格的优点和缺点,但不知何故,只要不需要太多参数/参数,我更喜欢第二种。当然,如果我需要更多的属性等等,那么第一个会更好,更简单等等,因为我不需要向方法传递这么多参数......

只是个人风格的问题?或者如何决定一种方法?谢谢


编辑:一个更好的例子:我目前正在做很多图像处理,问题是是否在对象的状态下在内部存储图像。我目前没有这样做,因为我使用的是静态方法,并将图像本身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;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我像这样从外面调用它,例如:

// here: read image to I...
Mat edges = ImageProcessing.cannyEdges(I, 20, 100);
Mat lines = ImageProcessing.getHoughLines(I);

// draw lines...
Run Code Online (Sandbox Code Playgroud)

问题是:是否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...
Run Code Online (Sandbox Code Playgroud)

这更好吗?再次出现的问题是:例如,我应该getHoughLines()lines内部存储(即)的结果还是应该直接将其返回给调用者!?

Eme*_*gia 1

我选择第一个选项有几个原因,即具有静态函数状态的对象,特别是对于复杂的计算,但也适用于更简单的计算。

  1. 对象更适合命令模式。
  2. 对象更适合策略模式。
  3. 静态方法可以使单元测试变成一场噩梦。
  4. 静态是 OOP 中的反模式,因为它破坏了多态性,相关技术也会破坏它的副作用,例如开放/封闭、模拟、代理等。

至少这是我的2c。

第一个示例的奇怪部分是这些calcX方法没有说明幂等性的任何内容,因此不清楚this.bla它被操纵时是什么。对于具有可选设置的复杂计算,另一种方法是使用构建器模式构造不可变对象,然后提供calcX基于固定对象状态和参数返回结果的方法。但它的适用性实际上取决于用例,所以 YMMV。

更新:对于您的新代码,更多的 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();
Run Code Online (Sandbox Code Playgroud)

这只是一个猜测,因为我不知道这些东西意味着什么。:)