"类不应该在其构造函数中执行涉及依赖项的工作."

dev*_*ium 12 c# java oop dependency-injection

因此,引用来自".NET中的依赖注入".考虑到这一点,下面的类是错误设计的吗?

class FallingPiece { //depicts the current falling piece in a tetris game
    private readonly IPieceGenerator pieceGenerator;
    private IPiece currentPiece;

    public FallingPiece(IPieceGenerator pieceGenerator) {
        this.pieceGenerator = pieceGenerator;
        this.currentPiece = pieceGenerator.Generate(); //I'm performing work in the constructor with a dependency!
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

所以这个FallingPiece班级有责任在俄罗斯方块游戏中控制当前掉落的棋子.当这件作品撞到底部或其他地方时,会发出一个事件信号,然后通过工厂生成另一个从上面再次开始下落的新件.

我看到的唯一替代方法是使用Initialize()方法生成该块,但IMO有点违背了让构造函数将对象置于有效状态的想法.

Jul*_*iet 15

一般来说,拇指规则就是:经验法则.不应该永远偏离的不可改变的法则 - 我很确定你会发现在构造函数中使用依赖项做事情比其他情况更有意义的情况.

考虑到这一点,让我们重新审视您的特定设计:

所以这个FallingPiece类负责控制俄罗斯方块游戏中当前掉落的棋子.当这件作品撞到底部或其他地方时,会发出一个事件信号,然后通过工厂生成另一个从上面再次开始下落的新件.

对我来说似乎很奇怪,FallingPiece它在完成后会触发片段生成器.

我的设计是这样的:

class PieceGenerator
{
    public FallingPiece NextFallingPiece()
    {
        FallingPiece piece = new FallingPiece(NextPiece());
        return piece;
    }
    // ...
}

class GameEngine
{
    public PieceGenerator pieceGenerator = new PieceGenerator();

    public void Start()
    {
        CreateFallingPiece();
    }

    void CreateFallingPiece()
    {
        FallingPiece piece = pieceGenerator.NextFallingPiece();
        piece.OnStop += piece_OnStop;
        piece.StartFalling();
    }

    void piece_OnStop(FallingPiece piece)
    {
        piece.OnStop -= piece_OnStop;
        if (!GameOver())
            CreateFallingPiece();
    }
}
Run Code Online (Sandbox Code Playgroud)

至少在这种设计中,GameEngine它完全有责任告诉发电机何时创造它的碎片,这似乎比具有该任务的FallingPiece更惯用.


Col*_*inD 5

是的,我会说某些东西不是那里设计的.很难说,因为你没有展示如何FallingPiece使用它或它如何适应系统,但它对我来说没有意义,为什么它需要currentPiece在它的构造函数中得到它.

由于它看起来currentPiece可以随着时间的推移而改变,看起来你正在使用单个实例FallingPiece作为当前下降的单件容器.在这种情况下,你必须以某种方式得到第二个,第三个等等.为什么不简单地为第一件做同样的事情呢?

你说当一件作品击中底部时,会发出一个事件,触发新作品的生成开始下降.难道你不应该自己解雇这个事件来开始第一件事吗?

一般来说:

不应该在构造函数中完成使用依赖项的一般原因(我认为),对象的构造应该纯粹是关于设置类以便能够执行它需要做的事情.让类实际完成他们所做的事情应该通过在创建对象的API之后调用来完成.在这种情况下FallingPiece,一旦它具有IPieceGenerator它能够做它需要做的一切.实际上这样做(开始下降)应该通过调用其API上的方法或(如此处似乎是这种情况)触发它将响应的事件来完成.