首页 新闻 会员 周边 捐助

类这样设计合理吗

0
[已解决问题] 解决于 2011-12-09 10:11

假设我需要一个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);

好像太别扭了。

太我也没有好的方法,请大家帮帮忙

leon_ALiang的主页 leon_ALiang | 初学一级 | 园豆:194
提问于:2011-12-07 17:45
< >
分享
最佳答案
1

不是很明白你的需求,为了做一个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(); 
胡屯 | 小虾三级 |园豆:714 | 2011-12-08 09:46

user.Validator.ValidateValue(user);
这句怎么理解?

Validator是user实例的一个成员,这个成员里有一个方法可以访问整个user实例。

这样不存在耦合的问题吗?

leon_ALiang | 园豆:194 (初学一级) | 2011-12-08 13:33

@leon032: 就对消除耦合是不可能的。

这里User 和 IValidate 抽闲接口耦合,相对于User和Validator 的耦合松一些。

如果需要的话,可以把User也抽象成为一个抽象来AbstractUser,让User集成自AbstractUser。

同时IValidate 宜组合的方式和AbstractUser进行耦合,这样User 和 Validator 就完全松耦合了。

但是这要结合你的需求而定,如果你认为没有那个必要,适当的耦合也是可以接受的。

胡屯 | 园豆:714 (小虾三级) | 2011-12-08 15:14

@胡屯: 非常感谢。
我一直认为不管是这接口或抽象类中都算耦合,如两个接口之间。
比方说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之间有耦合,对吧?

leon_ALiang | 园豆:194 (初学一级) | 2011-12-08 18:09

@leon032: 耦合度消减到相对很小了,是一个比较好的设计。

胡屯 | 园豆:714 (小虾三级) | 2011-12-09 08:41
其他回答(5)
0

你可以创建一个IValidator 接口,在用User 类实现这个接口。这样就优雅一点了。并且可以做一个通用的验证方法了。

小小刀 | 园豆:1991 (小虾三级) | 2011-12-07 19:23

恩。这样好。谢谢
还有没有别的思路呢?

支持(0) 反对(0) leon_ALiang | 园豆:194 (初学一级) | 2011-12-07 21:12
0

在验证函数里,对于用户实体的没一个属性,你还是要一个一个的验证

dreamhappy | 园豆:4 (初学一级) | 2011-12-07 19:58
0

你还不如直接在user类中定义一个valitdator方法来验证

如:

User user=new User();

user.validator();

李.net | 园豆:730 (小虾三级) | 2011-12-08 08:38
0

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; }
}
水牛刀刀 | 园豆:6350 (大侠五级) | 2011-12-08 10:17
0

创建一个属性:

 [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;
}


 

Jimson.Ma | 园豆:225 (菜鸟二级) | 2011-12-08 11:14
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册