??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲国产成人久久综合一,亚洲国产婷婷综合在线精品,亚洲高清无码在线观看http://www.tkk7.com/jelver/category/7679.html“一直很多h说我是天才,但我却相信这个世界没有天才。如果没有卓的努力和娴熟的球性,你永q不会踢出精彩的球。我?岁开始踢球,7岁进入格L奥少q队开始接受系l训l,至今为止已经t了20q的球。如果你认ؓq纯_Ҏ天才Q那Z么我14岁时没有现在q种天才呢?我从来不会低估努力的重要性,而这正是我对自己的要求。? ---------|纳_奥(Ronaldinho)zh-cnTue, 27 Feb 2007 10:27:24 GMTTue, 27 Feb 2007 10:27:24 GMT60cMcdpȝUML图与代码表现 (?http://www.tkk7.com/jelver/articles/87448.html冰河快狼冰河快狼Wed, 13 Dec 2006 04:37:00 GMThttp://www.tkk7.com/jelver/articles/87448.htmlhttp://www.tkk7.com/jelver/comments/87448.htmlhttp://www.tkk7.com/jelver/articles/87448.html#Feedback0http://www.tkk7.com/jelver/comments/commentRss/87448.htmlhttp://www.tkk7.com/jelver/services/trackbacks/87448.html 原文Q?a >http://www.javaeye.com/topic/37302?page=1
cMcM间的关系对于理解面向对象h很重要的作用Q以前在面试的时候也l常被问到这个问题,在这里我׃l一下?br />cMcM间存在以下关p?
(1)泛化(Generalization)
(2)兌(Association)
(3)依赖(Dependency)
(4)聚合(Aggregation)

UML图与应用代码例子:
1.泛化(Generalization)
[泛化]
表示cMcM间的l承关系Q接口与接口之间的承关p,或类Ҏ口的实现关系。一般化的关pL从子cL向父cȝQ与l承或实现的Ҏ相反?br />[具体表现]
父类 父类实例Qnew 子类()
[UML图](?.1)

?.1AnimalcMTigerc?Dogcȝ泛化关系

[代码表现]

  1. class  Animal{}   
  2. class  Tiger  extends  Animal{}   
  3. public   class  Test   
  4. {   
  5.      public   void  test()   
  6.     {   
  7.         Animal a= new  Tiger();   
  8.     }   
  9. }  

2.依赖(Dependency)
[依赖]
对于两个相对独立的对象,当一个对象负责构造另一个对象的实例Q或者依赖另一个对象的服务Ӟq两个对象之间主要体Cؓ依赖关系?br />[具体表现]
依赖关系表现?font color="#ff0000">局部变?/font>Q?font color="#ff0000">Ҏ的参?/font>Q以及对静态方法的调用
[现实例子]
比如说你要去拧螺丝,你是不是要借助(也就是依?Z刀(Screwdriver)来帮助你完成拧螺?screw)的工?br />[UML表现](?.2)


?.2 PersoncMScrewdrivercȝ依赖关系

