假设我有一个具有 Update(user) 和 Add(user) 的 DatabaseService 类。我的问题是如何以一种方法同时使用它们。这是一个好习惯吗?更具体地说,它是否违反了单一性规则(即单一责任)?例如,如果我有一个像这样的妈妈
public void AddOrUpdateUser(User user)
{
var userFound = GetUserById(user.Id);
if (userFound == null)
{
AddUser(user);
}
else
{
UpdateUser(user);
}
}
Run Code Online (Sandbox Code Playgroud)
这是个好主意吗?或者它会很糟糕,因为它打破了奇点规则,所以让消费者阶层决定做什么?
这种工作方式很常见。如果给定用户它尚未被持久化,它将被创建,否则,它将被更新。
Id顺便说一句,我会通过以下方式更改获取可能用户的部分:
public interface IPersistable
{
bool IsNew { get; }
}
public class User : IPersistable
{
public int Id { get; set; };
public bool IsNew => Id == 0;
}
Run Code Online (Sandbox Code Playgroud)
进而:
IPersistable persistable = user as IPersistable;
Contract.Assert(persistable != null);
if(persistable.IsNew)
{
// Create
}
else
{
// Update
}
Run Code Online (Sandbox Code Playgroud)
由于我们将此方法称为AddOrUpdateOP 在我的回答的一些评论中表示这可能会打破单一责任原则。
我确实相信这种担忧来自方法标识符,而不是该方法的实际用途。
整个方法负责持久化对象,从消费者的角度来看,这是一个单一的责任:我希望你负责持久化我的对象。
无论它是否已经在底层存储上,它仍然保留一个对象。我们可以将此方法重命名为Persist,Save或其他任何名称,但是AddOrUpdate,至少为该操作提供了更多语义,并且它遵循另一个非官方(但广泛接受)的原则:自记录代码(您只需阅读代码即可了解代码的作用本身)。
因此,如果它还会删除对象或任何其他可以由另一个动词表示的不相关操作,那么它似乎会违反单一责任原则。