我可以使用规范设计模式来改进以下场景吗?我很难看到如何实现它?
谢谢,
if (!string.IsNullOrEmpty(obj.Firstname) && !string.IsNullOrEmpty(obj.Lastname)
&& !string.IsNullOrEmpty(obj.Email)
&& !string.IsNullOrEmpty(obj.Username))
{
// do something
}
答案 0 :(得分:1)
当然,规范可以隐藏这个条件。但是,如果这是您的代码的唯一问题,并且仅在一个地方检查此条件,我将不会创建规范。即使重复此检查,我的第一个想法是避免处于无效状态的对象 - 即只是避免为此属性分配null
值。如果不可能,那么您可以询问用户是否有效,而不是从用户获取值并在用户之外检查它们(Tell, Don't Ask Principle):
public bool IsValid // consider better name here
{
get
{
return !String.IsNullOrEmpty(Firstname) &&
!String.IsNullOrEmpty(Lastname) &&
!String.IsNullOrEmpty(Email) &&
!String.IsNullOrEmpty(Username);
}
}
但是如果您打算创建复杂的规范,或者您计划将它们传递给您的系统(例如将规范传递给存储库以获取某些特定对象),那么这是一个好主意。
定义规范界面(如果您想要更多规范,或者如果您想要模拟它们):
public interface ISpecification<T>
{
bool IsSatisfiedBy(T value);
}
创建特定的规范(当然,名称可能更具体,如OvertimeWorkerSpecification
,它会检查工人是否有加班时间):
public class UserSpecification : ISpecification<User>
{
public bool IsSatisfiedBy(User user)
{
return !String.IsNullOrEmpty(user.Firstname) &&
!String.IsNullOrEmpty(user.Lastname) &&
!String.IsNullOrEmpty(user.Email) &&
!String.IsNullOrEmpty(user.Username);
}
}
假设用户看起来像:
public class User
{
public string Firstname { get; set; }
public string Lastname { get; set; }
public string Email { get; set; }
public string Username { get; set; }
}
用法很简单:
var spec = new UserSpecification();
// then pass your user to check if he satisfies specification
if (spec.IsSatisfiedBy(obj))
// do something
// or filter users with specification
var validUsers = users.Where(spec.IsSatisfiedBy);
另外,我建议你阅读Martin Fowler撰写的非常好的Specifications文章。