2005年04月23日
 版权所有 如有转载请注明出处。
         以我个人的能力,没有足够的时间和资源自行开发一套完整的平台。在已有的众多开源项目中选择若干优秀的项目进行整合。“站在巨人肩膀上”是牛顿有一句名言.,同样适合我们的IT行业。
我对平台的技术架构的构想,是采用开源的ORM框架做数据持久层, Asp.net没有合适的Web层框架,就采用Asp.net的Code-behind方式编写代码,数据持久层同Web表现层之间的连接采用IOC的容器。
1、 开源框架选择:
数据持久层Nhibernate和IbatisNet这两个都是非常优秀的数据持久层,Nhibernate是优秀的Hibernate的dotNet移植版本,在开源社区具有非常高的人气,IbatisNet是Data Mapper框架,也是JAVA版的Ibatis的移植版本,在dotnet的开源社区一样是非常受欢迎的一个工具。Nhibernate用于支持非常好的面向对象的设计的模型,IbatisNet用于支持应用程序的移植(已经存在数据库,处于生产状态),这两个框架对开发人员的要求。这样就具有更大的弹性。IOC容器Spring.Net和Castle,这是两个dotnet非常优秀的IOC容器。Spring.Net同样是Java的Spring 的移植版本,目前的版本是0.6,Castle则是dotnet下出现新的IOC容器,它的功能,成熟度方面比Spring.Net好得多,框架中准备采用Castle.最后的平台的技术架构就是Nhibernate/IbatisNet + Castle + ASP.NET
2、 架构整合:
Web层的Asp.net负责数据输入输出, 响应用户事件,及输入校验的工作,Web层上如何得到Nhibernate的Session和IbatisNet的SqlMapper?本架构中的DAO,Service以及 Nhibernate的Session和IbatisNet的SqlMapper都是通过Castle进行管理,Web层如何得到Castle IOC容器的实例呢,这里采用HttpModule来处理之,使用用HttpContext.Current.Items来保存容器实例,参看http://www.tobinharris.com/nhibernateasp.aspx。Asp.net页面通过Service处理业务逻辑,Service负责use case逻辑, domain相关的逻辑委托给domain model去实现. Service通过DAO完成对domain model的持久化工作. Service负责数据库事务和NHibernate Session/IbatisNet SqlMapper的管理。Domain model负责表示问题域的数据,DAO使用Nhibernate/IbatisNet持久化数据以及查询. 在实现DAO时, 我们使用了Castle的Nhibernate/IbatisNet DAO Support,极大地简化了代码, 很多方法都只用简单的一行完成。这样的架构优点很明显, 层次清晰, 各层的职责也明确, 便于分层设计与开发, 结合mock和Castle的IOC, unit test也是非常容易的. 而且后台(Service, domain model and DAO)的代码不依赖于Asp.net框架,同样的代码可以在Web App也可以在WinForm上面使用,只需更换UI层。
 
使用的框架工具的链接
http://www.castleproject.org/castle/show/HomePage
http://nhibernate.sourceforge.net/
http://sourceforge.net/projects/ibatisnet/
另外这里有一篇精彩文章应用系统架构设计
2005年04月19日

