【问题标题】:Is this an existing design pattern or not?这是否是现有的设计模式?
【发布时间】:2012-02-09 13:19:31
【问题描述】:

在我的公司,我们有一个基于这种模式的项目。我想知道这是一种现有的和公认的设计模式,还是各种模式的组合,或者只是解决问题的一种方便的编码解决方案。

interface IService <TRequest, TResponse>
    where TRequest : IRequest, TResponse : IResponse
{
     TResponse ProcessRequest(TRequest request);
}

public class ConcreteService : IService<ConcreteRequest, ConcreteResponse>
{
    public ConcreteResponse ProcessRequest(ConcreteRequest request)
    {
        // Do some stuff to create the ConcreteResponse object
    }
}

然后在 Web 服务操作中:

[WebMethod]
public ConcreteResponse SomeService(ConcreteRequest request)
{
    // Do some validations...

    // And then...
    var service = new ConcreteService();
    return service.ProcessRequest(request);
}

注意:我见过其他现实世界的项目采用了类似的方法。

【问题讨论】:

  • 我看到了一些继承和泛型,但我不知道你可能在想什么模式。
  • 没有实际代码或解释它应该做什么,这看起来很像古老的“过度工程”模式。
  • @larsmans - 我怀疑这种方法更多地与为外部客户端提供一定程度的版本容错有关。
  • @larsmans 它在 Web 服务项目中用于为用户提出的任何请求创建适当的响应。我们有一个从 IService 继承的类,用于 Web 服务中的每个 Web 方法(20 多个 Web 方法),并且这样做是为了保持 Web 服务之外的逻辑。

标签: .net oop design-patterns


【解决方案1】:

是的 - 它非常接近请求-响应模式,并且在 SOA 应用程序或向外部调用者提供公共接口的场景中非常常见。

这种模式的主要优点是它具有高度的版本容错性。

通常,如果我想向接口上的现有方法添加新参数,则会破坏该接口的兼容性 - 因为方法的签名已更改。针对一个版本编译的客户端无法调用另一个版本 - 即使新字段是可选的,或者旧字段已过时并且可以忽略。

使用此方法,方法的签名(在您的示例中为ProcessRequest)本身保持不变,但请求类型(在您的示例中为ConcreteRequest)现在有一个附加属性。一般来说,大多数序列化/反序列化都可以容忍这个(或者可以配置为容忍这个);如果属性出现在数据中,但不在反序列化到的类型上,它将被忽略。 Conversley 如果属性没有出现在数据中,但出现在实例上,那么实例将只有一个默认值(null、零或其他)。

所以我可以在方法中添加/删除参数,如果我有一个带有参数列表的普通方法,我将无法做到这一点。随着您扩展和发展公共接口,这可以成为一个非常强大的工具。

说了这么多——它只有在你需要的时候才有用。我已经看到它在没有任何好处的情况下使用。

【讨论】:

  • 请求/响应模式是否仅描述了使用这两个对象在 SOA 中交换信息,还是还涉及这些对象相互交互的方式及其生命周期?
  • 从记忆中 - 我会说它描述了您有一个“ProcessRequest”方法的想法,并且您传递了不同的具体类型。您可能有一个 GetUserInfoRequest 与相应的 GetUserInfoResponse 和一个 DeleteUserRequest具有相应的 DeleteUserResponse。然后,您将所有调用都转到一个方法,但具体的请求类型决定了实际调用本身。如上所述,请求/响应对象可以随着时间的推移而变化,而不会破坏一切。您还可以添加新的“方法”,而无需更改公共方法 sig,只需更改它接受的类型。
【解决方案2】:

这似乎是Adapter pattern 的变体。在消息传递方面,这是一个Message Translator 模式。

消息转换器是适配器的消息等价物 [GoF] 中描述的模式。适配器将接口转换为 组件到另一个接口中,以便它可以在不同的接口中使用 上下文

【讨论】:

  • 我认为它是一个消息翻译器,但前提是` // Do some stuff to create the ConcreteResponse object` 是一些简单的代码,可以被认为只进行翻译。
  • 是的,你说得对。但从其他角度来看,我们可以这样看待 - service as message translator 它将请求转换为响应,但这与消息转换无关,它更多的是 SOA,所以我承认消息翻译器不太适合这个例子
  • @DaveBall ProcessRequest 方法可能有复杂的逻辑。这不是从请求到响应的简单转换。
【解决方案3】:

我认为这是接口的正常用法,但它接近Request-Response pattern。为了更好,你可以使用an abstract factory patterndependency injection pattern,取决于你想要什么。

【讨论】:

  • 您能解释一下在这种情况下,其他两种模式如何使代码“更好”吗?
  • 第一个,根据他的目标,他想要多少种具体的响应,这可能很有用。而第二个是将接口“翻译”为具体类,例如使用企业库统一,只在一个地方更改“翻译”,甚至在所有类中更改他使用“手动”翻译就像一个当他创建他的具体类的新对象时进行强制转换。
猜你喜欢
  • 1970-01-01
  • 2021-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多