假设我需要一个User类,里面有一些user的信息,同时还需要验证这些信息(必须要验证),所以在user类里还有一个验证的成员。同时我定义了一个验证类Validator,里面有个验证方法,如下
public class User
{
private int age;
private string name;
private Validator validator;
}
public class Validator
{
bool ValidateValue(User user)
{
return true;
}
}
ValidateValue方法传递了一个user参数,总觉得很别扭。而user又要求必须验证,所以加了validator成员。这样用这个方法的时候:
User user=new User();
user.validator.ValidateValue(user);
好像太别扭了。
太我也没有好的方法,请大家帮帮忙
不是很明白你的需求,为了做一个check操作另外定义一个类?
不过从软件设计角度考虑,你的代码存在一些瑕疵。
1, User和Validator类紧耦合了,如果有需求要新增ValidateValue方法实现怎么办?
2, user.validator.ValidateValue(user); 是编译通不过的,因为validator是private;
以下是按照你的思路修改后的代码,未经验证,仅供参考:
public interface IValidate
{
bool ValidateValue(User user);
}
public class DefaultValidator : IValidate
{
bool IValidate.ValidateValue(User user)
{
return true;
}
}
public class User
{
private int age;
private string name;
private IValidate validator = new DefaultValidator() ;
public IValidate Validator
{
get { return this.validator; }
set { this.validator = value; }
}
public ValidateValue()
{
return this.validator.ValidateValue(this);
}
}
//调用过程
User user=new User();
user.ValidateValue();
或者
user.Validator.ValidateValue(user);
若果需要切换新的ValidateValue实现,可以定义一个新的继承IValidate接口的Validator类,灵活扩展
比如
public class NewValidator : IValidate
user.Validator = new NewValidator();
user.ValidateValue();
user.Validator.ValidateValue(user);
这句怎么理解?
Validator是user实例的一个成员,这个成员里有一个方法可以访问整个user实例。
这样不存在耦合的问题吗?
@leon032: 就对消除耦合是不可能的。
这里User 和 IValidate 抽闲接口耦合,相对于User和Validator 的耦合松一些。
如果需要的话,可以把User也抽象成为一个抽象来AbstractUser,让User集成自AbstractUser。
同时IValidate 宜组合的方式和AbstractUser进行耦合,这样User 和 Validator 就完全松耦合了。
但是这要结合你的需求而定,如果你认为没有那个必要,适当的耦合也是可以接受的。
@胡屯: 非常感谢。
我一直认为不管是这接口或抽象类中都算耦合,如两个接口之间。
比方说IA和IB接口直接存在耦合。
interface IA
{
string info{get;}
}
interface IB
{
void Validate(IA a);
}
这样两个接口之间存在耦合
实现IB:
public class B : IB
{
public void Validate(IA a)
{}
}
这样的话不认为A和B之间有耦合,对吧?
@leon032: 耦合度消减到相对很小了,是一个比较好的设计。
你可以创建一个IValidator 接口,在用User 类实现这个接口。这样就优雅一点了。并且可以做一个通用的验证方法了。
恩。这样好。谢谢
还有没有别的思路呢?
在验证函数里,对于用户实体的没一个属性,你还是要一个一个的验证
你还不如直接在user类中定义一个valitdator方法来验证
如:
User user=new User();
user.validator();
User和Validator高度耦合肯定是不正确的。你的问题里提出“同时还需要验证这些信息(必须要验证)”,我这里假设你是要保存到数据库的时候验证合法性,那么比较好的一个设计是:
public class User
{
public long ID { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
public class UserManager
{
public void Create(User user)
{
//这里用一个工厂方法获取validator,你可以为此加上缓存
//或者用IoC使它更便于扩展
ValidatorProvider.GetValidator<User>();
//验证通过后save to db
}
}
//当你的验证逻辑比较复杂
//或者说你有其他某个类比如Company也需要验证
//你应当把验证的信息标注到类中去
//在工厂中获取的validator通过元数据进行验证
//这样所有的validator的逻辑可以用同一段代码实现
public class User
{
public long ID { get; set; }
[Length(2,4)]
public string Name { get; set; }
[Range(0,150)]
public int Age { get; set; }
}
创建一个属性:
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class)]
public class ValidateAttribute : ValidationAttribute
{
public ValidAliasAttribute() : base() { }
public override bool IsValid(object value)
{
return true;
}
}
[Validate]
public class User
{
private int age;
private string name;
}