简体   繁体   English

Symfony 2中的DDD-如何与Validator服务进行交互?

[英]DDD in Symfony 2 - How to interact with Validator service?

Some time ago I've started playing with DDD. 前一段时间,我开始玩DDD。 For now, all my classes are POPO. 现在,我所有的课程都是POPO。 Almost all is complete but I'd like to validate my entities before persistence. 几乎所有步骤都已完成,但是我想在持久化之前验证我的实体。

I already know where to put validation (commands/use case objects) but ideally I would like to use a validator service in application/infrastructure layer. 我已经知道将验证(命令/用例对象)放在哪里,但理想情况下,我想在应用程序/基础结构层中使用验证器服务。 For me, validation should be part of domain layer but if I put it there, I'll have a lot of duplication. 对我来说,验证应该是域层的一部分,但是如果我把它放在那里,我将有很多重复。

Have you encountered such problem? 你遇到过这样的问题吗? Is there any reasonable solution for that? 有什么合理的解决方案吗? Thanks for all! 谢谢大家!

Don't mix the type of validations, I know it confuses and is not easy to separate concepts and do it the right way, but don't give up. 不要混淆验证的类型,我知道它会造成混淆,并且很难以正确的方式分离概念,但不要放弃。

There are business validations which should belong to your domain and don't use any external component/framework to validate (since your domain should be the most clean and natural possible), and application validations, which should check whether a URL is valid, if user is authenticated, and you could use Symphony or whatever framework/plugin you want. 有一些业务验证应属于您的域,并且不使用任何外部组件/框架进行验证(因为您的域应该是最干净自然的),而应用程序验证应检查URL是否有效,如果用户已通过身份验证,则可以使用Symphony或所需的任何框架/插件。

Your domain should be the most natural and clean possible, in a way you could even show it to a business analyst and discuss things. 您的域应该是最自然,最整洁的域,您甚至可以将其展示给业务分析师并进行讨论。 The validations you put inside your domain should follow this concept, which means that business analyst could even point to you if that validation is correct, and suggest changes if it's the case. 您在域中进行的验证应遵循此概念,这意味着如果该验证正确,则业务分析师甚至可以指向您,并在这种情况下建议更改。 Actually where I work, sometimes even the Key Users see the Domain (code and diagrams) and point out things. 实际上,在我工作的地方,有时甚至关键用户也可以看到域(代码和图表)并指出问题。

Now suppose anyway you do want to validate whether an URL is valid inside your domain, and don't follow the Always Valid approach (which is recommended), where you would assume the application layer already validated the URL for you. 现在,无论如何,假设您确实想验证URL在您的域内是否有效,并且不遵循始终有效的方法(建议这样做),在此方法中,您将假定应用程序层已经为您验证了URL。 Instead, you do want to have a line of code inside your domain explicitly trying to validate an URL. 相反,您确实希望在域内有一行代码明确地尝试验证URL。 If this is a requirement (and I'm against, but I'm giving a possible solution for it), I'd do this: 如果这是一个要求(我反对,但我为此提供了可能的解决方案),则可以这样做:

// This would belong to your domain...
interface IValidator
{
    public function IsValidURL($url);
}

class Foo
{
    public function SaveURL($url, $validator)
    {
        if (!$validator instanceof IValidator)
            throw new Exception("Invalid validator providen to Foo!");
        if (!$validator->IsValidURL($url))
            throw new Exception("The URL $url is not valid!");
        // Do logic
    }
}

// ...and this to your Application Layer
class SymphonyValidator implements IValidator
{
    public function IsValidURL($url)
    {
        // use Symphony validator or any other framework/plugin
    }
}


var foo = new Foo();
var validator = new SymphonyValidator();
foo->SaveURL("invalidUrl", validator);

But keep in mind this is just a workaround to call a validation method inside your domain, injecting a third-party component to do the hard job. 但是请记住,这只是在域中调用验证方法的解决方案,注入第三方组件来完成这项工作。 I'm personally against this, but if someone asks you "where do you guarantee the URL is valid? I can't find it in your domain" you could do this way (I'd argue URL validation is not up to business, but to infra/app layers) 我个人反对这样做,但是如果有人问您在哪里保证URL是有效的?在您的域中找不到它”,您可以这样做(我认为URL验证不适合您,但仅限于基础/应用层)

Actually, the domain would still not guarantee the URL is valid, because the validation is still provided by the application layer (what if the Validator class always returned true?), so that's why I'm against this. 实际上,域仍然不能保证URL是有效的,因为仍然由应用程序层提供验证(如果Validator类始终返回true怎么办?),所以这就是我反对的原因。 If you need this anyway, at least if you change from symphony to any other kind of validator, your domain is kept untouched and your domain is not coupled to specific third-party libraries, and any application could provide its own Validator (since your domain can be used by may applications like web, mobile, desktop, external API calls, etc). 如果仍然需要这样做,至少是从交响乐转换为任何其他类型的验证器,您的域保持不变,并且您的域未与特定的第三方库耦合,并且任何应用程序都可以提供自己的验证器(因为您的域可供Web,移动,桌面,外部API调用等应用程序使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM