“不要在设计使用抽象基类;但在建模/分析“ [英] “Do not use Abstract Base class in Design; but in Modeling/Analysis”

查看:204
本文介绍了“不要在设计使用抽象基类;但在建模/分析“的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新手,SOA虽然我在OOAD一定的经验。

I am newbie to SOA though I have some experience in OOAD.

一对SOA设计的指导原则是使用抽象类仅用于建模。从设计忽略它们。使用抽象可以在建模(分析阶段)有帮助。

One of the guidelines for SOA design is "Use Abstract Classes for Modeling only. Omit them from Design". The use of abstraction can be helpful in modeling (analysis phase).

在分析阶段我想出了一个BankAccount的基类。从它派生的专业类是FixedAccount和SavingsAccount。我需要创建,将返回所有帐户(帐户列表)为用户提供服务。应该是什么服务(S),以满足要求?结构

During analysis phase I have come up with a BankAccount base class. The specialized classes derived from it are "FixedAccount" and "SavingsAccount". I need to create a service that will return all accounts (list of accounts) for a user. What should be the structure of service(s) to meet the requirement?

请注意:这将是巨大的,如果你能使用的 WCF 的提供code演示。

Note: It would be great if you can provide code demonstration using WCF.

推荐答案

这听起来像你试图使用SOA来远程访问你的对象模型。你希望你的服务,以揭露和避免暴露你的服务实现继承的细节,你会看着的交互和功能更好。

It sounds like you are trying to use SOA to remotely access your object model. You would be better of looking at the interactions and capabilities you want your service to expose and avoid exposing inheritance details of your services implementation.

因此​​,在这种情况下,你需要的用户帐户列表的界面看起来是这样的。

So in this instance where you need a list of user accounts your interface would look something like

[ServiceContract]
interface ISomeService
{
    [OperationContract]
    Collection<AccountSummary> ListAccountsForUser(
        User user /*This information could be out of band in a claim*/);
}

[DataContract]
class AccountSummary
{
     [DataMember]
     public string AccountNumber {get;set;}
     [DataMember]
     public string AccountType {get;set;}
     //Other account summary information
}

如果你决定走下来的传承途径,您可以使用 KnownType属性,但请注意,这将增加某些类型的信息到信息通过网络发送的这可能会限制你的互操作性在某些情况下电线。

if you do decide to go down the inheritance route, you can use the KnownType attribute, but be aware that this will add some type information into the message being sent across the wire which may limit your interoperability in some cases.

更新

我是有点有限的时间较早,当我回答,所以我会尽力,并阐述为什么我preFER这种风格。

I was a bit limited for time earlier when I answered, so I'll try and elaborate on why I prefer this style.

我不会建议通过的DTO在一个单独的层,这通常会导致在您身边传递大量的数据未使用,religously其映射进,出的臃肿接口暴露你的OOAD什么是本质上是一个副本与所有的逻辑域模型中删除,我只是不明白的价值。我通常设计围绕着我的操作服务层,它揭露和我使用的DTO的服务交互的定义。

I would not advise exposing your OOAD via DTOs in a seperate layer this usually leads to a bloated interface where you pass around a lot of data that isn't used and religously map it into and out of what is essentially a copy of your domain model with all the logic deleted, and I just don't see the value. I usually design my service layer around the operations that it exposes and I use DTOs for the definition of the service interactions.

使用基于公开的操作,而不是域模型有助于保持业务封装和减少耦合到域模型的DTO。如果不公开我的域模型,我没有做实地的知名度和继承是为了系列化任何妥协。

Using DTOs based on exposed operations and not on the domain model helps keep the service encapsulation and reduces coupling to the domain model. By not exposing my domain model, I don't have to make any compromises on field visibility or inheritance for the sake of serialization.

例如,如果我露出传输方式从一个账户转到另一个账户的服务接口看起来是这样的:

for example if I was exposing a Transfer method from one account to another the service interface would look something like this:

[ServiceContract]
interface ISomeService
{
    [OperationContract]
    TransferResult Transfer(TransferRequest request);
}

[DataContract]
class TransferRequest
{
     [DataMember]
     public string FromAccountNumber {get;set;}
     [DataMember]
     public string ToAccountNumber {get;set;}
     [DataMember]
     public Money Amount {get;set;}
}

class SomeService : ISomeService
{
    TransferResult Transfer(TransferRequest request)
    {
        //Check parameters...omitted for clarity
        var from = repository.Load<Account>(request.FromAccountNumber);
        //Assert that the caller is authorised to request transfer on this account
        var to = repository.Load<Account>(request.ToAccountNumber);
        from.Transfer(to, request.Amount);
        //Build an appropriate response (or fault)
    }
}

现在从这个接口是非常清楚的conusmer什么所需的数据调用此操作。如果我实现了这个为

now from this interface it is very clear to the conusmer what the required data to call this operation is. If I implemented this as

[ServiceContract]
interface ISomeService
{
    [OperationContract]
    TransferResult Transfer(AccountDto from, AccountDto to, MoneyDto dto);
}

和AccountDto是帐户中的字段的副本,作为一个消费者,哪些字段我应该填充?他们全部?如果一个新的属性添加到支持新的操作,所有操作的所有用户现在可以看到这个属性。 WCF允许我这个属性标记为非强制性的,这样我就不会破坏我所有的其他客户,但如果是强制性的,以新的操作的客户端将只发现当他们打电话的操作。

and AccountDto is a copy of the fields in account, as a consumer, which fields should I populate? All of them? If a new property is added to support a new operation, all users of all operations can now see this property. WCF allows me to mark this property as non mandatory so that I don't break all of my other clients, but if it is mandatory to the new operation the client will only find out when they call the operation.

更糟的是,由于业务实施者,会发生什么,如果他们为我提供了一个电流平衡?我应该信任呢?

Worse, as the service implementer, what happens if they have provided me with a current balance? should I trust it?

这里的一般规则是要求谁拥有数据,客户端或服务?如果客户端拥有它,那么就可以将它传递给服务,做一些基本检查后,该服务可以使用它。如果该服务拥有它,客户端只能通过足够的信息服务,以获取它需要什么。这使得服务,以保持其拥有的数据的一致性。

The general rule here is to ask who owns the data, the client or the service? If the client owns it, then it can pass it to the service and after doing some basic checks, the service can use it. If the service owns it, the client should only pass enough information for the service to retrieve what it needs. This allows the service to maintain the consistency of the data that it owns.

在这个例子中,服务拥有的帐户信息,并找到它是一个帐号的关键。而服务可以确认的量(为正时,支持货币等),这是由客户端所拥有,因此,我们期望在DTO的所有字段进行填充。

In this example, the service owns the account information and the key to locate it is an account number. While the service may validate the amount (is positive, supported currency etc.) this is owned by the client and therefore we expect all fields on the DTO to be populated.

总之,我已经看到它做了所有3种方式,但各地的具体操作设计的DTO已经是迄今为止最成功的无论是从服务和消费的实现。它允许运营独立发展,是非常明确的关于什么是服务期望,什么将返回给客户端。

In summary, I have seen it done all 3 ways, but designing DTOs around specific operations has been by far the most successful both from service and consumer implementations. It allows operations to evolve independently and is very explicit about what is expected by the service and what will be returned to the client.

这篇关于“不要在设计使用抽象基类;但在建模/分析“的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