1

我有一个存在于服务器上的Employee类,我希望将它公开在 Web 服务中,以便客户端可以使用它。

这是我的课:

public class Employee
{
    public CountryCode { get; private set;} 
    public EmployeeType {get; set;}

    public bool IsTaxable
    {
       get
       {
           return (CountryCode != Codes.CaymanIslands 
                  && Status != EmployeeType.Contract);
       }
    }

    public void Employee(EmployeeType type, CountryCode code)
    {
        EmployeeType = type;
        CountryCode = code;
    } 

    private void Employee() {}
}

私有构造函数和私有设置器帮助这个类成为强类型,遵守 DRY 原则,并确保它只能在有效状态下被实例化。

例如,我确保IsTaxable未在构造函数中设置,而是根据其他类属性动态评估。这样,如果修改了EmployeeType , IsTaxable的结果将反映这种变化。我用这个简单的例子来强调这个对象逻辑丰富的事实。

假设这个Employee类存在于服务器上,我希望在客户端上访问它。我构建了一个 WebService(在 .NET 中我将使用 WCF),公开该类并使用开箱即用的工具连接,并且能够在我的客户端中通过网络使用该类。

问题是,这样做会导致我丢失大部分封装的逻辑。在接收端,客户端看不到这个富类及其私有设置器、隐藏构造函数、IsTaxable 属性中的逻辑等。相反,在客户端,我将看到一个像这样的轻量级类:

public class Employee
{
    public CountryCode { get; private set;} 
    public EmployeeType {get; }
    public bool IsTaxable {get; }
}

现在,客户端可以通过执行以下操作将类实例化为无效状态:

Employee e = new Employee();
e.EmployeeType = EmployeeType.Contractor;
e.IsTaxable = true;

失去丰富的对象仅仅是面向服务的生活的一个事实,是我们必须忍受的事情吗?

此类服务传输对象是否仅出于传输信息的目的而被视为弱数据传输实体,并且应该是只读的。

在客户端,您是否应该(如果需要)将它们包装在更丰富的对象中?

是否有任何方法可以通过线路传递逻辑完整的丰富对象,或者是否真的需要?

是否有任何既定的模式来处理这种情况?

4

2 回答 2

3

在查看设计模式之前,您需要查看的第一件事是您真正希望逻辑发生在哪里,以及如果“流氓”客户端更改它通过网络接收的数据实际会发生什么。

大多数客户端-服务器架构的设计方式是客户端尝试做的任何事情都必须由服务器验证。因此,如果客户端决定更改IsTaxable为 true,或者更改 Employee 的姓名或 ID 等,它不会对存储在服务器端的真实数据产生任何影响。客户端必须执行操作以更新服务器上的数据,并且只有当他有权这样做时,数据才会传播到数据库和系统的其余部分。

客户端总是“处于危险之中”(它可能被用户操纵、被黑客入侵、通过网络嗅探等),因此服务器必须足够安全以承受这种情况。

“传输对象”通常仅用于携带数据。然后,任何逻辑要么由客户端执行(例如,将数据格式化为对用户更友好的表示形式),要么由服务器执行。如果客户端需要对数据执行操作,则需要请求服务器执行(以便集中更新)。

因此,在您的情况下,您的 Web 服务需要为您的客户端公开操作以执行您可能需要的任何逻辑。

您可能想要了解的另一件事是如何创建Contract First Web 服务。这被认为是最佳实践,因为它不仅可以确保您的 Web 服务可与其他平台(例如 Java)互操作,还可以让您考虑要向客户公开哪些操作和数据,并帮助您避免错误(例如期望只有服务器可以访问的对象实例)。

契约优先意味着您创建描述操作的 WSDL 和描述要在 XML 中传输的消息和对象的 XSD。他们只是从那些 WSDL 和 XSD 文档中自动生成代码。

于 2012-12-12T11:48:58.813 回答
1

您不能对任意客户端执行此操作,但如果您同时控制客户端和服务器,则可以向客户端添加对包含您的Employee类的程序集的引用,然后将此类型用于 WCF 协定。

在 Visual Studio 中,您可以使用“添加服务引用”/“高级”/“在引用的程序集中重用类型”来执行此操作。

失去丰富的对象仅仅是面向服务的生活的一个事实,是我们必须忍受的事情吗?

是的,这是真的。在真正的面向服务的架构中,您不会在客户端和服务器之间共享行为,而只会交换消息。但是,如果您在控制双方的客户端-服务器体系结构中使用 WCF,则可以使用上述方法。

于 2012-12-12T11:59:17.237 回答