中国“龙芯”系列CPU的主设计师、中科院计算所研究员胡伟武说,“‘龙芯2号’是我国独立自主研究开发的第一个能够在计算机上跑的芯片,我们命名为‘毛泽东110’,这几个字就印在芯片的上面。”他说:“毛主席的革命精神永远不会过时,毛泽东思想永远不会过时。”

  他说,搞科研同样需要井冈山精神。国外大公司Intel、IBM每年投入几十亿美元,上百亿美元研究计算机芯片,中国则少得多。“我们不仅要有‘不怕鬼,不信邪’的精神,还要有‘星星之火,可以燎原’的精神。敢于迎接工作中碰到的种种挑战,对我们年轻人来说非常重要,尤其是在信息产业,我们还比较落后的情况下,更需要有这种精神。”

  胡伟武说,“毛主席在他漫长的革命生涯中,碰到了大量难以想象的困难,但他从来不被困难所吓倒,也不被敌人所吓倒,而是吓倒了一个又一个的敌人,能够做到这一点,不论是他的朋友还是他的敌人都不得不认可。这种精神是在革命中锻炼出来的精神,是我们中华民族五千年来形成的一种精神,我们年轻人就是要学习这种精神,做到战无不胜,攻无不克。在科研中,应当弘扬这种精神。”

  “我很佩服毛主席在复杂情况下总能一下子抓住问题的要害,并且做出正确的战略战术部署。”胡伟武经常对所里的研究生这样说,“工作当中经常会碰到科研和任务这个矛盾,好多博士生强调老让搞型号任务没有时间干科研了,我说这个观点不对,博士生论文必须从任务中来,到任务中去,论文要源于任务,水平要高于任务,而不是为了发表论文而去写论文,我们工科跟理科不大一样。包括我们做CPU研究,要敢于去做,但是方法也很重要,要集中精力打歼灭战,正如毛主席多次强调的,我们在某些面上不如对手,但是在某些点上我们是可以超过的,就要花五六倍的精力,或者三四倍的精力去全力打败对手,通过一些‘点’上的胜利,可以把‘面’带动起来。”

2005年04月16日

处理逻辑(Advice):在某个连接点所采用的处理逻辑。

切点(PointCut):一系列连接点的集合,它指明处理方式(Advice)将在何处被触发,可以使用正则表达式表达。

Advisor:是PointCutAdvice的综合体,完整描述了一个advice将会在pointcut所定义的位置被触发。

附注:

AOP全名Aspect-Oriented Programming,我们先来看看XXX-Oriented的意义,通常翻译「XXX导向」,也就是以XXX为中心,例如中文中「客户导向」就是以客户为中心,而「对象导向」(OOPObject-Oriented Programming)就是以对象为中心的程序设计。
  自然的,Aspect-Oriented Programming,就是「Aspect导向程序设计」,也就是以Aspect为中心的程序设计,但什么是Aspect?中文直译通常是「方面」,但这个名词容易使人混淆。
  牛津字典中的英英解释对Aspect是:particular part or feature of sth being considerd.
  所以Aspect在英文中不只有「方面」的意思,还有部份(part)的意思。中文中称「就这个方面来说」,通常指的是「就这个角度来说」或「就这个方向来说」,这个解释不适用于AOP中的Aspect。如果英文中说from this aspect of sth,除了可以翻译为上面两句的意义之外,还可以翻作「就这个部份来说」。

  以我们的前一个主题中的记录(log)动作插入至HelloSpeaker对象的hello()中为例,我们说「就记录这个部份」是不属于HelloSpeaker职责的,它被硬生生切入HelloSpeaker中,英文中我们可以说:The logging aspect of the "hello" method doesn’t belong to the job of HelloSpeaker.
  所以以整个方法的执行流程来说,如果执行流程是纵向的,则记录这个动作硬生生的「横切」入其中,这个横切入的部份我们就称之为Aspect,它是横切关注点(crosscutting concern,一个concern可以像是权限检查、事务等等)的模块化,将那些散落在对象中各处的程序代码聚集起来。

  所以Aspect要用中文表达的话,适切一些的名词该是「横切面」或「切面」。AOP关注于Aspect,将这些Aspect视作中心进行设计,使其中从职责被混淆的对象中分离出来,除了使原对象的职责更清楚之外,被分离出来的Aspect也可以设计的通用化,可运用于不同的场合。
  来看事务管理这个Aspect如何在动态代理下被抽取出来,下面是一个简单的概念,基本上是在Handler中先激活事务,执行存储层动作,方法执行成功则提交(commit),失败则回滚(rollback):
  代码:

TransactionHandler.java

public class TransactionHandler implements InvocationHandler {

