【问题标题】:Which Design Pattern To Use For Validation [closed]用于验证的设计模式 [关闭]
【发布时间】:2013-08-19 13:08:08
【问题描述】:

我确信我不是唯一一个面临这个问题的人,但直到现在我都无法找到解决方案。问题如下。

我已经从旧系统发布了一个 Web 服务(我没有任何控制权,也无法更改它),并且所有客户端都在使用它。我收到来自 Web 服务的请求,而我得到的对象是一个非常复杂的请求,但为了举例,假设我从 Web 服务调用中接收到对象 A,其中包含其他几个对象,如对象 B、对象 C 等此外,对象 B 和 C 也有一些原始数据类型以及其中的一些其他对象。我的问题是我想验证整个对象 A(所有包括对象和子对象),这里推荐哪种设计模式?其次,这里的重点是我可以从 Web 服务中获取不同类型的 Object A。我所说的不同类型的对象 A 的真正意思是对象 A 取决于客户端,即某些客户端将发送对象 A 而不将数据填充到包含对象 B 中,甚至他们可以部分填充对象 B,然后将其发送到对象 A .所以我必须根据客户端验证对象A(因为有些客户端需要包含对象B,有些则不需要,有些需要对象B中的少量元素等)。所以换句话说,我将有一个地方存储每个客户端的验证规则,这将告诉我客户端 ABC 希望对象 B 中的字段 abc 为字符串类型,最大长度为 25 个字符,它必须在该字段中包含数据。

我想要执行的一些验证是

检查某些对象(比如对象 B)的字段的数据类型、特定字段的长度、是此客户端所需的字段还是可选的字段等...

任何具体的工作示例都将非常有用。

此特定示例的对象 A 的结构如下。

    public class A
    {
        private B objectB;
        private C objectC;
        // and so on
    }

    public class B{
        private E objectE;
        private String name;
        private int age;
        // and so on
    } 

    public class C
    {
        private F objectF;
        private String address;
        private String country;
    }

    public class E
    {
        // Members here
    }

    public class F
    {
        // Members here
    }

P.S:我给类和成员起任意名称只是为了一般理解。哦,是的,我忘了提到我在这里使用的是 java,但这并不重要,因为设计原则或模式可以应用于任何语言。希望尽快收到你们的来信.. :)

【问题讨论】:

  • 验证可以通过多种方式完成,并且非常基于意见。看看Strategy pattern。
  • 您能推荐除策略模式以外的任何替代方案吗?
  • 我建议你使用Visitor和Factory/AbstractFactory的组合。 Factory 可以使用特殊规则按客户端类型创建任何验证器类。访客车使用验证器类验证整个结构

标签: validation design-patterns


【解决方案1】:

验证是一个交叉问题。有几种方法和几种设计模式可以实现。

在 Asp.net 中它是通过属性完成的,在 Java Spring 中它是通过 Annotations 完成的,以保持代码干净、可读和可维护。

您可以找到大量不同的方法,您需要记住的是这些框架遵循的方法。即代码维护、可读性和干净的代码。

没有灵丹妙药。您甚至可以在代码中编写验证。

【讨论】:

  • 你在这里提到了一个很好的观点(我完全忘记了)验证是一个交叉问题。感谢那。如果我在我的业务对象或任何对象中编写验证代码,它不会使代码混乱吗?我觉得会违反单一职责原则,你说呢?
  • 是的,确实如此,这就是为什么验证是一个横切关注点,就像日志记录一样,有时你无法避免它。您需要注意的是您的代码的正确性、干净、可读、不重复和可维护。
  • 你能给我推荐一个策略模式以外的设计模式吗?我正在尽最大努力保持我的代码干净、可读、可维护,并且我也遵循 DRY 原则,但我认为我已经到了必须动手的地步……:)
  • 你可以使用装饰器模式。 Asp.net 和 java 框架使用装饰器模式进行验证。
【解决方案2】:

每个类都应该知道如何验证自己。您可以从具有 .Validate() 方法的接口(例如 IValidatable)派生每个类。当您在对象 A 上调用 .Validate() 时,让它自己验证,然后在所有子对象上调用 .Validate()。这些孩子可以以类似的方式验证自己。

我认为这是命令模式的一个非常简单的版本。有点。

您还可以编写一个可以附加到您的班级的验证器。验证器可以知道如何验证电子邮件地址、常规地址等。这更具可扩展性,因为您基本上是在创建一个工具箱来附加到您的类中,该工具箱只包含它需要的工具。

【讨论】:

  • 是的,最初我认为每个类都将负责自己的验证,但我认为这样做会违反这一单一责任原则,此外实际代码可能会与业务杂乱无章代码。对此有什么想法吗?
  • 简短回答:视情况而定。如果您使用领域驱动设计,您可以验证设置器上的所有属性 - 如果您担心单一责任,那肯定是一种安全的方法。我认为通过使用验证器策略场景,您仍然是安全的。验证者负责验证。它恰好被它验证的对象引用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多