[转载]AAF灵便应用框架介绍系列(1):前言
这是本人在CSDN的第一篇文章,主要目的在于初步介绍一下个人前些年完成的“心血之作”:AAF 基础库1.0。因为是第一次介绍,我想篇幅应该尽可能短一些,只凝练而概括地介绍一下该框架最突出的一些特点。另外,我会提供一个非常简单的代码示例,以 便大家对该框架有一个初步而感性的体验。
本人目前在一家较大型电子商务公司担任CTO。AAF是我总结多年带队开发经验,于数年前开始开发并在2004年基本完成其1.0版本的组件框架。 开发完成后,一度觉得有些疲倦,所以就没有对成果进行任何宣传和介绍。最近突然觉得,与其这样将其束之高阁,不如将其介绍给大家,听听大家的反馈和意见。 如果能够对大家的工作有所帮助,起到提高开发效率及产出的目的,既为社会及企业做出一点绵薄贡献,又能帮助所有辛辛苦苦工作的开发人员更接近“快乐编程” 的梦想,那也算没有白废我为了开发AAF所付出的努力和心血。
AAF已经在实战中经过多次验证。其验证实例既包括一个注册用户达300万,每天新注册用户〉4000,每天订单数1万,各种操作、业务日志及资 金、物品等交易明细达10多万条的较大型在线电子商务系统,也包括基于本框架理念开发的一套类AAF的java平台在企事业项目的多个具体应用。验证结果 表明,采用AAF开发的系统不但能大幅降低开发成本(最少降低50%),提高开发效率及产出(提高100%以上),还能大幅提高系统性能和稳定性。验证结 果还表明:由于AAF由一系列新鲜而自然的概念组成,在开发人员逐步掌握了这些概念之后,开发效率还将明显上升。
开发AAF的初衷是解决如下这几个问题:
1)提供一个对象模型,使得使用AAF的应用的主要开发工作是定义并实现自己的对象模型, 同时通过AAF自带或者根据AAF的要求开发的各种服务(持久化、缓存、缓存同步,事务...)完成各种复杂应用的部署和运行。在AAF的服务中可以通过 对象模型中提供的ITypeDescription(灵便对象:AgileObject描述机制)访问应用定义的对象模型。顺便说一下,AAF自带的各种 服务本身也使用这一对象模型开发。
2) 提供一个真正好用、够用的开放的的O-R Mapping持久化层,解决几乎所有应用都需要考虑的数据库加载、保存、事务机制,使得应用可以完全跳过数据加载、保存及相关事务实现。当然目前已经有 一些O-R Mapping的框架存在,我这里暂且不进行相关的比较,只笼统地把AAf O-R Mapping实现的几个特点罗列在这里:a)在通常情况下几乎不需要额外编写什么代码或影射文件就能直接通过IPersister这个服务接口的实现加 载、存储、批量加载数据对象并且侦听相关事件,唯一的要求是数据对象必须继承AgileObject类型(或者实现IAgileObject接口也可以, 但是暂时不推荐)。b)在通过IPersister的SaveAgileObject/SaveObjects方法能够自动实现一组相关对象的事务化保 存,并且保证即便是这些对象分属于不同的数据库服务器也绝不会导致任何死锁。c)一组相关联的对象在保存时只需针对其中之一进行保存,系统将自动保存所有 相关对象并且保证不会出现死循环。
3) 提供一个真正好用、够用的开放的缓存机制,解决几乎所有应用都需要考虑的数据缓存机制。这一机制应该和前 一机制很好的结合,使得应用无需关心缓存的细节,甚至在大多数情形下除了进行一些必要的配置外,在编码过程中根本无需关心缓存机制的存在。AAF的缓存机 制目前和对象模型以及持久化服务进行了充分整合,对于通过配置文件设置了需要缓存的类型,系统将自动对其进行缓存管理。
4) 提供一个真正好用、 够用的缓存同步机制,解决所有实际商务/政务系统都需要面对的延展性(Scalability)问题。当根据需要进行水平延展(Scale out)时,系统能够很好的解决没缓存会导致吞吐很低`、性能很差,有缓存会导致系统延展比较困难得问题。虽然,缓存定时更新也是解决该问题的一个参考办 法,但是考虑到过于频繁的更新会恶化性能、过于缓慢的更新又会恶化用户体验的尴尬,这一办法不在我们的考虑之列。AAF很好地解决了这一问题,通过AAF 同步服务的支持,只需稍加配置,就可以实现所有AgileObject类型对象的自动同步而无须编写一行代码。
5)提供一个通用的参数设置服务, 该参数设置服务能够基本满足各种应用各种配置的需要,并且具有很强的可用性。
6) 提供一个真正好用、够用的开放的组织结构及授权体系,能够满足 不同企业、政府以及内外网应用的需要,能够非常灵活地针对各种组织结构对象进行授权,提高授权的正交性,尽可能减少不必要的反复授权。
7)提供一 个简单的分布式锁实现,使得系统在Scale Out时能够在多台并行的服务器上实现关键数据的互斥。在AAF中,这一机制也是通过同步服务实现的。
8) 提 供对象替代特性,使得各种对象类型能够在不同的应用或用一应用的不同用户中被根据实际需要通过配置或者开发简单的衍生对象类型所替代。
9) 提供 一个轻量级的SSO机制,使得同一二级域名下的SSO能够非常容易地被实现。
10) 低配置必要性及高配置可用性:上述所有特性的实现应该都只需 在很少配置甚至无需配置的情况下,达到不错的性能和功能要求,但是在必要时,又可以通过配置解决某些相对极端的特定问题。
下面以一个简单(过于简单了)订单系统给出一组典型的AAF实例代码。
以下代码为对象定义代码:
namespace AafTest
{
/// <summary>
/// Order 的摘要说明。
/// </summary>
public class Order : AgileObject
{
public decimal Sum
{
get
{
decimal sum = 0;
foreach(OrderItem odItem in this.OrderItems)
{
sum += odItem.ItemSum;
}
return sum;
}
}
public string UserId;
public string Email;
[Relation(ChildType = typeof(OrderItem), RelationType = typeof(FreeAgileRelation)]
public IAgileRelation OrderItems;
public OrderItem AddOrderItem(string prodId, int qty)
{
OrderItem item = new OrderItem();
item.ProductId = prodId;
item.Quantity = qty;
this.OrderItems.Add(item);
return item;
}
public Order()
{
}
}
public class OrderItem : AgileObject
{
private string _content;
public int Quantity;
public string ProductId;
public Decimal ProdPrice;
public string Content
{
get
{
return _content;
}
set
{
_content = value;
}
}
public decimal ItemSum
{
get
{
return this.Quantity * this.ProdPrice;
}
}
public OrderItem()
{
}
}
}
以下为使用该对象模型(创建订单)的代码
using Aaf.Agile;
using Aaf.Core;
using Aaf.Para;
using Aaf.Persistence;
...
private void btCreateOrder_Click(object sender, System.EventArgs e)
{
// 获取相关服务
ITypeService typeService = return (ITypeService)ServiceHub.Instance.GetService(typeof(ITypeService));
IPersister persister = return (IPersister)ServiceHub.Instance.GetService(typeof(IPersister));
// 创建一个订单并设置相关属性
Order order = (Order)TypeService.CreateInstance(typeof(Order));
order.UserId = "Zhangsan";
order.Email = "MrWuyou@sly.com";
// 增加订单明细
order.AddOrderItem("Prod001", 100);
order.AddOrderItem("Prod100", 200);
// 保存订单
persister.SaveObjects(null, new object[]{order}, false);
}
private void btGetOrder_Click(object sender, System.EventArgs e)
{
// 获取相关服务
IPersister persister = return (IPersister)ServiceHub.Instance.GetService(typeof(IPersister));
// 加载订单
Order order = (Order)persister.LoadAgileObject(typeof(Order), txtOrders.Text);
...
// 第二次加载,速度会很快,因为persister会自动从缓存加载
order = (Order)persister.LoadAgileObject(typeof(Order), txtOrders.Text);
}
大家可以看看实例代码,应该说写一个简单应用是非常轻松的事情。好了,先到这里,要去吃午饭了。作为AAF2.0系列的第一篇文章,暂时先 到这里。希望大家多讨论多支持多发表建议和意见,给我动力,让我能够把这一系列文章不断地写下去,和大家相互砥砺、携手进步。