    private Object delegate;

 

    public Object bind(Object obj) {

        this.delegate = obj;

        return Proxy.new ProxyInstance(.., .., ..);

    }

    public Object invoke(Object proxy, Method method, Object[] args) {

        Object result = null;

 

        …..

 

        YourTransaction transaction = null;

        try {

            transaction = yourMethodForGettingTransaction();

 

            result = method.invoke(delegate, args);

 

            transaction.commit();

        }

        catch(YourException e) {

            if(transaction != null) {

                try {

                    transaction.rollback();

                }

                catch(Exception e) {}

            }

        }

 

        ….

 

        return result;

    }

}

  在AOP中,有好几个关键的概念,然而其中更主要的是:PointCutAdviceAdvisor。这些术语并不是很直观,我们配合我们上一个主题的HelloSpeaker来说明会比较容易理解。
  PointCutJointPoint的集合,JointPoint是指Aspect加入的阶段点,例如某个方法被调用,某个成员被存取(Spring不支持),或是某个例外被丢出,以我们前一个主题的HelloSpeaker为例,hello()方法就是一个JointPointPointCutJointPoint的集合,意味着多个方法或例外丢出可以使用同一个处理建议(Advice)。
  Advice是在JointPoint上所要调用的处理建议(在JointPoint上所采取的动作,许多AOP框架通常以interceptor来实作Advice,之后会介绍),例如记录、事务处理、权限检查等。
  Advice类型(advice type)有AroundBeforeThrowsAfter returning。这些Advice类型会分别在以下的时机被调用:在JointPoint前后、JointPoint前、JointPoint丢出例外时、JointPoint执行完毕后。
  就我们上一个例子来说,我们在hello()这个JointPoint上会调用Around Advice,即我们的LogHandler。事务管理调用的Advice类型也是属于Around Advice,即上面的TransactionHandler,调用的JointPoint可能是某个DAO对象的saveXXX()方法。
  AdvisorPointCutAdvice组合在一起,我们前一个主题中的HelloSpeaker例子很简单,故而没有使用到Advisor,之后会介绍到Advisor
  补充:动态代理是比较常见的AOP实作策略,在《Expert One-on-One J2EE Development WIthout EJB Rod JohnsonJuergen Hoeller中的第八章中有提到,AOP的实作有五个主要的策略:

  • Dynamic Proxies

  • Dynamic Byte Code Generation

  • Java Code Generation

  • Use of a Custon Class Loader

Language Extensions

2005年04月06日

http://www.jroller.com/page/hammett/Weblog?catname=%2FCastle

代码生成工具工具NVelocity – A .Net Template Engine

2005年04月03日

Rails是一个open source的使用Ruby开发web应用的框架,它采用了流行的MVC模式,本文介绍了一个简单的基于数据库的web应用的开发。

翻译自 http://www.rubyonrails.org/show/TutorialStepOne
翻译   http://www.ruby-cn.org
原文分六步六页,这里简化到一页。

1 创建数据库

创建名为rails_production的数据库,以及有访问数据库权限的用户。本例数据库如下:
#
#
数据库 : `rails_production`
#

# ——————————————————–

#
#
`people`定义
#

CREATE TABLE `people` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `name` varchar(50) NOT NULL default ”,
  `street1` varchar(70) NOT NULL default ”,
  `street2` varchar(70) NOT NULL default ”,
  `city` varchar(70) NOT NULL default ”,
  `state` char(2) NOT NULL default ”,
  `zip` varchar(10) NOT NULL default ”,
  PRIMARY KEY  (`id`),
  KEY `name` (`name`)
) TYPE=MyISAM AUTO_INCREMENT=2 ;

#
#
`people`插入数据
#

INSERT INTO `people` VALUES (1, ‘Superman’, ‘123 Somewhere’, ”, ‘Smallville’, ‘KS’, ‘123456′);


2
.设置数据库参数
编辑config/database.yml(明天我做个东西配置文件教*.zml了:-)),相应的例子如下:

