我目前正在开展一个项目,其中我有一个其他实体的BankAccount实体。
每个银行帐户作为银行实体的参考,帐号和可选的IBAN。
现在,由于可以验证IBAN,我如何确保为帐户设置IBAN时有效。什么是干净的建筑方法?我目前有一个域层,没有任何其他层的引用,我喜欢这种干净的方法(我的灵感来自Eric Evans DDD)。幸运的是,可以在不访问任何外部系统的情况下执行IBAN验证,因此在这种情况下我可以使用类似
的内容puclic class BankAccount
{
public string Iban
{
set { // validation logic here }
}
}
但是现在我在考虑如果IBAN验证需要SQL服务器检查或外部dll,我会使用什么方法。我该如何实现呢?我是否会创建一个传递给服务的IBAN值对象,该对象决定IBAN是否有效,然后将其设置为BankAccount实体? 或者我会创建一个允许实施IBAN并在之前执行验证的工厂吗?
感谢您的帮助!
答案 0 :(得分:5)
我会使用某种形式的反转控制。
具体来说,我会有一个名为IIBANValidator的界面。验证IBAN的各种方法应该实现该接口。例如:
interface IBANValidator {
Boolean Validate(string iban);
}
class SqlBanValidator : IBANValidator {
public bool Validate(string iban) {
// make the sql call to validate..
throw new NotImplementedException();
}
}
然后,我会在我的BankAccount类中有一个方法接受一个实现IIBANValidator和IBAN编号的对象,其结构类似(未经任何拉伸优化):
Boolean SetIBAN(IIBANValidator validator, String iban) {
Boolean result = false;
if (validator.Validate(iban)) {
Iban = iban;
result = true;
}
return result;
}
此时您的BankAccount类不必依赖验证器,您可以随意更换它们,最终它非常干净。
最终代码如下所示:
BankAccount account = new BankAccount();
account.SetIBAN(new SqlBanValidator(), "my iban code");
显然,在运行时,您可以传递任何您想要的验证器实例。
答案 1 :(得分:2)
而不是IBAN号码是一个简单的字符串,如果它是一个真正的类?您可以在构造函数中实现验证(如果验证没有外部依赖关系),或者您可以使用工厂提供IBAN实例(如果您需要外部验证)。重要的是,如果你有一个IBAN实例,你知道它是一个有效的IBAN号码。
BankAccount实际上是否有可变的IBAN号码?我对银行业并不十分熟悉,但这听起来像是一个可怕的想法。
答案 2 :(得分:1)
您可以为存储库实施规范,使用依赖注入。但是你会失去一点凝聚力。
可以找到更多详细信息here。
答案 3 :(得分:0)
验证逻辑的放置位置取决于执行验证所需的信息。验证应该在具有足够信息的类型中执行。另一方面,也必须考虑验证逻辑的复杂性。例如,如果您的电子邮件数据仅附加到Person类型,则它可以在人员类型中“就地”验证,因为验证并不复杂(假设只检查了电子邮件格式)并且Person是唯一的消费者。另一方面,如果您使用商店和车库(销售您的旧东西)消费类型的交易数据(以商品数据和价格数据为特征),验证逻辑表明商品必须属于交易发起人,那么将验证置于交易类型中是有意义的
答案 4 :(得分:0)
您可以使用委托进行验证,您不需要传递整个界面,谁想要设置它必须有验证器。
public delegate bool Validation(IBAN iban);
void SetIBAN(IBAN iban, Validation isValid){
if(!isValid(iban)) throw new ArgumentException();
...}
答案 5 :(得分:0)
我将面向方面并减少耦合。
[IBANVlidator(Message = "your error message. can also come from culture based resouce file.")]
public string IBAN
{
get
{
return _iban;
}
set
{
this.validate();
_iban = value;
}
}
this
然后IBAN验证责任给予IBANValidator验证属性。当然这个设计可以改进,这超出了这个答案的范围。