3

所以,我认为有一个不返回刚刚成功保存的实体的 Save 方法有点奇怪。但是,传递给 Save 的实体会被函数修改。

例子:

//T SaveOrUpdate(T entity); from IDao
PlaylistDao.SaveOrUpdate(playlist);

该函数获取一个播放列表,将其保存到数据库中,然后返回保存的播放列表。但是,传递给 SaveOrUpdate 的参数是引用等于它的返回值。

考虑到这一点,这是一个更清晰的实现:

public void SavePlaylist(Playlist playlist)
{
    try
    {
        NHibernateSessionManager.Instance.BeginTransaction();
        PlaylistDao.SaveOrUpdate(playlist);
        NHibernateSessionManager.Instance.CommitTransaction();
    }
    catch (Exception exception)
    {
        Logger.Error(exception);
        throw;
    }
}

对比

public Playlist SavePlaylist(Playlist playlist)
{
    Playlist savedPlayist;
    try
    {
        NHibernateSessionManager.Instance.BeginTransaction();
        savedPlayist = PlaylistDao.SaveOrUpdate(playlist);
        NHibernateSessionManager.Instance.CommitTransaction();
    }
    catch (Exception exception)
    {
        Logger.Error(exception);
        throw;
    }

    return savedPlayist;
}

我认为第二个功能对于以前没有看过代码的人来说更清楚,但是一旦开发人员理解,第一个实现会更简洁明了。有什么想法吗?

更新:需要明确的是,SaveOrUpdate 对播放列表有副作用。当播放列表保存到数据库时,其 ID 字段将更新为数据库提供的值。

4

5 回答 5

4

我会选择第一种方法,但要稍作改动——将参数传递给ref. (请参阅评论。)第二个问题是您不必要地创建了一个额外的变量。为什么不直接<summary>在第一种方法中添加一些标签,以智能方式指示将要发生的事情以澄清任何混淆?对我来说,这比创建一个额外的变量来做同样的事情要好。

于 2012-12-05T06:34:50.213 回答
1

在第一个方法中,您只是简单地返回参数值,而没有任何副作用。我认为它既不清晰也不有用。您的第二种方法似乎更有用。

编辑:根据评论。

我不认为,你的方法SaveOrUpdate应该做这样的事情。最好返回一个值,如果出现一些异常或由于您想要做的任何意外情况怎么办:

playerlist = null;

在您的SaveOrUpdate方法中,您不会在方法中看到对原始对象的影响SavePlaylist。由于对象引用是按值传递的:)。而在您的第二种方法中,它将对对象产生影响,并且会更清楚地反映出来。ref如果您使用关键字传递参数,您的第一种方法会更清楚。

于 2012-12-05T06:34:10.573 回答
1

我想这是基于偏好的,重要的是选择一个模型并坚持下去。

我个人的意见是第二种方法是最好的。以下是我的理由。

  • Save 方法有副作用,即它改变了传递给它的对象。即使这些更改可以通过对象引用返回给调用者,但阅读您的代码的人可能无法完全看到这些更改,而无需实际查看 save 方法。

我认为第一行比下一行传达了修改对象的想法

// Side effect is better understood
paylist = PlaylistDao.SaveOrUpdate(playlist);

// Side effect is not obvious unless looked into the SaveOrUpdate method.
PlaylistDao.SaveOrUpdate(playlist);

这就是为什么有些人更喜欢函数式语言而不是过程式语言的原因,因为函数式语言不允许副作用,而是强制返回修改后的值。即使您没有使用函数式语言,我认为遵循该模式也有好处。

  • 其他原因是,返回修改后的值允许您构建更易于使用的流畅 API,(仅当您向 Playlist 类添加方法时,这不适用于 DAO 上的 SaveOrUpdate 方法) .

例如,如果你总是从你的方法返回新对象,你可以有类似的调用。

playlist.SaveOrUpdate().WriteToLog(); // Something like this.
于 2012-12-05T06:52:49.453 回答
0

也许返回布尔值会更好?如果出现问题,则为假?那么很容易检查返回值

于 2012-12-05T06:36:24.033 回答
-1

第二次尝试在系统中留下两个列表。具有无效条目的播放列表和具有有效条目的已保存播放列表(有效 = 当前)。哎呀,发生异常时,已保存的播放列表无效,播放列表仍然有效... 得到问题了吗?

第一次尝试总是使播放列表具有当前值。要么全部保存和更新,新实例具有唯一 ID 等,要么没有任何更改,列表仍然包含未保存的数据。

顺便说一句:我不认为播放列表是通过引用传递的。列表实例本身没有被修改,只有它的内容。即使实例本身会发生变化,这些变化在方法之外也是不可见的,因为方法本身将参数“播放列表”声明为仅输入。

于 2012-12-05T06:55:41.690 回答