My Sql
production:
  adapter: mysql
  database: rails_production
  host: localhost
  username: root
  password:
SQLite
production:
  adapter: sqlite
  dbfile: ../db/rails-production.db

test:
  adapter: sqlite
  dbfile: ../db/rails-test.db
Postgre SQL
production:
  adapter: postgresql
  database: rails_production
  username: postgres
  password:

test:
  adapter: postgresql
  database: rails_test
  username: postgres
  password:


3
.创建控制器
如果还没有创建rails应用,先要创建它。如:
rails path/to/your/new/railsapp
【注意】这将删除这个目录下的已有的rails应用。
创建新的控制器用new_controller(查看文档可以不带参数运行它)。本例如下:
./script/new_controller Friends list display new edit
: new_controller new_model(下面会看到)命令都需要包括ruby路径设置的一行,如果需要改变这些参数,可以丛script文件夹打开这些文件直接修改,设置ruby的正确位置。
: 不要定义任何叫做‘process’action, 这个方法是系统正确工作必须得,你不能重载它。
: Windows用户需要这样来运行程序。
ruby script/new_controller Friends list display new edit

4.创建模型model
创建模型用命令script/new_model,同样,不带参数可以查看本命令的帮助文档。
./script/new_model Person
5
.然后进入rails目录,如果安装了rake程序的话,运行 “rake”。这将测试你的rails应用是否正确部署了。
: 在版本0.5.0中,这个测试只支持mysql,所以如果你用sqlite或者psql出错的话,不必担心。

6.开发rails应用
打开views/friends/display.rhtml文件,当然在rails应用目录下。这个文件是前几步自动产生的,需要我们往里面填充一些东西。修改后如下:

<html>
<body>
<h1>Friends#display</h1>
This page should display one friend
<p />
<%= @person.name %><br/>
<%= @person.city %><br/>

</body>
</html>

这里面有一些动态内容,其中@person对象需要控制器来创建,所以打开controllers/friends_contrller.rb。一些方法已经被自动创建了,但是model还没有被连接进来,所以在require顶部加入:
require ‘person’
这将引入我们定义好的 Active Record 类,通过它我们就可以访问数据库了。
找到名为display的方法,改成下面的:
def display
  @person = Person.find(1)
end


这将从数据库中选出第一个记录,并放入@person变量,供view使用。
现在,我们再来看看model类,打开models/person.rb文件。同样系统已经为我门做了很多工作,已经为我们创建了访问属性的方法,所以不需要我们再写了。需要做的事情是这个类如何映射的我们创建的数据库表。Active Record负责了对象名到表名的映射。具体参见:http://api.rubyonrails.org/classes/ActiveRecord/Base.html

现在我们要做的只是把这个方法加入到Person:
def self.table_name()
“people”
end
然后打开浏览器,打开地址http://rails/friends/display
 ”rails”
是机器名,如果一切正常,你应该能看到应用已经开始工作了。
注意URL中包括控制器friendsaction display

Rails’ web site http://www.rubyonrails.org/show/HomePage

Dotnet平台上使用Rails的请关注Castle On rails项目哦,可以通过此处察看:

http://www.castleproject.org/castle/show/castleonrails

只不过需要拥有服务器的控制权限,他的后缀名称是rails,要配置IIS以便支持此文件名,目前可以支持ashx,但普通的虚拟主机依然无法使用,这可能是个比较麻烦的地方.这里有很多Rail的东西http://blog.csdn.net/ruby_cn/category/65002.aspx

http://blog.itpub.net/category/325/821

 

可以查看此地址

http://www.castleproject.org/castle/show/ActiveRecord

使用此工具可以免去编写NHibernate的配置文件,完全在代码内使用属性配置就可以自动内部映射成NHibernate所需要的数据库映射文件.上面有具体的例子,感兴趣就去瞧瞧

http://rubyforge.org/projects/activerecord/