Java 正在将对象本身(this)传递给字段';什么方法不好?

Java 正在将对象本身(this)传递给字段';什么方法不好?,java,oop,Java,Oop,我正在编写一个小游戏,我有两门课:Board和Piece电路板目前有一个块,可以在电路板的边框中移动 public class Board { private Piece piece_; private int width, height; ... movePieceDown() { piece_.moveTo(this, 1, 2); } } public class Piece { public boolean moveTo(Board board, in

我正在编写一个小游戏,我有两门课:
Board
Piece
电路板
目前有一个
,可以在
电路板
的边框中移动

public class Board {
  private Piece piece_;
  private int width, height;
  ...

  movePieceDown() {
    piece_.moveTo(this, 1, 2);
  }
}

public class Piece {
  public boolean moveTo(Board board, int x, int y) {
    // move piece to new location (x,y)
    // return true if successful
  }
}
如果我在
piece.moveTo(这个,1,2)中,这是一个糟糕的方法吗将参考传递到板上,以便在板上没有障碍物时工件可以移动到新位置?若不将参考传递给电路板,工件就不知道新位置上是否有障碍物,或者是否超出电路板边界

在我看来,每个对象都应该只关注自身:工件应该移动到新位置,而电路板应该关注是否合法移动,但我发布的这个示例代码更有意义,并且简化了事情


TL;DR:我把对象本身传递给一个字段的方法,这是违反了OOP准则,还是某种普通的OOP习惯用法?提前感谢您向我澄清这一点。

这是一个不错的方法。将此
传递给各种方法在编程中并不少见。这取决于你的设计,就我而言,
Piece
类中没有任何内容

Board
类中的一件事可能会让人困惑-
movePieceDown
方法。您有不可用的参数
线路板
。如果您计划使用
作为参数,请删除该属性,因为该板不应接收其他板作为潜在参数,事实上,不应意识到其他板可能存在

最后,您可以确保
Piece
Board
的接口视为方法参数,并确保该契约永远不会更改。例如,它可以有以下方法:

public interface IBoard { 
    public boolean isFieldFree(int x, int y)
    public Piece getPiece(int x, int y) 
}

无论您以后如何更改电路板的实现,这都应该始终有效,这样您就不必在更改
电路板时重新编写
代码。通过这种方式,您可以强制执行一条规则,即
不能更改电路板的状态(在界面中,不要公开任何更改电路板状态的方法)。

我认为这是一种很好的策略,尤其是当您需要将一组局部变量传递给一个方法时。与其传递所有这些局部变量,不如传递对象的实例来整理方法签名


只需确保实践良好的封装,以便接收此参数的方法不会修改字段或调用具有受限访问权限的方法。

首先,为什么您的piece变量以下划线结尾?这很奇怪:p

至于你的问题。我会处理所有与片段相关的事情,比如在片段类中移动。如果你想知道你在板上的位置,我会在你的piece类中有两个整数变量,叫做x和y

该块不必知道它是否会与板上的其他块碰撞,因为这是您的板类在移动块时应该处理的事情

例如,如果你把你的棋子移动到x=1和y=2,你应该让你的棋盘检查在位置1,2是否已经有一个棋子,并做出相应的反应

将“this”传递给另一个类的方法没有错,但是从松散耦合的面向对象编程的角度来看,它不是最佳设计


就我的2美分:)

一般来说,通过
这个
并不少见,但这取决于具体情况。在这种情况下,它是否是上帝取决于实现细节。一块
电路板
有几个可以移动的管道,因此位置是一块电路板的属性。然而,将工件从一个位置移动到另一个位置可能是电路板的一项功能。例如,如果新位置已被占用,会发生什么情况?然后这一块会移动其他块吗?这是否适合您的设计


根据您在工件上的签名,我希望moveTo函数接受一块板,这向我表明工件可以从一块板移动到另一块板。在阅读代码时,这可能是误读,除非情况确实如此。

我不确定这样做是否会阻止任何面向对象编程规则,但它看起来确实很奇怪,因为您正在
板上调用一个方法
,然后该方法所做的唯一事情就是调用
工件上的一个方法
将其自身作为参数传递

面向对象编程就是将事物视为现实世界中的对象。按照这种方法,我会将其视为一块在板上,例如,它的位置由板决定,而不是由板本身决定。从这种方法来看,移动工件是在电路板上完成的,而不是工件本身

因此,即使将
作为参数传递并不是错误的,我还是希望定义方法:

public class Board
{
    private Piece p;
    // ...

    public boolean movePieceDown()
    {
        // Move the piece to a new location using it's setters
    }
}

除此之外,由于
对象知道它的属性,因此生成的代码将更具可读性,因为您不必调用太多的getter和setter(例如检查边界)。

只回答标题中的特定问题(而不是关于OO设计的一般意见):不,这不是不好的做法,但相当普遍


但是,请注意,不建议在构造函数中将
这个
传递给外部世界,因为它可能会在并发场景中导致严重的错误,在这种场景中,接收方可能会看到源处于不一致的状态。

这是通过正常的方法调用隐式传递的。阅读我在论坛上找到的这篇文章


你也可以阅读这篇文章。

你为什么要把
传给movePieceDown?是的,打得好,很抱歉,我在发布代码的时候打错了。现在将进行编辑。感谢您的回答darijan,以及来自克罗地亚的问候:)。是的,那是我山姆的错别字