[代码表现]

  1. public class Person{   
  2.     /** 拧螺丝?/  
  3.     public void screw(Screwdriver screwdriver){   
  4.         screwdriver.screw();   
  5.     }   
  6. }  

3.兌(Association)
[兌]
对于两个相对独立的对象,当一个对象的实例与另一个对象的一些特定实例存在固定的对应关系Ӟq两个对象之间ؓ兌关系?br />[具体表现]
兌关系是?font color="#ff0000">实例变量
来实?br />[现实例子]
比如客户和订单,每个订单对应特定的客P每个客户对应一些特定的订单Q再例如公司和员工,每个公司对应一些特定的员工Q每个员工对应一特定的公?br />[UML图] (?.3)

?.3 公司和员工的兌关系


[代码表现]
  1. public class Company{   
  2.     private Employee employee;   
  3.     public Employee getEmployee(){   
  4.         return employee;   
  5.     }   
  6.     public void setEmployee(Employee employee){   
  7.         this.employee=employee;   
  8.     }   
  9.     //公司q作   
  10.     public void run(){   
  11.         employee.startWorking();   
  12.     }   
  13. }  
(4)聚合QAggregationQ?/font>
[聚合]
当对象A被加入到对象B中,成ؓ对象B的组成部分时Q对象B和对象A之间集关pR聚合是兌关系的一U,是较强的兌关系Q强调的?font color="#ff0000">整体?font color="#ff0000">部分
之间的关pR?br />[具体表现]
与关联关pMP聚合关系也是通过实例变量来实现这样关pȝ。关联关pd聚合关系来语法上是没办法区分的,?font color="#ff0000">语义上才?font color="#ff0000">更好的区?/font>两者的区别?br />[兌与聚合的区别]
(1)兌关系所涉及的两个对象是处在同一个层ơ上的。比如h和自行R是一U关联关p,而不是聚合关p,因ؓZ是由自行车组成的?br />聚合关系涉及的两个对象处于不q等的层ơ上Q一个代表整体,一个代表部分。比如电脑和它的昄器、键盘、主板以及内存就是聚集关p,因ؓL是电脑的l成部分?br />(2)对于h聚集关系Q尤其是集关p)的两个对象,整体对象会制U它的组成对象的生命周期。部分类的对象不能单独存在,它的生命周期依赖于整体类的对象的生命周期Q当整体消失Q部分也随之消失。比如张三的电脑被偷了,那么电脑的所有组件也不存在了Q除非张三事先把一些电脑的lgQ比如硬盘和内存Q拆了下来?br />[UML图](?.4)

?.3 电脑和组件的聚合关系

[代码表现]
  1. public class Computer{   
  2.     private CPU cpu;   
  3.     public CPU getCPU(){   
  4.         return cpu;   
  5.     }   
  6.     public void setCPU(CPU cpu){   
  7.         this.cpu=cpu;   
  8.     }   
  9.     //开启电?  
  10.     public void start(){   
  11.         //cpuq作   
  12.         cpu.run();   
  13.     }   
  14. }  


[参考资料]
1.《Java与模式?阎宏 ~著) W??l一建模语言UML?/strong>


冰河快狼 2006-12-13 12:37 发表评论
]]>
ȝ一下最q关于domain object以及相关的讨?http://www.tkk7.com/jelver/articles/41009.html冰河快狼冰河快狼Fri, 14 Apr 2006 00:50:00 GMThttp://www.tkk7.com/jelver/articles/41009.htmlhttp://www.tkk7.com/jelver/comments/41009.htmlhttp://www.tkk7.com/jelver/articles/41009.html#Feedback0http://www.tkk7.com/jelver/comments/commentRss/41009.htmlhttp://www.tkk7.com/jelver/services/trackbacks/41009.html http://forum.javaeye.com/viewtopic.php?t=11712

在最q的围绕domain object的讨Z现出来了三U模型,(q有一些其他的旁枝Q不一一分析?Q经q一番讨论,各种问题逐渐清晰hQ在q里我试囑ց一个ȝQ便于大家了解和掌握?

W一U模型:只有getter/setterҎ的纯数据c,所有的业务逻辑完全由business object来完?又称TransactionScript)Q这U模型下的domain object被Martin FowlerUC为“血的domain object”。下面用举一个具体的代码来说明,代码来自Hibernate的caveatemptorQ但l过我的改写Q?

一个实体类叫做ItemQ指的是一个拍卖项?
一个DAO接口cd做ItemDao
一个DAO接口实现cd做ItemDaoHibernateImpl
一个业务逻辑cd做ItemManager(或者叫做ItemService)

java代码: 

public class Item implementsSerializable{
    privateLong id = null;
    privateint version;
    privateString name;
    private User seller;
    privateString description;
    private MonetaryAmount initialPrice;
    private MonetaryAmount reservePrice;
    privateDate startDate;
    privateDate endDate;
    privateSet categorizedItems = newHashSet();
    privateCollection bids = newArrayList();
    private Bid successfulBid;
    private ItemState state;
    private User approvedBy;
    privateDate approvalDatetime;
    privateDate created = newDate();
    //  getter/setterҎ省略不写Q避免篇q太?/span>
}



java代码: 

public interface ItemDao {
    public Item getItemById(Long id);
    publicCollection findAll();
    publicvoid updateItem(Item item);
}



ItemDao定义持久化操作的接口Q用于隔L久化代码?

java代码: 

public class ItemDaoHibernateImpl implements ItemDao extends HibernateDaoSupport {
    public Item getItemById(Long id){
        return(Item) getHibernateTemplate().load(Item.class, id);
    }
    publicCollection findAll(){
        return(List) getHibernateTemplate().find("from Item");
    }
    publicvoid updateItem(Item item){
        getHibernateTemplate().update(item);
    }
}


ItemDaoHibernateImpl完成具体的持久化工作Q请注意Q数据库资源的获取和释放是在ItemDaoHibernateImpl里面处理的,每个DAOҎ调用之前打开SessionQDAOҎ调用之后Q关闭Session?Session攑֜ThreadLocal中,保证一ơ调用只打开关闭一?

java代码: 

public class ItemManager {
    private ItemDao itemDao;
    publicvoid setItemDao(ItemDao itemDao){ this.itemDao = itemDao;}
    public Bid loadItemById(Long id){
        itemDao.loadItemById(id);
    }
    publicCollection listAllItems(){
        return  itemDao.findAll();
    }
    public Bid placeBid(Item item, User bidder, MonetaryAmount bidAmount,
                            Bid currentMaxBid, Bid currentMinBid)throws BusinessException {
            if(currentMaxBid != null && currentMaxBid.getAmount().compareTo(bidAmount) > 0){
            throw new BusinessException("Bid too low.");
    }
   
    // Auction is active
    if( !state.equals(ItemState.ACTIVE))
            throw new BusinessException("Auction is not active yet.");
   
    // Auction still valid
    if( item.getEndDate().before(newDate()))
            throw new BusinessException("Can't place new bid, auction already ended.");
   
    // Create new Bid
    Bid newBid = new Bid(bidAmount, item, bidder);
   
    // Place bid for this Item
    item.getBids().add(newBid);
    itemDao.update(item);     //  调用DAO完成持久化操?/span>
    return newBid;
    }
}



事务的管理是在ItemMangerq一层完成的QItemManager实现具体的业务逻辑。除了常见的和CRUD有关的简单逻辑之外Q这里还有一个placeBid的逻辑Q即目的竞标?

以上是一个完整的W一U模型的CZ代码。在q个CZ中,placeBidQloadItemByIdQfindAll{等业务逻辑l统攑֜ItemManager中实玎ͼ而Item只有getter/setterҎ

W二U模型,也就是Martin Fowler指的rich domain object是下面这样子的:

一个带有业务逻辑的实体类Q即domain object是Item
一个DAO接口ItemDao
一个DAO实现ItemDaoHibernateImpl
一个业务逻辑对象ItemManager

java代码: 

publicclass Item implementsSerializable{
    //  所有的属性和getter/setterҎ同上Q省?/span>
    public Bid placeBid(User bidder, MonetaryAmount bidAmount,
                        Bid currentMaxBid, Bid currentMinBid)
            throws BusinessException {
   
            // Check highest bid (can also be a different Strategy (pattern))
            if(currentMaxBid != null && currentMaxBid.getAmount().compareTo(bidAmount) > 0){
                    throw new BusinessException("Bid too low.");
            }
   
            // Auction is active
            if( !state.equals(ItemState.ACTIVE))
                    throw new BusinessException("Auction is not active yet.");
   
            // Auction still valid
            if( this.getEndDate().before(newDate()))
                    throw new BusinessException("Can't place new bid, auction already ended.");
   
            // Create new Bid
            Bid newBid = new Bid(bidAmount, this, bidder);
   
            // Place bid for this Item
            this.getBids.add(newBid)// h意这一句,透明的进行了持久化,但是不能在这里调用ItemDaoQItem不能对ItemDao产生依赖Q?/span>
   
            return newBid;
    }
}



竞标q个业务逻辑被放入到Item中来。请注意this.getBids.add(newBid); 如果没有Hibernate或者JDOq种O/R Mapping的支持,我们是无法实现这U透明的持久化行ؓ的。但是请注意QItem里面不能去调用ItemDAOQ对ItemDAO产生依赖Q?

ItemDao和ItemDaoHibernateImpl的代码同上,省略?

java代码: 

publicclass ItemManager {
    private ItemDao itemDao;
    publicvoid setItemDao(ItemDao itemDao){ this.itemDao = itemDao;}
    public Bid loadItemById(Long id){
        itemDao.loadItemById(id);
    }
    publicCollection listAllItems(){
        return  itemDao.findAll();
    }
    public Bid placeBid(Item item, User bidder, MonetaryAmount bidAmount,
                            Bid currentMaxBid, Bid currentMinBid)throws BusinessException {
        item.placeBid(bidder, bidAmount, currentMaxBid, currentMinBid);
        itemDao.update(item);    // 必须昑ּ的调用DAOQ保持持久化
    }
}



在第二种模型中,placeBid业务逻辑是放在Item中实现的Q而loadItemById和findAll业务逻辑是放在ItemManager中实现的。不q值得注意的是Q即使placeBid业务逻辑攑֜Item中,你仍焉要在ItemManager中简单的装一层,以保证对placeBid业务逻辑q行事务的管理和持久化的触发?

q种模型是Martin Fowler所指的真正的domain model。在q种模型中,有三个业务逻辑ҎQplaceBidQloadItemById和findAllQ现在的问题是哪个逻辑应该攑֜Item中,哪个逻辑应该攑֜ItemManager中。在我们q个例子中,placeBid攑֜Item?但是ItemManager也需要对它进行简单的装)QloadItemById和findAll是放在ItemManager中的?

切分的原则是什么呢Q?Rod Johnson提出原则是“case by case”,可重用度高的Q和domain object状态密切关联的攑֜Item中,可重用度低的Q和domain object状态没有密切关联的攑֜ItemManager中?

我提出的原则是:看业务方法是否显式的依赖持久化?/span>

Item的placeBidq个业务逻辑Ҏ没有昑ּ的对持久化ItemDao接口产生依赖Q所以要攑֜Item中?span style="COLOR: red">h意,如果q了Hibernateq个持久化框ӞItemq个domain object是可以进行单元测试的Q他不依赖于Hibernate的持久化机制。它是一个独立的Q可UL的,完整的,自包含的域对?/span>?

而loadItemById和findAllq两个业务逻辑Ҏ是必L式的Ҏ久化ItemDao接口产生依赖Q否则这个业务逻辑无法完成。如果你要把q两个方法放在Item中,那么Item无法脱Hibernate框架Q无法在Hibernate框架之外独立存在?br />
W三U模型印象中好像是firebody或者是Archie提出?也有可能不是Q记不清楚了)Q简单的来说Q这U模型就是把W二U模型的domain object和business object合二Z了。所以ItemManager׃需要了Q在q种模型下面Q只有三个类Q他们分别是Q?

ItemQ包含了实体cM息,也包含了所有的业务逻辑
ItemDaoQ持久化DAO接口c?
ItemDaoHibernateImplQDAO接口的实现类

׃ItemDao和ItemDaoHibernateImpl和上面完全相同,q略了?

java代码: 

publicclass Item implementsSerializable{
    //  所有的属性和getter/setterҎ都省?/span>
   privatestatic ItemDao itemDao;
    publicvoid setItemDao(ItemDao itemDao){this.itemDao = itemDao;}
   
    publicstatic Item loadItemById(Long id){
        return(Item) itemDao.loadItemById(id);
    }
    publicstaticCollection findAll(){
        return(List) itemDao.findAll();
    }

    public Bid placeBid(User bidder, MonetaryAmount bidAmount,
                    Bid currentMaxBid, Bid currentMinBid)
    throws BusinessException {
   
        // Check highest bid (can also be a different Strategy (pattern))
        if(currentMaxBid != null && currentMaxBid.getAmount().compareTo(bidAmount) > 0){
                throw new BusinessException("Bid too low.");
        }
       
        // Auction is active
        if( !state.equals(ItemState.ACTIVE))
                throw new BusinessException("Auction is not active yet.");
       
        // Auction still valid
        if( this.getEndDate().before(newDate()))
                throw new BusinessException("Can't place new bid, auction already ended.");
       
        // Create new Bid
        Bid newBid = new Bid(bidAmount, this, bidder);
       
        // Place bid for this Item
        this.addBid(newBid);
        itemDao.update(this);      //  调用DAOq行昑ּ持久?/span>
        return newBid;
    }
}



在这U模型中Q所有的业务逻辑全部都在Item中,事务理也在Item中实现?br />
在上面三U模型之外,q有很多q三U模型的变种Q例如partech的模型就是把W二U模型中的DAO和Manager三个cdqؓ一个类后Ş成的模型Q例如frain....(id很长C?的模型就是把W三U模型的三个cd全合qؓ一个单cd形成的模型;例如Archie是把W三U模型的Item又分出来一些纯数据c?可能是,不确?形成的一个模型?

但是不管怎么变,基本模型归纳h是上面的三U模型,下面分别单评价一下:

W一U模型绝大多Ch都反对,因此反对理由我也不多讲了。但遗憾的是Q我观察到的实际情Ş是,很多使用Hibernate的公司最后都是这U模型,q里面有很大的原因是很多公司的技术水qx有达到这U层ơ,所以导致了q种贫血模型的出现。从q一Ҏ_Martin Fowler的批评声音不是太响了Q而是太弱了,q需要再l箋呐喊?

W二U模型就是Martin Fowler一直主张的模型Q实际上也是我一直在实际目中采用这U模型。我没有看过Martin的POEAAQ之所以能够自己摸索到q种模型Q也是因Z02q我已经开始思考这个问题ƈ且寻求解x案了Q但是当时没有看到HibernateQ那时候做的一个小型项目我已经按照q种模型来做了,但是׃没有O/R Mapping的支持,写到后来又不得不全部Ҏ贫血的domain objectQ项目做完以后再l箋找,随后发CHibernate。当Ӟ现在很多Z开始就是用Hibernate做项目,没有l历q我l历的那个阶Dc?

不过我觉得这U模型仍然不够完,因ؓ你还是需要一个业务逻辑层来装所有的domain logicQ这昑־非常|嗦Qƈ且业务逻辑对象的接口也不够E_。如果不考虑业务逻辑对象的重用性的?业务逻辑对象的可重用性也不可能好)Q很多hq脆去掉了xxxManagerq一层,在Web层的Action代码直接调用xxxDaoQ同时容器事务管理配|到Actionq一层上来。Hibernate的caveatemptor是q样架构的一个典型应用?

W三U模型是我很反对的一U模型,q种模型下面QDomain Object和DAO形成了双向依赖关p,无法q框架试Qƈ且业务逻辑层的服务也和持久层对象的状态耦合C一P会造成E序的高度的复杂性,很差的灵zL和p糕的可l护性。也许将来技术进步导致的O/R Mapping理下的domain object发展到够的动态持久透明化的话,q种模型才会成ؓ一个理想的选择。就像O/R Mapping的流行得第二种模型成ؓ了可?O/R Mapping行以前Q我们只能用W一U模型,W二U模型那时候是不现实的)?/span>

既然大家都统一了观点,那么有了一个很好的讨论问题的基了。Martin Fowler的Domain ModelQ或者说我们的第二种模型N是完无~的吗?当然不是Q接下来我就要分析一下它的不I以及可能的解军_法,而这些都来源于我个h的实跉|索?

在第二种模型中,我们可以清楚的把q?个类分ؓ三层Q?

1、实体类层,即ItemQ带有domain logic的domain object
2、DAO层,即ItemDao和ItemDaoHibernateImplQ抽象持久化操作的接口和实现c?
3、业务逻辑层,即ItemManagerQ接受容器事务控Ӟ向Web层提供统一的服务调?

在这三层中我们大家可以看刎ͼdomain object和DAO都是非常E_的层Q其实原因也很简单,因ؓdomain object是映数据库字段的,数据库字D不会频J变动,所以domain object也相对稳定,而面向数据库持久化编E的DAO层也不过是CRUD而已Q不会有更多的花P所以也很稳定?

问题在于这个充当business workflow facade的业务逻辑对象Q它的变动是相当频繁的?span style="COLOR: red">业务逻辑对象通常都是无状态的、受事务控制的、Singletonc?/span>Q我们可以考察一下业务逻辑对象都有哪几cM务逻辑ҎQ?

W一c:DAO接口Ҏ的代?/span>Q就是上面例子中的loadItemByIdҎ和findAllҎ?

ItemManager之所以要代理q种c,目的有两个:向Web层提供统一的服务调用入口点和给持久化方法增加事务控制功?/span>。这两点都很Ҏ理解Q你不能既给Web层程序员提供xxxManagerQ也l他提供xxxDaoQ所以你需要用xxxManager装xxxDaoQ在q里Q充当了一个简单代理功能;而事务控制也是持久化Ҏ必须的,事务可能需要跨多个DAOҎ调用Q所以必L在业务逻辑层,而不能放在DAO层?

但是必须看到Q对于一个典型的web应用来说Q绝大多数的业务逻辑都是单的CRUD逻辑Q所以这U情况下Q针Ҏ个DAOҎQxxxManager都需要提供一个对应的装ҎQ这不但是非常枯燥的Q也是o人感觉非怸好的?


W二c:domain logic的方法代?/span>。就是上面例子中placeBidҎ。虽然Item已经有了placeBidҎQ但是ItemManager仍然需要封装一下Item的placeBidQ然后再提供一个简单封装之后的代理Ҏ?

q和W一U情늱|其原因也一P也是ZlWeb层提供一个统一的服务调用入口点和给隐式的持久化动作提供事务控制?

同样Q和W一U情况一P针对每个domain logicҎQxxxManager都需要提供一个对应的装ҎQ同h枯燥的,令h不爽的?


W三c:需要多个domain object和DAO参与协作的business workflow。这U情冉|业务逻辑对象真正应该完成的职责?

在这个简单的例子中,没有涉及到这U情况,不过大家都可以想像的出来q种应用场景Q因此不必D例说明了?

通过上面的分析可以看出,只有W三cM务逻辑Ҏ才是业务逻辑对象真正应该承担的职责,而前两类业务逻辑Ҏ都是“无奈之䏀,不得不ؓ之的事情Q不但枯燥,而且令h沮?




分析完了业务逻辑对象Q我们再回头看一下domain objectQ我们要仔细考察一下domain logic的话Q会发现domain logic也分Zc:

W一c:需要持久层框架隐式的实现透明持久化的domain logicQ例如Item的placeBidҎ中的q一句:
java代码: 

this.getBids().add(newBid);


上面已经着重提刎ͼ虽然q仅仅只是一个Java集合的添加新元素的操作,但是实际上通过事务的控Ӟ会潜在的触发两条SQLQ一条是insert一条记录到bid表,一条是更新item表相应的记录。如果我们让ItemqHibernateq行单元试Q它是一个单U的Java集合操作Q如果我们把他加入到Hibernate框架中,他就会潜在的触发两条SQLQ?span style="COLOR: red">q就是隐式的依赖于持久化的domain logic
?
特别h意的一ҎQ在没有Hibernate/JDOq类可以实现“透明的持久化”工具出C前,q类domain logic是无法实现的?

对于q一cdomain logicQ业务逻辑对象必须提供相应的封装方法,以实C务控制?


W二c:完全不依赖持久化的domain logicQ例如readonly例子中的TopicQ如下:

java代码: 

class Topic {
    boolean isAllowReply(){
        Calendar dueDate = Calendar.getInstance();
        dueDate.setTime(lastUpdatedTime);
        dueDate.add(Calendar.DATE, forum.timeToLive);
   
        Date now = newDate();
        return now.after(dueDate.getTime());
    }
}



注意q个isAllowReplyҎQ他和持久化完全不发生一丁点关系。在实际的开发中Q我们同样会遇到很多q种不需要持久化的业务逻辑(主要发生在日期运、数D和枚Dq算斚w)Q这Udomain logic不管q不脱L在的框架Q它的行为都是一致的。对于这Udomain logicQ业务逻辑层ƈ不需要提供封装方法,它可以适用于Q何场合?/span>


冰河快狼 2006-04-14 08:50 发表评论
]]>
UML用例建模的慨念和应用http://www.tkk7.com/jelver/articles/35894.html冰河快狼冰河快狼Fri, 17 Mar 2006 16:12:00 GMThttp://www.tkk7.com/jelver/articles/35894.htmlhttp://www.tkk7.com/jelver/comments/35894.htmlhttp://www.tkk7.com/jelver/articles/35894.html#Feedback0http://www.tkk7.com/jelver/comments/commentRss/35894.htmlhttp://www.tkk7.com/jelver/services/trackbacks/35894.html一Q?UML?br />
  UMLQ统一建模语言QUnified Modeling LanguageQ是一U定义良好、易于表达、功能强大且普遍适用的可视化建模语言。它融入了Y件工E领域的新思想、新Ҏ和新技术。它的作用域不限于支持面向对象的分析与设计,q支持从需求分析开始的软g开发的全过E。在pȝ分析阶段Q我们一般用UML来画很多图,主要包括用例图、状态图、类图、活动图、序列图、协作图、构建图、配|图{等Q要d些图要根据具体情况而定。其实简单的理解Q也是个人的理解QUML的作用就是用很多图从静态和动态方面来全面描述我们要开发的pȝ?br />
  二. 用例建模?br />
  用例建模是UML建模的一部分Q在我眼里,它也是UML里最基础的部分。用例徏模的最主要功能是用来表达pȝ的功能性需求或行ؓ?br />
  依我的理解用例徏模可分ؓ用例囑֒用例描述。用例图由参与者(ActorQ、用例(Use CaseQ、系l边界、箭头组成,用画囄Ҏ来完成。用例描q用来详l描q用例图中每个用例,用文本文档来完成?br />
  1Q?用例?br />
  参与者不是特指hQ是指系l以外的Q在使用pȝ或与pȝ交互中所扮演的角艌Ӏ因此参与者可以是人,可以是事物,也可以是旉或其他系l等{。还有一点要注意的是Q参与者不是指人或事物本nQ而是表示人或事物当时所扮演的角艌Ӏ比如小明是图书馆的理员,他参与图书馆理pȝ的交互,q时他既可以作ؓ理员这个角色参与管理,也可以作为借书者向图书馆借书Q在q里明扮演了两个角Ԍ是两个不同的参与者。参与者在d中用Wh物画来表C,人物下面附上参与者的名称?br />


  用例是对包括变量在内的一l动作序列的描述Q系l执行这些动作,q生传递特定参与者的价值的可观察结果。这是UML对用例的正式定义Q对我们初学者可能有炚w懂。我们可以这样去理解Q用例是参与者想要系l做的事情。对于对用例的命名,我们可以l用例取一个简单、描q性的名称Q一般ؓ带有动作性的词。用例在d中用椭圆来表C,椭圆下面附上用例的名U?br />


  pȝ边界是用来表C正在徏模系l的边界。边界内表示pȝ的组成部分,边界外表C系l外部。系l边界在d中方框来表示Q同旉上系l的名称Q参与者画在边界的外面Q用例画在边界里面。因为系l边界的作用有时候不是很明显Q所以我个h理解Q在d时可省略?br />
  头用来表示参与者和pȝ通过怺发送信h消息q行交互的关联关pR箭头尾部用来表C启动交互的一方,头头部用来表示被启动的一方,其中用例L要由参与者来启动?br />
  2Q?用例描述

  用例囑֏是简单地用图描述了一下系l,但对于每个用例,我们q需要有详细的说明,q样可以让别h对这个系l有一个更加详l的了解Q这时我们就需要写用例描述?br />
  对于用例描述的内容,一般没有硬性规定的格式Q但一些必L者重要的内容q是必须要写q用例描q里面的。用例描qC般包括:要描qͼ说明Q、前|(前提Q条件、基本事件流、其他事件流、异怺件流、后|(事后Q条件等{。下面说说各个部分的意思:

  要描qͼ对用例的角色、目的的要描qͼ

  前置条gQ执行用例之前系l必要处于的状态,或者要满的条Ӟ

  基本事g:描述该用例的基本程Q指每个程都“正常”运作时所发生的事情,没有M备选流和异常流Q而只有最有可能发生的事g;

  其他事g:表示q个行ؓ或流E是可选的或备选的Qƈ不是总要总要执行它们Q?br />
  异常事g:表示发生了某些非正常的事情所要执行的程Q?br />
  后置条gQ用例一旦执行后pȝ所处的状态;



UML的作用就是用很多图从静态和动态方面来全面描述我们要开发的pȝ
三. 用例囑֒用例描述设计实例

  q里用我开发的一个家教网站来单的分析用例囄L和用例描q的写法。这个网站我用UML完整的分析一下,以下我提取了用例囑֒用例描述的部分。这个家教网站分为前台客Ll和后台理pȝ?br />
  前台客户pȝ的用例图如下Q?br />


  后台理pȝ用例囑֦下:



  对于用例描述Q篇q有限,我在q里只列了后台管理系l中的网站公告发布这个用例的描述。如下:

用例名称Q网站公告发?/td>
用例标识P202
参与者:负责?/td>
要说明:
  负责人用来填写和修改家教|站首页的公告,公告最l显C在家教|站的首上?/td>
前置条gQ?br />  负责人已l登陆家教网站管理系l?/td>
基本事g:
 1Q?负责人鼠标点几Z修改公告”按?br /> 2Q?pȝ出现一个文本框Q显C着原来的公告内?br /> 3Q?负责人可以在文本框上修改公告Q也可以完全删除Q重新写新的公告
 4Q?负责人编辑完文本框,按“提交”按钮,首页公告p修改
 5Q?用例l止
其他事gA1Q?br /> 在按“提交”按钮之前,负责人随时可以按“返回”按钮,文本框的M修改内容都不会媄响网站首늚公告
异常事g:
 1Q?提示错误信息Q负责h认
 2Q?q回到管理系l主面
后置条gQ?br /> |站首页的公告信息被修改
注释Q无

  

冰河快狼 2006-03-18 00:12 发表评论
]]>
建模工具Rose的学?Q?/title><link>http://www.tkk7.com/jelver/articles/35893.html</link><dc:creator>冰河快狼</dc:creator><author>冰河快狼</author><pubDate>Fri, 17 Mar 2006 16:09:00 GMT</pubDate><guid>http://www.tkk7.com/jelver/articles/35893.html</guid><wfw:comment>http://www.tkk7.com/jelver/comments/35893.html</wfw:comment><comments>http://www.tkk7.com/jelver/articles/35893.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/jelver/comments/commentRss/35893.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/jelver/services/trackbacks/35893.html</trackback:ping><description><![CDATA[概述 <p>  在这个面向对象应用程序开发不断变化的时代Q在合理旉内开发和理高质量应用程序变得越来越困难。ؓ了面对这U挑战,制定出每个公叔R能用的通用对象模型语言Q统一建模语言QUMLQ。UML是信息技术行业的蓝图Q是详细描述pȝl构的方法。利用这个蓝图,我们来容易徏立和l护pȝQ保证系l能适应需求的改变。一个系l的模型建得好,׃ؓ满用户需求、保证系l的E_性和质量、提高系l的扩展性打下了良好的基。ROSE是用UML快速开发应用程序的工具之一Q它是一个面向对象的建模工具?</p><p>UMLl一建模语言 </p><p>  UMLQUnified Modeling LanguageQ统一建模语言Q是一U面向对象的建模语言Q它的主要作用是帮助我们对Y件系l进行面向对象的描述和徏模,它可以描q这个Y件开发过E从需求分析直到实现和试的全q程。UML通过建立各种cR类之间的关联、类/对象怎样怺配合实现pȝ的动态行为等成分Q这些都UCؓ模型元素Q来l徏整个模型Q刻d观世界。UML提供了各U图形,比如Use Case图、类图、顺序图、协作图、状态图{,来把q些模型元素及其关系可视化,让h们可以清楚容易的理解模型。我们可以从多个视角来考察模型Q从而更加全面的了解模型Q这样同一个模型元素可能会出现在多个图中,对应多个囑Ş元素?<br /></p><p>  p图viewQ图diagramQ模型元素model element和通用机制general mechanism{几个部分组?.视图是表辄l的某一斚w特征的UML建模元素的子集,由多个图构成Q是在某一个抽象层上,对系l的抽象表示.图是模型元素集的囑Ş表示Q通常为弧Q关p)和顶点(其他模型元素Q相互连接构成的.模型元素代表面向对象中的cR对象、消息和关系{概念,是构成图的最基本的常用概?通用机制用于表示其它信息Q比如注释、模型元素的语义{。另外,它还提供扩展机制QUML语言能够适应一个特D的ҎQ或q程Q,或扩充至一个组l或用户. <br /></p><p>  UML是用来描q模型的Q用模型来描q系l的l构或静态特征,以及行ؓ或动态特征。从不同的视角ؓpȝ的构架徏模,形成pȝ的不同视图(VIEWQ?<br /></p><p>  用例视图(use case view)Q强调从用户的角度看到的或需要的pȝ功能Q是被称为参与者的外部用户所能观察到的系l功能的模型图; <br /></p><p>  逻辑视图(logical view)Q展现系l的静态或l构l成及特征,也称为结构模型视?structural model view)或静态视图(static viewQ; <br /></p><p>  q发视图(concurrent view)Q体Cpȝ的动态或行ؓ特征Q也UCؓ行ؓ模型视图Qbehavioral model viewQ、动态视?dynamic view)Q?<br /></p><p>  lg视图(component view)Q体Cpȝ实现的结构和行ؓ特征Q也UCؓ实现模型视图(implementation model view) Q?<br /></p><p>  配置视图(deployment view)Q体Cpȝ实现环境的结构和行ؓ特征Q也UCؓ环境模型视图Qenvironment model viewQ或物理视图(physical view)?</p><p>建模工具Rose 之游 </p><p>  ROSE是美国Rational公司的面向对象徏模工P利用q个工具Q我们可以徏立用UML描述的Y件系l的模型Q而且可以自动生成和维护C++、Java、VB、Oracle{语a和系l的代码?<br /></p><p>  ROSE是个菜单驱动应用E序Q用工具栏帮助用常用特性。它的界面分Z个部?-BrowserH口、DiagramH口和DocumentH口。BrowserH口用来览、创建、删除和修改模型中的模型元素QDiagramH口用来昄和创作模型的各种图;而DocumentH口则是用来昄和书写各个模型元素的文档注释?</p><p align="center"><img height="333" src="http://www.ddvip.net/program/uml/index3/img/rosexx_1.gif" width="412" /></p><p align="center">Rose界面 <br /></p><p>  Rose模型的四个视图是Use Case视图 、Logical视图、Component视图和Deployment视图。每个视N对不同对象,h不同用途。Use Case视图包括pȝ中的所有角艌Ӏ案例和Use Case图,q包括一些Sequence囑֒Collaboration图?<br /></p><p align="center"><img height="280" src="http://www.ddvip.net/program/uml/index3/img/rosexx_2.gif" width="181" /></p><p align="center">Use Case视图 <br /></p><p>  Logical视图xpȝ如何实现使用案例中提到的功能。它提供pȝ的详l图形,描述lg间如何关联。除其它内容之外QLogical视图q包括需要的特定cRClass囑֒State Transition 图。利用这些细节元素,开发h员可以构造系l的详细设计?</p><p align="center"><img height="308" src="http://www.ddvip.net/program/uml/index3/img/rosexx_3.gif" width="181" /></p><p align="center"><br />Logical视图 <br /></p><p>  Component视图包括模型代码库、执行库和其它组件的信息。组件是代码的实际模块。Component视图的主要用h负责控制代码和编译部|应用程序的人。有些组件是代码库,有些lg是运行组Ӟ如执行文件或动态链接库QDLLQ文件?<br /></p><p>  Collaboration囑օ注系l的部vQ可能与pȝ的逻辑l构不同。整个小l都用Collaboration图了解系l部|Ԍ但用h发布应用E序的h员?</p><p>Rose的九U图 <br /></p><p>  用例图use case diagramQ描q系l功?<br />   cdclass diagramQ描q系l的静态结?<br />   对象图object diagramQ描q系l在某个时刻的静态结?<br />   序列图sequence diagramQ按旉序描述pȝ元素间的交互 <br />   协作图Collaboration diagramQ按照时间和I间序描述pȝ元素间的交互和它们之间的关系 <br />   状态图state diagramQ描qCpȝ元素的状态条件和响应 <br />   zd图activity diagramQ描qCpȝ元素的活?<br />   lg图component diagramQ描qC实现pȝ的元素的l织 <br />   配置图deployment diagramQ描qC环境元素的配|,q把实现pȝ的元素映到配置?<br /></p><p>  Ҏ它们在不同架构视囄应用Q可以把9U图分成Q?<br /></p><p>  用户模型视图Q用例图 <br />   l构模型视图Q类图、对象图 <br />   行ؓ模型视图Q序列图、协作图、状态图、活动图Q动态图Q?<br />   实现模型视图Q组件图 <br />   环境模型视图Q配|图 </p><img src ="http://www.tkk7.com/jelver/aggbug/35893.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/jelver/" target="_blank">冰河快狼</a> 2006-03-18 00:09 <a href="http://www.tkk7.com/jelver/articles/35893.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>建模工具Rose的学?/title><link>http://www.tkk7.com/jelver/articles/35892.html</link><dc:creator>冰河快狼</dc:creator><author>冰河快狼</author><pubDate>Fri, 17 Mar 2006 16:08:00 GMT</pubDate><guid>http://www.tkk7.com/jelver/articles/35892.html</guid><wfw:comment>http://www.tkk7.com/jelver/comments/35892.html</wfw:comment><comments>http://www.tkk7.com/jelver/articles/35892.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/jelver/comments/commentRss/35892.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/jelver/services/trackbacks/35892.html</trackback:ping><description><![CDATA[在随着面向对象的程序设计的q泛应用Q可视化~程遍地开q今天Q编E工作h员的C一再被动摇Q早以不再作为开发中的主,而Y件工E的应用以作Y件开发的质量和效率的重要见证已越来越被重视,针对早期的结构化建模工具的明显不IROSE吸取众多建模工具的优点,排除其不I采用面向对象的成熟技术和双向工程的技巧,为提高Y件开发的效率Q保证Y件开发的质量和可l护性作Z巨大的A献?<br />软g工程概述 <br />   软g开发是一套关于Y件开发各阶段的定义、Q务、作用的建立在理Z的一门工E学U。它册Y件危机,指导Z利用U学、有效的Ҏ来开发YӞ提高及保证Y件开发的效率和质量取C一定的作用?软g开发过E:需求分析(开始阶D)--概要设计Q静态结构)--详细设计Q动态结构) --~码-试-l护 <br />l构化模型设计方?<br />AQE-R图(实体关系图) <br />   实体Q客观存在ƈ可区分的事物?<br />   属性:实体所h的某U特性,一个实体可以有多个属性?<br />   关系Q实体之间的对应关系Q可分ؓ1Q?联系?Qn联系、mQn联系 <br /><img height="530" src="http://www.ddvip.net/program/uml/index3/img/rosexx.gif" width="400" /><br />BQ数据流?<br /><img height="241" src="http://www.ddvip.net/program/uml/index3/img/rosexx1.gif" width="538" /><br />CQ功能模块图 <br /><img height="252" src="http://www.ddvip.net/program/uml/index3/img/rosexx2.gif" width="370" /><br />l构化模型的不 <br />   传统的结构化模型的设计所建立的模型不能反应源代码Q与E序设计p。模型与代码几乎没什么关pR这L模型不能生成代码Q代码更不能生成模型Q模型大多是ȝ领导看或拿出作掩盖。所以不能保证Y件的质量Q更不易软g的维护,没什么约束力也没有检的标准Q它的弊端是显于易见的?<br />面向对象的模型设计方?<br />   定义Q利用面向对象方法,把应用程序分成许多小块(对象Q,q些对象是独立的Q然后组合这些对象,建立E序?<br />   特点Q包装、ѝ多态?<br />   常用的徏模工PPlayCase, Rational ROSE, Computer Association BPWin , Computer Association ERWin, Oracle Designer/2000, Sybase PowerDesigner <br />UML语言概述 <br />   定义Q一U面向对象的l一建模语言?<br />   作用Q帮助我们对软gpȝq行面向对象的和建模?<br />   核心Q类Q类之间的关pR?<br />   建模Q通过用L业务震需求映ؓ代码Q保证代码满些需求,代码能方便地回溯需求,q个q程叫徏模?<br />ROSE建模工具 <br />   定义Q是一U分析和设计面向对象的徏模工兗?<br />   作用Q利用ROSEq个工具Q我们可以徏立用UML的Y件系l的模型Q面目可以自动生成和l护C++、JAVA、VB、PB、ORACLE{语a和系l的代码?<br />   核心Q七大框?<br />   1. Use-Case DiagramsQ用例框图) <br />   2. sequence diagram Q顺序框图) <br />   3. Collaboration diagram Q协作框图) <br />   4. Class diagram Q类框图Q?<br />   5. State Transition diagram Q状态框图) <br />   6. Component diagram Q组件框图) <br />   7. Deployment diagram Q扩展框图) <br />   下面l合软g工程知识、利用ROSE建模工具Q本人在开发电力部们的"110KV标准设计图文理pȝ"中所用到的ROSE模型及对ROSE在开发实践中的剖?<br />一?需求分析阶D?<br />   dQ徏立用户需求和功能模块Q确定系l中的角色和使用案例。利用ROSEQ生成角Ԍ使用案例和生成用例图 <br />所用到的框图: <br />   1.Use-Case DiagramsQ显CZ用案例(表示pȝ功能Q与角色Qh或系l)间的交互。如下图Q?<br /><img height="347" src="http://www.ddvip.net/program/uml/index3/img/rosexx3.gif" width="450" /><br />   Use CaseQ用例)Q在不展C个系l或pȝ内部l构的情况下Q对pȝ或系l的q诏的功能单元的定义和描q?<br />角色Q用Y件的人或外部pȝ本n?<br />2. sequence diagram <br />   按时间先后顺序,从上C分析使用案例Q确定案例的处理程。如下图Q?<br /><img height="566" src="http://www.ddvip.net/program/uml/index3/img/rosexx4.gif" width="493" /><br />3 Collaboration diagram Q?<br />   定对象之间的关pȝ处理q程的分析流E。如下图Q?<br /><img height="396" src="http://www.ddvip.net/program/uml/index3/img/rosexx5.gif" width="429" /><br />二?概要设计阶段 <br />   dQ通过分析Use-Case Diagrams Q得到所用到的类Q分析这些类的属性、操作和它们之间的关pR?<br />   所用到的框图: <br />1.Class Diagrams. <br />   昄pȝ中类与类之间的交互?<br /><img height="338" src="http://www.ddvip.net/program/uml/index3/img/rosexx6.gif" width="203" /><br />2.包:h一些共性的cȝ合在一L图?<br /><img height="180" src="http://www.ddvip.net/program/uml/index3/img/rosexx7.gif" width="383" /><br /><br />三?详细设计阶段 <br />   dQ细化和个性Use-Case的描q?Q如cȝ操作和对象之间的消息相对应,填充参数及复杂的cȝ设计?<br />   所用到的框图: <br />1.Class Diagrams <br />2.State Diagrams:昄一个对象从生成到删除的生命周期?<br />四?~码和测试阶D?<br />   dQ进行Y件的开发和试Q生成组件框图?<br />   lgQ表CZ码的物理模块?<br />   lg框图Q表C系l中的组件及怺依赖性?<br />   Delpoyment Diagrams:昄|络中的物理布局和各U组件的位置?<br /><img height="231" src="http://www.ddvip.net/program/uml/index3/img/rosexx8.gif" width="511" /><br />双向工程 <br />   1.生成代码Q根据选择开发应用程序的语言生成对应的程序的代码?<br />   步骤Q检查模?生成lg-类映射lg-讄代码生成属?选择cR组件和?生成代码 <br />   2.逆向转出工程Q根据选择开发应用程序的语言生成对应的程序的代码?<br />   步骤Q检查模?生成lg-类映射lg-讄代码生成属?选择cR组件和?生成代码 <img src ="http://www.tkk7.com/jelver/aggbug/35892.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/jelver/" target="_blank">冰河快狼</a> 2006-03-18 00:08 <a href="http://www.tkk7.com/jelver/articles/35892.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>UML的用?Use Case)概念分析及实?http://www.tkk7.com/jelver/articles/35299.html冰河快狼冰河快狼Tue, 14 Mar 2006 13:09:00 GMThttp://www.tkk7.com/jelver/articles/35299.htmlhttp://www.tkk7.com/jelver/comments/35299.htmlhttp://www.tkk7.com/jelver/articles/35299.html#Feedback0http://www.tkk7.com/jelver/comments/commentRss/35299.htmlhttp://www.tkk7.com/jelver/services/trackbacks/35299.html UML的用?Use Case)概念分析及实?/SPAN>

?/SPAN>/d 

2005-02-25 

?/SPAN>UML?/SPAN>use caseg最單的,用例建模的最主要功能是用来表达pȝ的功能性需求或行ؓQ依我的理解用例建模可分为用例图和用例描q。用例图由参与者(ActorQ、用例(Use CaseQ、系l边界、箭头组成,用画囄Ҏ来完成。用例描q用来详l描q用例图中每个用例,用文本文档来完成Q以及由头所l成的各U关p,包括泛化Q包含,扩展{。本文准备向大家介绍以下内容,所有图C均?/SPAN>PowerDesigner所?/SPAN>.

u       用况

u       参与?/SPAN>

u       泛化

u       <<use>>

u       <<include>>

u       <<extend>>

u       用例描述 

Q.             用况Q?/SPAN>use caseQ?/SPAN> 

 

                             图1 用况?/SPAN> 

是对一l动作序列(其中包括它的变体Q的描述Q系l执行该动作为执行此动作的参与者生一个可观察的结果倹{比如你使用计算器,q里可以把计器看作为用况,参与者是dQ登峰按了3Q3Q用冉|行的序列Q,计算机器q回一个结果6?/SPAN> 

Q.             参与?/SPAN>(Actor)

   

参与者不是特指hQ是指系l以外的Q在使用pȝ或与pȝ交互中所扮演的角艌Ӏ因此参与者可以是人,可以是事物,也可以是旉或其他系l等{。还有一点要注意的是Q参与者不是指人或事物本nQ而是表示人或事物当时所扮演的角艌Ӏ比如小明是图书馆的理员,他参与图书馆理pȝ的交互,q时他既可以作ؓ理员这个角色参与管理,也可以作为借书者向图书馆借书Q在q里明扮演了两个角Ԍ是两个不同的参与者。参与者在d中用Wh物画来表C,人物下面附上参与者的名称?/SPAN>


 

Q.             泛化

泛化和类中的泛化概念是一LQ子用况l承父用늚行ؓ和含义,q可以增加或覆盖父用늚行ؓ;子用况可以出现在M父用况出现的位置Q父和子均有具体的实例)。下面给ZU图C来说明泛化的概念和含义                                             

          

    

    

    

图2 含义l承                                 图3 行ؓl承

 Q.<<user>>

<<use>>: ?/SPAN>关系非常象一个函数调用或一个子q程以这U方式用的用例UCؓ?

象用例因为它不能单独存在而必被其它用例使用Q请看下?

 

 

           图4 使用<<use>>CZ

 

 

Q.<<include>>

怎么解释q个定义呢? q是说明一下它的功能吧Q?/SPAN><<include>>可以把几个用例的公共步骤分离出来成ؓ一个单独的被包含用例。学q?/SPAN>C的朋友知道它的含义了吧。呵?/SPAN>

好的Q定义都已经知道了,下面用一个示例来加深大家的印象。假如有个h事系l,l理可以查看员工的信息,q可以增加,修改和删除,但每ơ执行这三个操作Ӟ都要定位到相应的员工Q即先查询定位到要操作的员工。图Q给Zq种表述?/SPAN>use case ?/SPAN>,L?/SPAN><<include>>的含?/SPAN>

 

 

                          图5 <<include>>的用?/SPAN>

6Q?/SPAN><<extend>>

  <<extend>>为已存在用例d新的行ؓ提供了一U方法?/SPAN> 基础用例提供了一l扩展点Q?/SPAN>extend pointsQ,扩展Ҏ钩子Q在此可以添加新的行为,扩展用例提供了一l插入片D,q些片段可被插入到基用例的钩子位|。需要注意的是基用例不知道扩展用例的Ml节Q它仅ؓ扩展用例提供了钩子。这?/SPAN><<include>>不同Q此时如果没有被包含用例Q客L例将不完整。图Q说明了主述文字描述

 

             

             图6 <<extend>>的用?/SPAN>

Q.用例描述

   当然用例描述是对用例的文字性说明。具体要描述哪些,q里׃多说了,l大家一个具体示例一看就明白。假如有个家教网Q下面只是一个抽象片Dc主要是Z说明用例描述的含义?/SPAN> 

 

 

 

 

下面是用例|站公告发布的用例描q?/SPAN>

 



冰河快狼 2006-03-14 21:09 发表评论
]]>
对象关系数据库之间的映射http://www.tkk7.com/jelver/articles/35292.html冰河快狼冰河快狼Tue, 14 Mar 2006 12:41:00 GMThttp://www.tkk7.com/jelver/articles/35292.htmlhttp://www.tkk7.com/jelver/comments/35292.htmlhttp://www.tkk7.com/jelver/articles/35292.html#Feedback0http://www.tkk7.com/jelver/comments/commentRss/35292.htmlhttp://www.tkk7.com/jelver/services/trackbacks/35292.html
Z么对?关系数据库的映射对于C开发者是一件大事呢Q一斚wQ对象技术(例如 Java 技术)是应用于新Y件系l开发的最常见的环境。另外,关系数据库仍然是许多人都青睐的持久信息存储方法,q且在较长时间内q种情况不太会改变。请l箋M去,了解如何使用q种技术?BR>

Z么要写有兛_?关系数据库之间的映射的文章呢Q因为在对象范例和关p范例之间“阻抗不匚w”。对象范例基于Y件工E的一些原理,例如耦合、聚合和装Q而关p范例则Z数学原理Q特别是集合论的原理。两U不同的理论基础D各自有不同的优缺炏V而且Q对象范例侧重于从包含数据和行ؓ的对象中构徏应用E序Q而关p范例则主要针对数据的存储。当问而寻找一U合适的ҎӞ“阻抗不匚w”就成了主要矛盾Q用对象范例,您是通过它们的关pL讉K对象Q而用关p范例,则通过复制数据来联接表中的行。这U基本的差异D两种范例的结合ƈ不理惻I不过话说回来Q本来就预料C有一些问题。对象-关系数据库之间的映射成功的一个秘诀是理解q两U范例和它们的差异,然后Zq些认识来进行明智的取舍?/P>

本文应该能够消除C开发周期中一些普遍共有的误解Q对对象-关系数据库之间映所涉及到的一些问题提供了切合实际的看法。这些策略基于我的开发经验,目范围从小到大Q涉及金融、销售、军事、远E通信和外购等行业。我已对使用 C++?Smalltalk、Visual Basic ?Java 语言~写的应用程序应用了q些原则?/P>

如何对象映成关系数据?/STRONG>
在这一节中Q我会描qC些将对象成功映射成关pL据库所需的基本技术?/P>

属性映成?/STRONG>
cd性将映射成关pL据库中的零或几列。要CQƈ不是所有属性都是持久的。例如, cM? 属性,q个属性由其实例在计算时用,但它不保存到数据库中。而且Q某些对象属性本w就是对象,例如 对象有一个作为属性的 实例Q它映射为数据库中的几列Q实际上Q很有可? cLw就映成一个或多个表)。重要的是,q是一个递归定义Q有时属性将映射成零或者多列。也有可能将几个属性映成表中的单一列。例如,代表国邮递区号代码的cd以有三个数字属性,每个都表C完整邮政编号代码中的每一部分Q而邮政编号代码可以在地址表中作ؓ单一的列存储?/P>

在关pL据库中实现?/STRONG>
在将对象保存到关pL据库中时Q承的概念中发生几个有的问题。(请参?A Building Object Applications That Work"。)问题从根本上归结释如何在您的持久模型中组l承的属性。解册个难题所用的Ҏ会对pȝ设计有很大媄响。将l承映射到关pL据库中有三种基本解决办法Qؓ更好地理解它们,我将讨论在图 1 中显C的映射cd表的优缺炏Vؓ化问题,我没有ؓcȝ所有属性都建模Q也没有为其完整{֐或Q何类Ҏ建模?/P>

?1. 单类层次l构?UML cȝ意图

类映射成表
cd表的映射通常不是直接的。除了非常简单的数据库以外,您不会有cd表的一对一映射。在以下章节中,我将讨论为关pL据库实现l承l构的三U策略:



整个cdơ结构用一个数据实?/B>
使用q种ҎQ您可以一个完整类层次l构映射成一个数据实体,而层ơ结构中所有类的所有属性都存储在这个实体中。图 2 描述了采取这个方法时?1 的类层次l构的持久模型。请注意Qؓ表的主键引入了一? ?- 我在所有解x案中都?OID Q没有商业含义的标识Q又U替代键Q,只是Z保持一致和使用我所知道的向数据实体分配键的最好办法?/P>

?2. 类层次l构映射成单一数据实体
?2. 类层次l构映射为单一数据实体

q种Ҏ的优Ҏ单,因ؓ所需的所有h员数据都可以在一张表中找刎ͼ所以在Z更改角色时支持多态性,q且使用q种ҎQ专门报告(Z组用户特定目的所执行的报告,q些用户通常自己写报告)也非常简单。缺Ҏ每次在类层次l构的Q何地Ҏ加一个新属性时都必d一个新属性添加到表中。这增加了类层次l构中的耦合 - 如果在添加一个属性时有Q何错误,除获得新属性的cȝ子类外,q可能媄响到层次l构中的所有类。它q可能浪Ҏ据库中的许多I间。我q必L? 列来表明行代表的是学生、教授还是其它类型的人员。在Zh单一角色时这U方法很有效Q但如果他们有多个角Ԍ例如Q一个h既是学生又是教授Q,很快׃失效?/P>

每个具体cM用一个数据实?/B>
使用q种ҎQ每个数据实体就既包含属性又包含它所表示的类l承的属性。图 3 描述了采取这个方法时?1 的类层次l构的持久模型。有? cd应的和与 cd应的数据实体Q因为它们是具体c,但没有与 cd应的数据实体Q因为它是抽象类Q它的名UC斜体字表C)。ؓ每个数据实体都分别分配了自己的主键, ??/P>

?3. 每个具体类映射成单个数据实?/STRONG>
?3. 每个具体类映射成单个数据实? border=0 height=107 src=

q种Ҏ最大的好处是,它仍然能相当Ҏ地执行专门报告,只要您所需的有兛_一cȝ所有数据都只存储在一张表中。但也有几个~点。一个是当修改类Ӟ必须修改它的表和它所有子cȝ表。例如,如果要向 cL加高度和重量Q就需要同时更C个表Q它会涉及很多工作。第二,无论何时Q只要对象更改了它的角色 - 可能您聘用了您一个刚毕业的学生作为教?- 则需要将数据复制到相应的表中Qƈ为它指定一个新?OID。这又涉及到很多工作。第三,很难在支持多个角色的同时仍维护数据完整性。(q种情况是可能的Q只是比原先困难一炏V)例如Q您会在哪里存储既是学生又是教授的h的姓名呢Q?/P>

每个cM用一个数据实?/B>
使用q种ҎQؓ每个cdZ张表Q它的属性是 OID 和特定于该类的属性。图 4 描述了采取这个方法时?1 的类层次l构的持久模型?h意,? 用作了所有三个数据实体的主键。图 4 的一个有的Ҏ是Qؓ ? 中的 列都分配了两个构造型Q而这在标准徏模语a (UML) 中是不允许的。我的意见是Q这是一个必ȝ UML 持久性徏模概要解决的问题Q甚臛_能在q个建模规则中也需要更攏V(有关持久性模型的详细信息Q请参阅

?4. 每个类映射成它自己的数据实?/STRONG>

q种Ҏ的最大好处就是它能够最好地适应面向对象的概c它能够很好地支持多态性,对于对象可能有的每个角色Q只需要在相应的表中保存记录。修改超cdd新的子类也非常容易,因ؓ您只需要修Ҏd一张表。这U方法也有几个缺炏V第一Q数据库中有大量的表 -- 实际上每c都有一个(加上l护关系的表Q。第二,使用q种技术读取和写入数据的时间比较长Q因为您必须讉K多个表。如果通过类层次l构中的每个表放入不同物理磁盘驱动器盘片Q假设每个磁盘驱动器头都单独操作)上来地组l数据库的话Q就可以~解q个问题。第三,有关数据库的专门报告很困难,除非d一些视图来模拟所需的表?/P>

比较映射{略
现在Q请注意Q每个映策略怎样产生不同的模型。要理解三种{略之间的设计优~点Q请考虑?5 中显C的Ҏ们的cdơ结构做些简单的更改Q添加了 Q这是从 中承的?/P>

?5. 扩展初始cdơ结?/STRONG>

?6 昄了一个更新过的持久性模型,用于整个类层次l构映射成一个数据实体。尽很明显Q数据库中的I间费增加了,但请注意Q按照这U策略操作,只需花非常小的代价就可以更新模型?/P>

?6. 扩展的层次l构映射成单一数据实体
?6. 扩展的层次l构映射成单一数据实体

?7 昄了将每个具体cL成数据实体时的持久性模型。用这个策略,虽然因ؓ我们从教授提升到ln教授Q这样对象和我们的关pd有了改变Q学生变成教授)Q所以如何处理对象的q个问题更复杂了Q但我只需要添加一个新表?/P>

?7. 扩展的层次l构的具体类映射成数据实?/STRONG>

?8 昄了第三种映射{略的解x?-- 单个类映射成单个数据实体。这需要我d一个只包括 cȝ新属性的新表。这U方法的~点是,要用新cȝ实例Q它需要好几个数据库访问?/P>

?8. 扩展的层次l构的所有类映射成数据实?/STRONG>

要摒弃这样一U观点,卌些办法都不够好;每种办法都有其优~点。在下面的表 1 中对它们q行比较?/P>

?1. 比较映射l承的各U办?/B>

考虑因素
每个层次l构一张表
每个具体cM张表
每个cM张表
专门报告
Ҏ
中等
中等/困难
实现的难易程?/FONT>
Ҏ
中等
困难
数据讉K的难易程?/FONT>
Ҏ
Ҏ
中等/Ҏ
耦合
非常?/FONT>
?/FONT>
?/FONT>
数据讉K速度
?/FONT>
?/FONT>
中等/?/FONT>
对多态性的支持
中等
?/FONT>
?/FONT>

映射兌、聚合和l成
不仅必须对象映到数据库中Q还必须对象之间的关系q行映射Q这h能在以后q行恢复。对象之间有四种cd的关p:l承、关联、聚合和l成。要有效地映这些关p,必须理解它们之间的差异、如何实C般的关系Q以及如何实现特定的多对多关pR?/P>

兌、聚合和l合之间的差?/STRONG>
从数据库的角度看Q关联和聚合Q组合关pM间的唯一不同是对象相互之间的l定E度。对于聚合和l合Q在数据库中Ҏ体所做的操作通常需要同时对部分q行操作Q而关联就不是q样?/P>

在图 9 中有三个c,其中两个在它们之间有单的兌关系Q有两个׃n聚合关系Q实际上Q组合可能是q种模型中更切的说法)。(有关关系的详l信息,请参?A Building Object Applications That Work"。)从数据库的观点看Q聚合/l合和关联是不同的,在聚合情况下Q在整体中读取时Q您通常希望在部分中dQ而在兌情况下,需要执行什么操作ƈ不L那么明显。在对象保存到数据库中或从数据库中删除对象也存在相同的情况。当Ӟ上述讨论通常特定于商业领域,但这U经验之谈往往在很多情况下出现?/P>

?9. 兌和聚合/l合之间的差?/STRONG>
?9. 兌和聚合/l合之间的差? border=0 height=99 src=

在关pL据库中实现关p?/STRONG>
关系数据库中的关pL通过使用外键来维护的。外键是在一张表中出现的一个或多个数据属性;它可以是另一张表的键的一部分Q或者干脆碰巧就是另一张表的键。外键可以让您将一张表中的一行与另一张表中的一行相兌v来。要实现一对一和一对多的关p,您只需要将一张表的键包括在另一张表中?/P>

在图 10 中有三张表,它们的键 (OID) 和外键用于在它们之间实现关系。首先,? ? 数据实体间有一个一对一的关联。一对一兌是它的每个复合度的最大值都?1 的这么一U关pR要实现q个关系Q我? 数据实体中用属?Q?CODE> 数据实体的键。因为关联是单向?-- employee 那些行知道它们的位置行,但反q来׃?-- 所以我必须q么做。如果这是个双向的关联,我还会在 中添加一个名? 的外键。然后,使用相同的方法在 ? 之间实现了多对一兌Q又UCؓ一对多兌Q,唯一的不同是外键放在了 中,因ؓ它在关系的“多”方?/P>

?10. 单h力资源数据库的持久性模型?/STRONG>

实现多对多关?/STRONG>
要实现多对多关系Q需要关联表的概念,它是一U数据实体,唯一目标是在关系数据库中l护两个或多个表之间的关联。图 10 中,?CODE> ? 之间有一个多对多关系。图 11 中,可以看到如何使用兌表来实现多对多关pR在关系数据库中Q关联表中包含的属性传l上是关pM涉及到的表中的键l合。关联表的名U通常是它所兌的表的名U组合,或者是它实现的兌的名U。在q种情况下,我选择 而不? ?Q因为我觉得它可以更好地反映兌的性质?/P>

?11. 在关pL据库中实现多对多关系

看一下图 11 中应用程序的复合度。规则是Q一旦引入了兌表,复合度就“交叉”,如图 12 所C。gؓ '1' 的复合度d外边~引入,如图 11 ?12 中所C,以保留原始关联的整体复合度。原始的兌表明雇员有一U或多种利Qƈ且Q何给定的利都给予一个或多个雇员。在?11 中您可以看到Q即使在有关联表l护兌的情况下仍然是这U情c?/P>

?12. 兌表简?/STRONG>

有必要注明我选择应用构造型?lt;<兌?gt;>”而不是关联类的说?-- 关联类与它所描述的关联连接的虚线?-- Z两个原因。首先,兌表的目的是实现关联,而关联类的目的是描述兌。其ơ,?11 中采取的Ҏ反映了ؓ使用关系技术所需的实际实现策略?/P>

l束



冰河快狼 2006-03-14 20:41 发表评论
]]>
用rational rose 2003 设计商业销售系l?/title><link>http://www.tkk7.com/jelver/articles/34947.html</link><dc:creator>冰河快狼</dc:creator><author>冰河快狼</author><pubDate>Sun, 12 Mar 2006 16:10:00 GMT</pubDate><guid>http://www.tkk7.com/jelver/articles/34947.html</guid><wfw:comment>http://www.tkk7.com/jelver/comments/34947.html</wfw:comment><comments>http://www.tkk7.com/jelver/articles/34947.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/jelver/comments/commentRss/34947.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/jelver/services/trackbacks/34947.html</trackback:ping><description><![CDATA[     摘要: 本次分析设计是针对一个商业销售系l中的几个主要业务进行徏模?我们的设计对象是一个商场的商业销售系l。商Z设有业务部、仓库、若q柜台组及收银台{,业务部负责组l进货、保及销售,仓库对购q的商品q行保管Q而柜台则是进行商品零售的场所Q收银台作ؓ大厦财务出纳的收Ƅ负责零售商品的收ƾ?1. 现有pȝ描述 该商场现有部门如下: 家用电器l理部、家用电器大件柜、家用电器小件柜Q?五金交电l?..  <a href='http://www.tkk7.com/jelver/articles/34947.html'>阅读全文</a><img src ="http://www.tkk7.com/jelver/aggbug/34947.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/jelver/" target="_blank">冰河快狼</a> 2006-03-13 00:10 <a href="http://www.tkk7.com/jelver/articles/34947.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ERwin相关概念快速入?albertyi原创)http://www.tkk7.com/jelver/articles/34454.html冰河快狼冰河快狼Thu, 09 Mar 2006 05:14:00 GMThttp://www.tkk7.com/jelver/articles/34454.htmlhttp://www.tkk7.com/jelver/comments/34454.htmlhttp://www.tkk7.com/jelver/articles/34454.html#Feedback0http://www.tkk7.com/jelver/comments/commentRss/34454.htmlhttp://www.tkk7.com/jelver/services/trackbacks/34454.html
1、如果只做文档,可以选择只徏立logical view2、如果是做项目,需要同时用Logical view 和physical view3、一般Logical view是用于做文档的,而physical view是用于生成或者导本的4、表之间的三U连接线Q第一U用于把?中的主键插入到表2中的外键Q且插入的作2的主键第二种用于多对多,很少用到W一U用于把?中的主键插入到表2中的外键Q且插入的不作ؓ?的主?BR>
5、Logical中的和physical中对应的表的名称可以不一P一般在physical中的表的名称用英文名U在Logical中的表的名称则无所谓,如果需要可以用中文

6、在Physical view中的Tools中的[Forward Engineer/Schema Generation]中在右侧的表中用对勾可以选择需要操作的目

点击【preview】可以看到脚本,可以复制q来Ҏp是脚本了点击【report】可以直接导本点凅RGenerate】则可以直接q接到数据库Q把相关的Scheme都徏立v?BR>
7、在Logical view的一个Entity上右键点击,选择attributesQ就q入了给表加入column的界面了在General中选择一U基本类?Domain)比如string后,p加入一个名UCQAttribute name是Logical view中的名字Column name是用于生成脚本的名U。在General中的Primary Key的checkbox是选ؓ主键的地方了。在DataType中就能设定具体的数据cdQ比如VARCHAR2,NUMBER{?BR>
8、关于烦引和U束的徏立右键在Entity上,选择Key Groupp新徏U束?BR>
9、在Attribute中选择Datatypep在Validate中选择q个column相关的约束,在Default中选择q个column的默认g

10、关于Domains的概念Domain的概念在Sql server中是支持的,可以在脚本的最开始就定义一堆的Domain,然后在其后的脚本中都引用相关的域名,而不用直接原始的数据cd了?BR>
for exampleQ在一个项目的数据库设计中卡号用得非常的多Q所以在ERwin中Logical view中选择Domain,然后右键点击? <unkonwn>QnewQ就能创ZU新的Domain在叫做Cardseries。选择property可以l他选择相关的属性,比如选择Datatype为VARCHAR(18)Q还可以l它选择U束{等?BR>
q个新徏的Domain p在这个项目中方便的用了?BR>
11、关于Subject Area的概念当整个目设计表比较多的时候,很难在一个view中连接清楚所有的表的之间的关p这样就需要在Subject Area中分多个AreaQ把相关的表攑ֈ相关的的Area中去q接关系Q这h较方便设计?BR>
1>右键点在一个相应的Area上,然后go to Q就能看到那个Area相应的View2>右键Q?gt;property,p讄当前Area中需要哪些表,其中比较有用的一l按钮是最后一l?两个)Q能把选中的要加入Area的表的相关的MUAncester和NUDescendant同时加入AreaQ至于M和N可以自己选择Q非常方ѝ?BR>
注意Q在M非主Area中新建的Entity都会?lt;Main Subject Area>中有一份,删除也是同时q行?img src ="http://www.tkk7.com/jelver/aggbug/34454.html" width = "1" height = "1" />

冰河快狼 2006-03-09 13:14 发表评论
]]>
高 DAO ~程http://www.tkk7.com/jelver/articles/32010.html冰河快狼冰河快狼Wed, 22 Feb 2006 12:29:00 GMThttp://www.tkk7.com/jelver/articles/32010.htmlhttp://www.tkk7.com/jelver/comments/32010.htmlhttp://www.tkk7.com/jelver/articles/32010.html#Feedback0http://www.tkk7.com/jelver/comments/commentRss/32010.htmlhttp://www.tkk7.com/jelver/services/trackbacks/32010.html
内容Q?/B>
DAO 基础
事务界定
使用 JDBC q行事务界定
JTA 概述
使用 JTA 的事务界?/FONT>
用于事务控制?JTA Ҏ
使用 JTA ?JDBC
选择最好的方式
日志记录?DAO
DAO 中的异常处理
实现实例QMovieDAO
l束?/FONT>
参考资?/FONT>
关于作?/FONT>
Ҏ文的评h
相关内容Q?/B>
使用 SDAO q行 J2EE 试的分步方?/FONT>
Create persistent application data with Java Data Objects
理解 JTS -- 事务处理?/FONT>
developerWorks Toolbox subscription
Java 专区中还?
教学
工具与?/FONT>
代码与组?/FONT>
所有文?/FONT>
实用技?/FONT>
1.2学习~译更好?DAO 的技?/SPAN>
Sean C. Sullivan (dao-article@seansullivan.com)
J2EE 开发h员用数据访问对?Data Access Object DAO)设计模式Q以便将低别的数据讉K逻辑与高U别的业务逻辑分离。实?DAO 模式涉及比编写数据访问代码更多的内容。在本文中,Java 开发h?Sean C. Sullivan 讨论?DAO ~程中三个常常被忽略的方面:事务界定、异常处理和日志记录?/FONT>

在过?18 个月中,我参加了一个由有才华的软g工程师组成的组Q构建定制的、基?Web 的供应链理应用E序。我们的应用E序讉K范围q泛的持久性数据,包括配送状态、供应链衡量(metrics)、库存、货q发、项目管理数据和用户信息。我们用 JDBC API q接到我们公司的不同数据库^CQƈ在整个应用程序中使用 DAO 设计模式?/FONT>

?1 昄了应用程序和数据源之间的关系Q?/FONT>

?1. 应用E序和数据源
应用E序和数据源

在整个应用程序中使用数据讉K对象(DAO)使我们可以将底层数据讉K逻辑与业务逻辑分离开来。我们构Z为每一个数据源提供 GRUD (创徏、读取、更新、删?操作?DAO cR?/FONT>

在本文中Q我ؓ您介l构建更好的 DAO cȝ DAO 实现{略和技术。更切地说Q我讨论日志、异常处理和事务界定。您学到如何将q三者结合到自己?DAO cM。本文假定您熟悉 JDBC API、SQL 和关pL据库~程?/FONT>

我们以?DAO 设计模式和数据访问对象的概述开始?/FONT>

DAO 基础
DAO 模式是标?J2EE 设计模式之一。开发h员用q种模式底层数据访问操作与高层业务逻辑分离开。一个典型的 DAO 实现有以下组Ӟ

  • 一?DAO 工厂c?
  • 一?DAO 接口
  • 一个实C DAO 接口的具体类
  • 数据传输对象(有时UCؓ值对?

具体?DAO cd含访问特定数据源的数据的逻辑。在下面一节中您将学习设计和实现数据访问对象的技术。有?DAO 设计模式的更多内容请参阅 参考资?/FONT>?/FONT>

事务界定
关于 DAO 要记住的重要一Ҏ它们是事务性对象。由 DAO 所执行的每一个操?-- 如创建、更新或者删除数?-- 都与一个事务相兌。因此,事务界定的概念就变得特别重要了?/FONT>

事务界定是定义事务边界的方式。J2EE 规范描述了两U事务界定的模型Q编E式(programmatic)和声明式(declarative)。表 1 分析了这两种模型Q?/FONT>

?1. 两种事务界定的模?/B>
声明式事务界?/FONT> ~程式事务界?/FONT>
E序员用 EJB 部v描述W声明事务属性?/FONT> E序员负责编写事务逻辑?/FONT>
q行时环?EJB 容器)用这些属性自动管理事务?/FONT> 应用E序通过一?API 控制事务?/FONT>

我们侧重于~程式事务界定?/FONT>

设计考虑
如前所qͼDAO 是事务性对象。一个典型的 DAO 执行像创建、更新和删除q样的事务性操作。在设计 DAO Ӟ首先要问自己以下问题Q?/FONT>

  • 事务要如何开始?
  • 事务应如何结束?
  • 哪一个对象将负责开始一个事务?
  • 哪一个对象将负责l束一个事务?
  • DAO 是否要负责事务的开始和l束Q?
  • 应用E序是否需要通过多个 DAO 讉K数据Q?
  • 事务涉及C?DAO q是多个 DAOQ?
  • 一?DAO 是否调用另一?DAO 的方法?

了解上述问题的答案将有助于您选择最适合?DAO 的事务界定策略。在 DAO 中有两种主要的界定事务的{略。一U方式是?DAO 负责界定事务Q另一U将事务界定交给调用q个 DAO Ҏ的对象处理。如果选择了前一U方式,那么将事务代码嵌入?DAO 中。如果选择后一U方式,那么事务界定代码是?DAO cd面。我们将使用单的代码CZ帮助您更好理解每一U方式是如何工作的?/FONT>

清单 1 昄了一个有两种数据操作?DAOQ创建和更新Q?/FONT>

清单 1. DAO Ҏ
  public void createWarehouseProfile(WHProfile profile); public void updateWarehouseStatus(WHIdentifier id, StatusInfo status); 

清单 2 昄了一个简单的事务。事务界定在 DAO cd面。注意在q个例子中调用者是如何在一个事务中l合多个 DAO 操作的?/FONT>

清单 2. 调用者管理的事务
  tx.begin(); // start the transaction dao.createWarehouseProfile(profile); dao.updateWarehouseStatus(id1, status1); dao.updateWarehouseStatus(id2, status2); tx.commit(); // end the transaction 

q种事务界定{略对于需要在一个事务中讉K多个 DAO 的应用程序特别有用?/FONT>

可以?JDBC API 或?Java 事务 API(Java Transaction API JTA)实现事务界定?JDBC 事务界定?JTA 事务界定要简单,但是 JTA 提供了更多的灉|性。在下面一节中我将更深入地分析事务界定的机制?/FONT>

?JDBC q行事务界定
JDBC 事务是用 Connection 对象控制的。JDBC Connection 接口(java.sql.Connection)提供了两U事务模式:自动提交和手工提交?CODE>java.sql.Connection 提供了以下控制事务的ҎQ?/FONT>

  • public void setAutoCommit(boolean)
  • public boolean getAutoCommit()
  • public void commit()
  • public void rollback()

清单 3 昄了如何用 JDBC API 界定一个事务:

清单 3. ?JDBC API q行事务界定
  import java.sql.*; import javax.sql.*; // ... DataSource ds = obtainDataSource(); Connection conn = ds.getConnection(); conn.setAutoCommit(false); // ... pstmt = conn.prepareStatement("UPDATE MOVIES ..."); pstmt.setString(1, "The Great Escape"); pstmt.executeUpdate(); // ... conn.commit(); // ... 

使用 JDBC 事务界定Ӟ您可以将多个 SQL 语句l合C个事务中。JDBC 事务的一个缺Ҏ事务的范围局限于一个数据库q接。一?JDBC 事务不能跨越多个数据库。在下面Q我们将看一下如何用 JTA q行事务界定。因?JTA 不像 JDBC 那样有名Q所以我们首先做一个简介?/FONT>

JTA ?/FONT>
Java 事务 API(JTA) 及其同门兄弟 Java 事务服务(Java Transaction Service JTS)?J2EE q_提供了分布式事务服务。一?I xmlns="">分布式的事务涉及一个事务管理器和一个或者多个资源管理器。一?I xmlns="">资源理?/I>是Q何类型的持久性的数据存储。事务管理器负责协调所有事务参与者之间的通信。事务管理器与资源管理器之间的关pd?2 所C:

?2. 一个事务管理器和资源管理器
一个事务管理器和资源管理器

JTA 事务?JDBC 事务功能更强。JDBC 事务局限ؓ一个数据库q接Q?JTA 事务可以有多个参与者。所有下?Java q_lg都可以参?JTA 事务Q?/FONT>

  • JDBC q接
  • JDO PersistenceManager 对象
  • JMS 队列
  • JMS 主题
  • 企业 JavaBeans
  • W合 J2EE q接体系l构(J2EE Connector Architecture)规范的资源适配?

使用 JTA 的事务界?/FONT>
要用 JTA q行事务界定Q应用程序要调用 javax.transaction.UserTransaction 接口中的Ҏ。清?4 昄了对 UserTransaction 对象的典?JNDI 查询Q?/FONT>

清单 4. 一个对 UserTransaction 对象?/FONT> JDNI 查询
  import javax.transaction.*; import javax.naming.*; // ... InitialContext ctx = new InitialContext(); Object txObj = ctx.lookup("java:comp/UserTransaction"); UserTransaction utx = (UserTransaction) txObj; 

当应用程序找C UserTransaction 对象后,可以开始事务了Q如清单 5 所C:

清单 5. ?JTA 开始一个事?/FONT>
  utx.begin(); // ... DataSource ds = obtainXADataSource(); Connection conn = ds.getConnection(); pstmt = conn.prepareStatement("UPDATE MOVIES ..."); pstmt.setString(1, "Spinal Tap"); pstmt.executeUpdate(); // ... utx.commit(); // ... 

当应用程序调?CODE> commit()Ӟ事务理器用一个两阶段的提交协议结束事务?/FONT>

控制事务?JTA Ҏ
javax.transaction.UserTransaction 接口提供了以下事务控制方法:

  • public void begin()
  • public void commit()
  • public void rollback()
  • public int getStatus()
  • public void setRollbackOnly()
  • public void setTransactionTimeout(int)

应用E序调用 begin() 开始事务。应用程序调?commit() 或?CODE> rollback() l束事务。参?/FONT>参考资?/FONT>以了解更多关于用 JTA q行事务理的内宏V?/FONT>

使用 JTA ?JDBC
开发h员通常?DAO cM?JDBC q行底层数据操作。如果计划用 JTA 界定事务Q那么就需要有一个实?javax.sql.XADataSource?CODE>javax.sql.XAConnection ?javax.sql.XAResource 接口?JDBC 驱动E序。一个实Cq些接口的驱动程序将可以参与 JTA 事务。一?CODE> XADataSource 对象是一?XAConnection 对象的工厂?CODE>XAConnections 是参?JTA 事务?JDBC q接?/FONT>

您将需要用应用服务器的理工具讄 XADataSource。从应用服务器和 JDBC 驱动E序的文档中可以了解到相关的指导?/FONT>

J2EE 应用E序?JNDI 查询数据源。一旦应用程序找C数据源对象,它就调用 javax.sql.DataSource.getConnection() 以获得到数据库的q接?/FONT>

XA q接与非 XA q接不同。一定要C XA q接参与?JTA 事务。这意味着 XA q接不支?JDBC 的自动提交功能。同Ӟ应用E序一定不要对 XA q接调用 java.sql.Connection.commit() 或?CODE> java.sql.Connection.rollback()。相反,应用E序应该使用 UserTransaction.begin()?/CODE>UserTransaction.commit() ?CODE> serTransaction.rollback()?/FONT>

选择最好的方式
我们讨论了如何用 JDBC ?JTA 界定事务。每一U方式都有其优点Q您需要决定哪一U最适合于您的应用程序?/FONT>

在最q的许多目中,我们组是用 JDBC API q事务界定来构徏 DAO cȝ。这?DAO cd以ȝ如下Q?/FONT>

  • 事务界定代码嵌入?DAO cM?
  • DAO cM?JDBC API q行事务界定?
  • 调用者不能界定事务?
  • 事务范围局限于单个 JDBC q接?

JDBC 事务q不L适合复杂的企业应用程序。如果您的事务要跨越多个 DAO 或者多个数据库Q那么下列实现策略也许更合适:

  • 事务?JTA 界定?
  • 事务界定代码?DAO 中分d来?
  • 调用者负责界定事务?
  • DAO 加入一个全局事务?

JDBC 方式׃其简单性而具有吸引力QJTA 方式提供了更大的灉|性。您所选择的实现将取决于应用程序的特定需求?/FONT>

日志记录?DAO
一个良好实现的 DAO cd使用日志记录来捕捉有兛_q行时行为的l节。您可以选择记录异常、配|信息、连接状态、JDBC 驱动E序元数据、或者查询参数。日志对于开发的所有阶D都很有用。我l常在开发时、测试时和生产中分析应用E序日志?/FONT>

在本节,我将展示一个显C如何将 Jakarta Commons Logging 加入?DAO 中的代码CZ。在q之前,让我们回一下一些基本知识?/FONT>

选择日志?/FONT>
许多开发h员用一U原始格式进行日志记录:System.out.println ?CODE> System.err.println?CODE>Println 语句速度快且使用方便Q但是它们没有提供全功能的日志记录系l所h的功能。表 2 列出?Java q_的日志库Q?/FONT>

?2. Java q_的日志库
日志?/FONT> 开放源代码Q?/FONT> URL
java.util.logging 不是 http://java.sun.com/j2se/
Jakarta Log4j ?/FONT> http://jakarta.apache.org/log4j/
Jakarta Commons Logging ?/FONT> http://jakarta.apache.org/commons/logging.html

java.util.logging ?J2SE 1.4 q_上的标准 API。不q,大多数开发h员同?Jakarta Log4j 提供了更多的功能和更大的灉|性。Log4j 优于 java.util.logging 的一Ҏ它同时支?J2SE 1.3 ?J2SE 1.4 q_?/FONT>

Jakarta Commons Logging 可以?CODE> java.util.logging 或?Jakarta Log4j 一同用。Commons Logging 是一个日志抽象层Q它隔离了应用程序与底层日志实现。?Commons LoggingQ您可以通过改变配置文g更换底层日志实现。Commons Logging ?Jakarta Struts 1.1 ?Jakarta HttpClient 2.0 中用?/FONT>

一个日志记录示?/FONT>
清单 7 昄了如何在 DAO cM使用 Jakarta Commons LoggingQ?/FONT>

清单 7. DAO cM?Jakarta Commons Logging
 import org.apache.commons.logging.*; class DocumentDAOImpl implements DocumentDAO { static private final Log log = LogFactory.getLog(DocumentDAOImpl.class); public void deleteDocument(String id) { // ... log.debug("deleting document: " + id); // ... try { // ... data operations ... } catch (SomeException ex) { log.error("Unable to delete document", ex); // ... handle the exception ... } } } 

日志记录是所有Q务关键型应用E序的重要部分。如果在 DAO 中遇到故障,那么日志通常可以提供判断出错位置的最好信息。将日志加入?DAO 可以保证您有Zq行调试和故障排除?/FONT>

DAO 中的异常处理
我们讨论q了事务界定和日志,现在对于如何在数据访问对象上应用它们有了更深入的理解。我们的W三个和最后一个讨题是异常处理。遵从几个简单的异常处理指导可以使您?DAO 更容易用、更健壮及更易于l护?/FONT>

在实?DAO 模式Ӟ考虑以下问题Q?/FONT>

  • DAO 的公共接口中的方法是否抛出检查过的异常?
  • 如果是的话,抛出何种查过的异常?
  • ?DAO 实现cM如何处理异常Q?

在?DAO 模式的过E中Q我们的组开发了一些处理异常的原则。遵从这些原则可以极大地改进您的 DAOQ?/FONT>

  • DAO Ҏ应该抛出有意义的异常?BR>
  • DAO Ҏ不应该抛?java.lang.Exception?CODE>java.lang.Exception 太一般化了。它不传递关于底层问题的M信息?BR>
  • DAO Ҏ不应该抛?CODE> java.sql.SQLException。SQLException 是一个低U别?JDBC 异常。一?DAO 应该力争装 JDBC 而不是将 JDBC 公开l应用程序的其余部分?BR>
  • 只有在可以合理地预期调用者可以处理异常时QDAO 接口中的Ҏ才应该抛出检查过的异常。如果调用者不能以有意义的方式处理q个异常Q那么考虑抛出一个未查的(q行?异常?BR>
  • 如果数据讉K代码捕获了一个异常,不要忽略它。忽略捕L异常?DAO 是很难进行故障诊断的?BR>
  • 使用链接的异常将低别的异常转化为高U别的异常?BR>
  • 考虑定义标准 DAO 异常cRSpring Framework (参阅参考资?/FONT>)提供了很好的一套预定义?DAO 异常cR?

有关异常和异常处理技术的更多信息参阅参考资?/FONT>?/FONT>

实现实例Q?MovieDAO
MovieDAO 是一个展C本文中讨论的所有技术的 DAOQ事务界定、日志和异常处理。您可以?/FONT>参考资?/FONT>一节中扑ֈ MovieDAO 源代码。代码分Z个包Q?/FONT>

  • daoexamples.exception
  • daoexamples.movie
  • daoexamples.moviedemo

DAO 模式的这个实现包含下面列出的cd接口Q?/FONT>

  • daoexamples.movie.MovieDAOFactory
  • daoexamples.movie.MovieDAO
  • daoexamples.movie.MovieDAOImpl
  • daoexamples.movie.MovieDAOImplJTA
  • daoexamples.movie.Movie
  • daoexamples.movie.MovieImpl
  • daoexamples.movie.MovieNotFoundException
  • daoexamples.movie.MovieUtil

MovieDAO 接口定义?DAO 的数据操作。这个接口有五个ҎQ如下所C:

  • public Movie findMovieById(String id)
  • public java.util.Collection findMoviesByYear(String year)
  • public void deleteMovie(String id)
  • public Movie createMovie(String rating, String year, String, title)
  • public void updateMovie(String id, String rating, String year, String title)

daoexamples.movie 包包?MovieDAO 接口的两个实现。每一个实C用一U不同的方式q行事务界定Q如?3 所C:

?3. MovieDAO 实现
MovieDAOImpl MovieDAOImplJTA
实现 MovieDAO 接口? ?/FONT> ?/FONT>
通过 JNDI 获得 DataSourceQ?/FONT> ?/FONT> ?/FONT>
?DataSource 获得 java.sql.Connection 对象Q?/FONT> ?/FONT> ?/FONT>
DAO 在内部界定事务? ?/FONT> ?/FONT>
使用 JDBC 事务Q?/FONT> ?/FONT> ?/FONT>
使用一?XA DataSourceQ?/FONT> ?/FONT> ?/FONT>
参与 JTA 事务Q?/FONT> ?/FONT> ?/FONT>

MovieDAO 演示应用E序
q个演示应用E序是一个名?daoexamples.moviedemo.DemoServlet ?servlet cR?CODE>DemoServlet 使用q两?Movie DAO 查询和更新表中的电媄数据?/FONT>

q个 servlet 展示了如何将支持 JTA ?MovieDAO ?Java 消息服务(Java Message Service)l合C个事务中Q如清单 8 所C?/FONT>

清单 8. ?MovieDAO ?JMS 代码l合C个事务中
  UserTransaction utx = MovieUtil.getUserTransaction(); utx.begin(); batman = dao.createMovie("R", "2008", "Batman Reloaded"); publisher = new MessagePublisher(); publisher.publishTextMessage("I'll be back"); dao.updateMovie(topgun.getId(), "PG-13", topgun.getReleaseYear(), topgun.getTitle()); dao.deleteMovie(legallyblonde.getId()); utx.commit(); 

要运行这个演C应用程序,需要在应用服务器上配置一?XA 数据源和一个非 XA 数据源。然后,部v daoexamples.ear 文g。这个应用程序可以在M兼容 J2EE 1.3 的应用服务器上运行。参?/FONT>参考资?/FONT>以获?EAR 文g和源代码?/FONT>

l束?/FONT>
正如本文所展示的,实现 DAO 模式需要做比编写低U别的数据访问代码更多的工作。现在,通过选择一个适合您的应用E序的事务界定策略、通过?DAO cM加入日志记录Q以及通过遵从几项单的异常处理原则Q您可以构徏更好?DAO?/FONT>

参考资?/FONT>



冰河快狼 2006-02-22 20:29 发表评论
]]>
վ֩ģ壺 ˾ƷƵ| ҹþþþüŮӰԺ| | պŷ| ŷ޾Ʒһ| ҹ | ɫһһһһƵѿ| 91޹˾Ʒ| ŷAۺһ| һһƬѲ| ŷǾƷһ| 91ѸƷ| APPѹۿƵ| ŷ޾ƷƵѹۿ| ޵һseվ| һɫþۺ޾Ʒ| ɾƷһ| ޹ƷþSM| ޾Ʒ| ޹պ߹Ƶ| ҹɫ˽ӰԺ߹ۿ| ѸӰƬһ| ѹۿavëƬվ| ĻmvѸӰ| 18վڵ| 67paoǿ| þݹѹۿ| Ʒ߹ۿ| ëƬ߲ѹۿ| avڹƬ| ˾Ʒһѿ| һˮëƬѿ| վvƬ| һƵۿwww| aëƬëƬѹۿ| Ůҹ24ʽƵ | AvרDVD| ˳߹ۿ| ޾Ʒר߲| AVרAVëվ| ޲͵V͵Vɫ|