>我尝试遵循名义工作流程并捕获我的模型和服务抛出的异常:唯一/外部约束违规,空字段,无效参数等…(!!我只捕获我知道应该的异常)
>专业人员:在我的控制器和服务中编写的代码非常少:我只需处理异常并将其转录为用户可理解的消息.代码非常简单易读.
>缺点:我需要编写特定的异常,有时可能会有很多不同的异常.我还需要捕获并解析数据库异常(约束违规等等)的泛型PDO / Doctrine异常,以将它们转换为有意义的异常(例如:DuplicateEntryException).我也无法绕过一些验证:假设我的模型的一个对象被标记为已锁定:尝试删除它会引发异常.但是我可能想强制删除它(例如使用确认弹出窗口).我不能在这里绕过这个例外.
>我使用代码和数据库查询显式测试和预验证所有内容.例如,我将测试某些东西不是null,并且在将其设置为模型中的属性之前是一个整数.或者我将进行数据库查询以检查我是否不会创建重复的条目.
>专业人士:不需要编写特定的异常,因为我预先验证了所有内容,所以我不应该做很多try / catch.如果我愿意,我也可以绕过一些验证.
>缺点:在控制器,服务和模型中编写大量测试和验证.我将执行更多查询(验证部分).数据库已经对外键,唯一约束,而不是空列进行了验证……我不应该忽略它并自己重新编码.这也导致非常无聊的代码!
我宁愿使用一种模式或另一种模式,而不是混合模式,以使事情尽可能简单.
第一个解决方案在我看来是最好的,但我担心它可能是某种反模式?或者可能在其理论简单性背后隐藏着难以处理的情况?
此外,模型期望并不总是与特定界面建立的期望完全一致(可能表格只显示潜在选项的子集,或者界面可能是美国各州的下拉,而模型存储来自许多国家有时复杂的接口可以以增强用户体验的方式集成多个不同的模型对象.虽然对用户很好,但是使用异常方法的这些模型的交互可能非常难以处理,因为一些输入可能是混合输入,两种模型都不能单独验证.您总是希望确保验证首先符合UI的期望,而第二种方法允许您在最复杂的界面中执行此操作.
而且,异常处理在周期方面相对昂贵.验证问题可能非常频繁,我会尽量避免处理问题这么昂贵的操作,而不是频繁发生.
最后,一些验证对于模型来说并不是必需的,但它可以防止攻击.虽然您可以将其添加到模型中,但添加的功能可能会使模型代码快速混乱.
>您可以为您的应用创建一个清晰的边界.>所有验证都在一个地方,可以共享.>如果两个或更多模型使用相同的输入,则不会重复验证.>模型可以专注于他们擅长的领域:将抽象实体的知识映射到应用程序状态.>即使是最复杂的UI也可以进行适当的验证.>抢占可能会更有效率.>不能真正属于任何模型的以安全为中心的验证任务可以干净地添加到应用程序中.