• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
鱼要的是海洋,鸟要的是天空,我要的是自由!
平凡的人不平凡的人生
博客园    首页    新随笔    联系   管理    订阅  订阅

SOA实践 --转

SOA的理论已经够多了,也许我们可以来实践着在项目中采用SOA架构。

下面来自我自己的经验和理解,一家之言。

1、DTO

Data Transfer Object,或者叫Entity、Data Object。DTO是指在一个对象里面只包含所表示的实体的数据,而不包含任何操作行为。传统的OOP理论认为建立这样纯粹只包含数据的实体类是不正确的,而SOA架构为了能够在分布的、异构的平台上能够顺利的传递数据,则正需要这样的DTO对象。

SOA对DTO的要求是使用方式是:在系统的各个Layer之间传递的,就是DTO,从DAL到BLL,从BLL到各种Service Facade,从Service Facade到外面的服务消费者(包括PL),都传递着DTO。因为这个要求,DTO必须要可被序列化。

2、Layer结构

BLL是不直接对外公开的,对外公开的是在BLL之上的Service Facade,Service Facade里面通常只包含static方法,供服务消费者调用。Service Facade传递和返回的基本上都是DTO,比如:

OrderInfo GetOrder(Int32 orderID);
void UpdateOrder(OrderInfo order);

OrderInfo就是一个DTO。

3、Service Facade的通道多样性

在作为对外的服务接口上,可能提供多种通道的界面,比如可以接收WebService、.Net Remoting、MSMQ、DCOM等等方式的调用,还可能是同步的、异步的调用。所以可能需要提供各种的Service Facade。

ShadowFax通过双重Pipe解决这个问题,第一个管道专门接收各种各样调用请求,然后统一传递给第二个管道,第二个管道再通过调用BLL来处理请求,然后将结果传给第一个管道。

4、每个Service尽量细化

比如有一个Service,调用它必须对调用者进行验证,那么不如再做一个单独的Authentication Service来专门提供验证服务,因为这个单独的Authentication Service可能以后将可以提供给其他的Service使用。

5、Service各自独立(解耦)

可以想象,在一个大型的系统(甚至可以大到整个Internet)里面,如果每个模块、子系统都以Service的方式来提供给外部的服务消费者,那么各个模块和系统都是直接可扩展、可重用的。他们相互相对独立。

好像太简单了一点哈,但这就是我对SOA核心的理解了。

SOA实践方面的资源(本文参考了大量下面所列的资源):
Getting a little closer to SOA
www.dotnetguru.org/us/articles/SOA-Softly/SOA-Softly.html
Are objects with behavior bad for SOA?
dotnetjunkies.com/WebLog/seichert/archive/2004/02/26/8038.aspx
Udi Dahan - The Software Simplist
udidahan.weblogs.us/
Hernan de Lahitte's blog
weblogs.asp.net/hernandl
 
 
想想Indigo, 有三个元素是Services设计中要体现的:Message、Port、Channel
看看你上面说的一些概念,能否从这三点再Review一下?

下面是基于SOA的系统需要考虑和有模式解决的问题:
Service oriented architecture(逻辑的)
Web Services, messaging, contracts
Security
Caching and state management
Deployment policies & constraints
Heterogeneous platforms

然后Building Applications With DSLs
Choose a specific aspect of overall development
Define a metamodel for the abstractions OR extend an existing one
Define a graphical notation
Define a synchronization engine
Define Patterns
Define Aspects


Building Service Oriented Applications is a complex undertaking

这次培训获得的知识,这是其中的一部分
 
对于一般应用而言,我倒觉的不需要考虑channel
对于dto或是po,我同bz的观点一样,我认为,没有单纯的dto,像JGTM2004那种
public class Customer
{
    public string CustomerId;
    public string Name;
}

之类的dto在service facade中往往没有实际使用价值,因为当通过service facade传送的往往是复合对象
Entity 不应该包含商业逻辑是肯定的,但实体应该标识自己的状态,如isnew,isdeleted,isdirty
这样,才可以进行批的处理,这个需求往往体现在更新上

当然,像这种只有公共字段的dto还有以下问题
通常,不能用于绑定,一般只支持属性绑定
必要的数据检验还是有的,虽然在服务端检查是必须的,但如果在客户端检查一次,岂不是更好
 
 
 
一般我会把这种类命名为CustomerInfo,它将被作为VALUE OBJECT被Customer实体对象使用。在SOA里面这种类型有很重要的意义(其实用一个serializable struct就可以),它是被转为contract之前的最后一个和已经和实体类型基本无关的信息,相当于内存中的message表现——所以你用一个字典也问题不大,不过显然直观性不如用field-only class/struct。

Entity是实体标识(identity)的一个重要的组成部分(很有意思哈:identity = id + entity)。entity更多的包含业务相关的数据和与数据相关的业务逻辑(而不是什么业务逻辑都不包括),系统中可以用IDENTITY MAP([PEAA])来记录ID与Entity之间的关联,比如说identityMap[customerID] = customerEntity。这样,当两个程序同时取得同一个customerID对应的customerEntity的时候,IDENTITY MAP可以保证取得的是同一个对象,这可以有效的避免data collision。在很多ORM方案中都有所谓session或者context的概念,其中就有这一块实现。

进一步说,EntityStatus也应该是在entity对象的外部用一个map来维护的,因为customer实体本身是没有这个概念的,这个概念只是对persisting才有意义——不过在很多系统设计中为了简单性起见,把这个EntityStatus放在一个公共基类中,也未尝不可——但决不会放在entityInfo中就是了。

关于和UI相关的绑定,显然不是和entityInfo打交道(这个东西是entity内部private的一部分),真正绑定的应该是entity对象才对,因为这个对象上面没有public fields,只有public properties,既不影响绑定功能,也可以在被赋值时施加业务数据逻辑(should not be null、must between 18-60、length should not exceed 100 characters、etc)——这个逻辑一般都是用程序直接表达,但在我们的项目中也有用custom attribute表达的,这样有两个好处,一个是代码简化,第二个就是这个信息可以被UI对象访问到,以便可以做客户端检查,比如这样:
public class Customer
{
  [Constraint.Range(18, 60)]
  public int Age
  {
    get { return customerInfo.Age; }
    set { customerInfo.Age = ConstraintApplied(value); }
  }

  [Constraint.MaxLength(100), Constraint.MinLength(4), Constraint.CannotBeNull]
  public string Name
  {
    get { return customerInfo.Name; }
    set { customerInfo.Name = ConstraintApplied(value); }
  }
}

public object ConstraintApplied(object value)
{
  MethodInfo method = new StackTrace().GetFrame(1).GetMethod() as MethodInfo;
  if (method==null) ...

  ConstraintAttribute[] constraints = Attribute.GetCustomAttributes(...);

  foreach (ContraintAttribute constraint in constraints)
  {
    if (false==constraint.Validate(value))
    {
      throw new ConstraintException(...);
    }
  }

  return value;
}

而UI绑定到一个属性的时候,也可以从上面取到ConstraintAttribute并构造相应的客户端验证机制……
posted @ 2005-11-25 09:54  伊凡  阅读(373)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3