所以,我认为有一个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;
}
}
vs
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字段将使用DB提供的值进行更新。
答案 0 :(得分:4)
我会选择第一种方法,但只需稍加改动 - 将参数传递给ref
。 (请参阅注释。)我遇到的问题是你不必要地创建了一个额外的变量。为什么不在第一个方法中添加一些<summary>
标签,在intellisense中指出将要发生什么以澄清任何混淆?对我来说,这比创建一个额外的变量基本上做同样的事情要好。
答案 1 :(得分:1)
在第一个方法中,您只是返回参数值而没有任何改变并带有副作用。我认为它不清楚或有用。你的第二种方法似乎更有用。
编辑:基于评论。
我不认为,你的方法SaveOrUpdate
应该做这样的事情。最好返回一个值,如果出现某种异常或由于您想要做的任何意外情况,该怎么办:
playerlist = null;
在SaveOrUpdate
方法中,您不会在SavePlaylist
方法中看到对原始对象的影响。由于对象引用是通过值:)传递的。而在你的第二种方法中,它会对物体产生影响,并且会更清楚地反映出来。如果使用ref
关键字传递参数,则第一种方法会更清晰。
答案 2 :(得分:0)
也许返回布尔值会更好?如果出现问题,会有误吗?那么很容易检查返回值
答案 3 :(得分:0)
我想这更偏向于基础,重要的是选择一个模型并坚持下去。
我个人认为第二种方法是最好的。这是我的理由。
我认为第一行传达了修改对象的想法,而不是下一行
// Side effect is better understood
paylist = PlaylistDao.SaveOrUpdate(playlist);
// Side effect is not obvious unless looked into the SaveOrUpdate method.
PlaylistDao.SaveOrUpdate(playlist);
这就是为什么有些人喜欢功能语言而不是程序语言,因为功能语言不允许副作用,但强制返回修改后的值。即使您没有使用函数式语言,我认为遵循这种模式也有好处。
例如,如果您始终从方法中返回新对象,则可以进行类似。
的调用playlist.SaveOrUpdate().WriteToLog(); // Something like this.
答案 4 :(得分:-1)
第二次尝试在系统中留下两个列表。带有无效条目的播放列表和带有效条目的savedPlaylist(有效=当前)。 Ooops,当发生异常时,savedPlaylist无效且播放列表仍然有效......问题?
第一次尝试总是会让播放列表具有当前值。要么全部都保存并更新,新实例具有唯一ID等,或者没有任何更改,列表仍包含未保存的数据。
BTW:我不认为PlayList是通过引用传递的。列表实例本身不会被修改,只会修改其内容。即使实例本身会发生变化,这些变化也会在方法之外隐藏,因为方法本身仅将参数'Playlist'声明为输入。