??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲第一图区,国产精品午夜一区二区欲梦,国产精品久久久久999 http://www.aygfsteel.com/oofrank/交流blog QQ:421057986 <a >oofrank@donews</a> zh-cn Sun, 18 May 2025 17:08:28 GMT Sun, 18 May 2025 17:08:28 GMT 60 DAO-持久?领域对象-贫血模型 http://www.aygfsteel.com/oofrank/archive/2006/04/10/40337.html兼听则明 兼听则明 Mon, 10 Apr 2006 14:21:00 GMT http://www.aygfsteel.com/oofrank/archive/2006/04/10/40337.html http://www.aygfsteel.com/oofrank/comments/40337.html http://www.aygfsteel.com/oofrank/archive/2006/04/10/40337.html#Feedback 4 http://www.aygfsteel.com/oofrank/comments/commentRss/40337.html http://www.aygfsteel.com/oofrank/services/trackbacks/40337.html 原文
关于"贫血模型"的讨论几乎没有停止过,在openfans.org的开发过E中,我们也讨Z很久,我觉的有很多东西应该C? 明确一下意思先: DAO:数据操作对象,会操作数据库 持久?能提供对象持久化服务的一pdlg或服?br />领域对象:描述领域模型的对?是通过业务分析q行pȝ建模的?br />?
血模型:是domain
object只有属性的getter/setterҎ的纯数据c,所有的业务逻辑完全׃个所谓的Manager来完?又称
TransactionScript)Q这U模型下的domain object被Martin FowlerUC为“血的domain
object?br />常见的类基本l构如下: 一个业务数据类叫做ItemQ?br />一个DAO接口cd做ItemDao 一个DAO接口实现cd做ItemDaoHibernateImpl 一个业务逻辑cd做ItemManager(或者叫做ItemService). 观察上面的几个类很容易发现问? 1:Item和ItemManager实际是操作与数据的关p?实际完成的就是经典OO中的一个对象的能力; 2:当有许多Item?cȝ变得很庞?产生很多 xxxDao xxxImpl xxxManager 其中包含大量重复代码; ?lt;<重构>>的观?上述代码存在以下臭味: 1:重复的代码 ?xxxDao xxxImpl xxxManager(通常) 2:霰弹式修改,一个变化媄响多个类,cM间不够高内聚 item变化-->Dao,Impl,Manager均要变动 3:依恋情结,两个cM间互怽用过?item<->Manager 4:ql承体系,当增加一个新cLL要增加另一个类 5:夸夸其谈未来?在没有Q何暗C的情况下考虑扩展 Dao,实际HibernateImpl可能nq内是唯一的Dao实现 6:U稚的数据类Q只有数据的c?item 我觉?贫血模型 是系l分析设计方向性错误的产物: 1:没有q行领域建模---以数据表l构Z?而不是业务模型ؓ中心的思考方?使设计h员选择Item虑问题的出发点 2:DAO与持久层h---我们需要的一U持久化服务,DAO紧紧是提供数据操作能力而已,Hibernate是一U高U的服务(他已l包含了DAO,而不是相?,已经完成了所有的持久层服? 3:q于低偶?--一些本来一些提供单一职责的内容分散在多个单元中 客户?依赖更多的接?而忘C高内聚原? 4:Spring的能力限?--׃Spring现阶D不支持对于领域模型的服务注?使设计h员将操作和数据分开,q将领域变ؓDataOnly? (Spring2.0在很大E度上解册个问? 我认好的解决Ҏ: 首先领域建模,建立领域模型-->合ƈ前面所说的Item和ItemManager成ؓ domainItem;对于数据库服? 1:如果考虑领域层包含数据操作能?则徏立DAOq择其它好的DAOҎ比如IBATIS或Hibernate之类的组? 2:如果考虑数据库(或其他存储界?存储考虑在领域之外成为持久层, a:则或者对持久层框架同时徏?同时选择合适的lg为持久层服务提供存储服务(包括DAO--亦可选择IBATIS/Hibernatelg), b:或者直接用Hibernate/JDO{框架实现持久化服务,领域层直接用持久层服务,寚w域对象进行持久化和反持久?从持久层获取以持久化的对?. 其他:
实际?作ؓ一U解x?所?贫血模型"的具体?q不会有太大的问?其是用一些代码生成工h已经做好相应的基本框架时,很多软g的核心h
值都在于对客h供的服务,而其内部则成为黑?我们只要合理的解决业务问?是"王道"?对于代码的臭?可以慢慢重构--q也需要成本呀. 再其? 有h?我们的业务就是CRUD,领域模型只有数据cd_?我觉的这是搞错了方向------只有CRUD?只有处理CRUD的那些类才有必要q行建模(他们才是领域模型),而所谓的User\Item{数据类则完全没有必要进行徏?更不要谈领域? 贫血之外: 实际?软g\OOҎ的外延大的很,更多问题与数据库存储无关(但也有血问题),所以徏模才是根?OOҎ的原则才是我们必L握的. ]]> SQLServer的一个bug http://www.aygfsteel.com/oofrank/archive/2006/02/05/29643.html兼听则明 兼听则明 Sun, 05 Feb 2006 14:37:00 GMT http://www.aygfsteel.com/oofrank/archive/2006/02/05/29643.html http://www.aygfsteel.com/oofrank/comments/29643.html http://www.aygfsteel.com/oofrank/archive/2006/02/05/29643.html#Feedback 0 http://www.aygfsteel.com/oofrank/comments/commentRss/29643.html http://www.aygfsteel.com/oofrank/services/trackbacks/29643.html 我有一个表使用字符cd存储数字?惌行汇总计: sum(case when isnumeric(FieldName)=0 then 0 else cast (FieldName as numeric) end) 单试了一下没有问题,可是今天数据中有一??.1234567E7?nbsp; isnumericq回1 cast q回错误 呜呜。。。?br>怎么?..... ]]>使用Quartz要注意的一个问?/title> http://www.aygfsteel.com/oofrank/archive/2006/01/23/28979.html兼听则明 兼听则明 Sun, 22 Jan 2006 16:52:00 GMT http://www.aygfsteel.com/oofrank/archive/2006/01/23/28979.html http://www.aygfsteel.com/oofrank/comments/28979.html http://www.aygfsteel.com/oofrank/archive/2006/01/23/28979.html#Feedback 0 http://www.aygfsteel.com/oofrank/comments/commentRss/28979.html http://www.aygfsteel.com/oofrank/services/trackbacks/28979.html 当设|一个Schedule的startDate早于 new Date()Qƈ且调度周期又触发于startDate和new Date()之间Ӟ׃立即触发当前job。简单的解决方式是将startDate设ؓnew Date(). ]]> 使用abator自动生成ibatis代码的经? 及碰到的问题的解x?/title> http://www.aygfsteel.com/oofrank/archive/2006/01/21/28874.html兼听则明 兼听则明 Sat, 21 Jan 2006 05:51:00 GMT http://www.aygfsteel.com/oofrank/archive/2006/01/21/28874.html http://www.aygfsteel.com/oofrank/comments/28874.html http://www.aygfsteel.com/oofrank/archive/2006/01/21/28874.html#Feedback 12 http://www.aygfsteel.com/oofrank/comments/commentRss/28874.html http://www.aygfsteel.com/oofrank/services/trackbacks/28874.html 1:abator下蝲:http://ibatis.apache.org/abator.html 2:abator安装到eclipse?br>3:此时可以新徏一U文件类型:Abator for iBATIS Configuration File,建立一?br>4:在 jdbcConnection 中设|要mapping的数据库的jdbcq接 classPathEntry 是你的jdbc driverc\?br>5:javaModelGenerator,sqlMapGenerator,daoGenerator
分别讄 java dataObject、sql mapping文g?DAO 接口、实现类的生成位|?targetPackage
目标包,targetProjectQeclipse目 6:daoGenerator 中可以设|属性 type: ibatis 或 spring 指定生成的dao实现cL使用com.ibatis.dao.client.template.SqlMapDaoTemplate q是 org.springframework.orm.ibatis.support.SqlMapClientDaoSupport 7: table ?tableName 指定要处理的表名 可以有多个table 8:table中可以包含子元素 generatedKey: 使InsertҎ可以q回|Q由指定的column mapping 9:generatedKey中的sqlStatement属性可以是获取sequence的SQLQ也可以是获取自增值的SQL 比如:Oracle?select theSequence.nextVal from dual SQLServer?SELECT @@IDENTITY as column_name 10:保存文gQ选中文gQ右键菜单选择Generate iBATIS Artifacts! ok...使用abtor生成的iBatis代码出现xml解析错误的解x?/u> 如果按上q方式生成的代码有xml解析错误Q?nbsp; 请下?a >q个 注意Q该文g名ؓAbator.rar.txt实际是一个rar文gQ只是上传服务器有文件类型限?所以只好加了扩展名txt?br>请去?txt后解压?br> 使用 org.apache.ibatis.abator.core_0.5.1.jar 替换调你?eclipse\plugins 的同名文?卛_?br> 然后重新生成代码?OK 应该可以?... 我改了一点代码,需要可以留a?img src ="http://www.aygfsteel.com/oofrank/aggbug/28874.html" width = "1" height = "1" /> ]]> 在eclipseQplugin开发中到的怪问题:(eclipse 3.1.1 + wtp1.0) http://www.aygfsteel.com/oofrank/archive/2006/01/20/28819.html兼听则明 兼听则明 Fri, 20 Jan 2006 10:45:00 GMT http://www.aygfsteel.com/oofrank/archive/2006/01/20/28819.html http://www.aygfsteel.com/oofrank/comments/28819.html http://www.aygfsteel.com/oofrank/archive/2006/01/20/28819.html#Feedback 0 http://www.aygfsteel.com/oofrank/comments/commentRss/28819.html http://www.aygfsteel.com/oofrank/services/trackbacks/28819.html objectContributionQobjectClass*: org.eclipse.core.resources.IFile 在action的Class代码中: public void selectionChanged(IAction action, ISelection selection) { StructuredSelection ss = (StructuredSelection) selection; this.selectedFile==(IFile)ss.getFirstElement(); //此处抛出异常 } 上述代码的异帔R常奇怪: Ҏ的的跟踪Qss.getFirstElement()q回值是FileQ该cdCIFile接口Q?br>而且我用 ss.getFirstElement().getClass().isAssignableFrom(IFile.class)q回是falseQ?br>真是奇怪!Q-Q有人知道ؓ什么吗Q?br> 另外在实践eclipse plugin开发过E中也有几个心得Q?肯定能用Q但未必最? 1、如果开发pluginQ所有的依赖库都要包含到 Plug-in Dependencies 中;而不能只是引入到工程中?br>2、如何输出到consoleQ?br>MessageConsole mc=new MessageConsole("****",null); IConsole[] cs=new IConsole[1]; cs[0]=mc; ConsolePlugin.getDefault().getConsoleManager().addConsoles(cs); mc.activate(); PrintStream out=new PrintStream( mc.newOutputStream()); out.println("*******."); 3、如何获取依赖工E的输出路径Q?br>selectedProjectQ当前工E-Q-q户选择 String[] ps= selectedProject.getRequiredProjectNames(); IWorkspace w= selectedProject.getProject().getWorkspace(); for(int i=0;i<ps.length;i++){ IResource r=w.getRoot().findMember(ps[i]); try{ IJavaProject jp=new JavaProject((IProject)r,null); File source=new File(jp.getProject().getLocation().append(jp.getOutputLocation().removeFirstSegments(1)).toOSString()); //作你的事?.... }catch(Exception e){ //不是javaProject e.printStackTrace(); } 4、如何用进度DialogQ?br>Shell shell = new Shell(); ProgressMonitorDialog dialog = new ProgressMonitorDialog(shell); IRunnableWithProgress thread = new SomeRunner(shell); dialog.run(true, false, thread); //============================= private class SomeRunner implements IRunnableWithProgress { public void run(IProgressMonitor monitor)throws InvocationTargetException, InterruptedException { monitor.beginTask("一些信?, 数?d作量); for(;;){ // 一些工?br> monitor.worked(数?已完成工作量); //实际中,我得情况不太相符Q不明白Q但差不?:( monitor.setTaskName("一些信?); // 一些工?nbsp; } monitor.done(); } } ]]> Spring 中的异常悖论 http://www.aygfsteel.com/oofrank/archive/2006/01/19/28702.html兼听则明 兼听则明 Thu, 19 Jan 2006 13:45:00 GMT http://www.aygfsteel.com/oofrank/archive/2006/01/19/28702.html http://www.aygfsteel.com/oofrank/comments/28702.html http://www.aygfsteel.com/oofrank/archive/2006/01/19/28702.html#Feedback 19 http://www.aygfsteel.com/oofrank/comments/commentRss/28702.html http://www.aygfsteel.com/oofrank/services/trackbacks/28702.html 首先要明两个问题: 1、系l隔d则: 即系l间依赖应该是清晰的Q不因ؓ一个系l的故障影响其他pȝQ甚x个系l?br>2、简单应用习惯: 普通程序员只会处理checked Exception,负责ȝE序员会处理被调用的函数可能抛出的异?Ҏ源码或javadoc) 我们到一个情况: 使用Spring?init Ҏ初试化一个bean--一个用Qutarz的调度程序。初试化q程中会抛出RuntimeExceptionQ从而造成Spring容器的整个初试化p|。首先我们修改了E序Q捕获了所有异常,随后在编码指南中加入了一句话Q?所有用Spring-init机制初试化的cddinit中捕h有异常:Exception"。因为只有如此才能保证整个系l不会因为局部问题而完全瘫痪?br> 我觉得这是Spring对异常处理的一个悖论: 正方Q底层异帔R装成Runtime?l过几次包装--->单应用习?-->异常被抛出领域层(init场景?由Spring处理) 反方: 一个类的失败可以造成整个pȝ的失?--->Spring被RuntimeException宕掉---->不符合系l隔d?br> 当然充分的测试可能可以解册个问题:但是要注意,试只能证明pȝ有bugQ不能证明系l没有bug?br> 解决ҎQ?br>1、好的设计习惯:应该隔ȝpȝ隔离开-->使用不同的Spring配置文g. 2、接口层错误处理Q在接口层应该尽量对可以处理的异常进行处?然后以合理的方式传递给上层. PS:在与Z互的pȝ中都应该l最l用户合理的错误提示Q所以表现层应该量捕获非业务的RuntimeExceptionl最l用h好的操作感受?br> ]]>白马非马的面向对象分?/title> http://www.aygfsteel.com/oofrank/archive/2006/01/19/28649.html兼听则明 兼听则明 Thu, 19 Jan 2006 06:16:00 GMT http://www.aygfsteel.com/oofrank/archive/2006/01/19/28649.html http://www.aygfsteel.com/oofrank/comments/28649.html http://www.aygfsteel.com/oofrank/archive/2006/01/19/28649.html#Feedback 4 http://www.aygfsteel.com/oofrank/comments/commentRss/28649.html http://www.aygfsteel.com/oofrank/services/trackbacks/28649.html 以马作ؓq行问题域进行徏模,已知存在白马q种cd。显然存在马的超c,q且马类包含一个属性-颜色Q是否需要徏立白马的子类呢?显而易见的是,当马的颜色属性是白色Ӟ马的一些实例表达了一个白马的Ҏ实例?由此我们可以得知Q白马显然是?Q根据里氏替换原则,子类型必能够替换掉它们的基cdQ显然在分析了马的行为模式以后,我们可以得出l论Q白马可以替换马。-Q-Q!N真的要徏立白马、黑马、X马的子类吗? 我认为可以从以下几方面进行分析?BR> 1、类的职?很大E度上等同于服务能力Q操作方?: 设计一个类Q首先要从类职责的分析入手,一个类要承担响应的职责Q反q来说同L职责应该由同LcL担,否则会造成cL滥,实例孤单的状c如果领域内马和白马承担同样的职责,应该只徏立马一个类Q不应该只见树不见林Q造成不抽象的cȝ产生?BR> 2、类的行为模?当类承担响应职责Ӟ如何扩展)Q?BR> 分析一个类要从cȝ行ؓ模式入手Q既然一个类要承担责任,其承担的责Q表现方式是否一样呢呢?q就是她的行为模式,q也是里氏替换原则主要v作用的地方,如果两个cȝ职责相当Q但行ؓ模式不同则不能成cd子类的关p?比如"著名"的正方Ş不是长方形问?。马c,作ؓ类Q基于一些特D的行ؓ方式Q吃草,?..Q对于白马她的行为模式和马是一LQƈ没有不同Q所以白马是马而非马的同根l承子类。对于长方Ş和正方Ş都是h相同计算面积法(职责)的四方Ş的子cR?BR> Q-Q-Q-Q以下是关于此事的一些扩展分析-Q-Q-Q-Q-Q- 3、子cȝ产生Q?BR> 何时需要生子cdQ是对其父类的职责进行扩展,白马没有对父cȝ职责q行扩展Q所以不是马的子cR首先子c要扩展类Q其ơ子cM能重写或废除类的职责?BR> 4、属性,状态的区别(cȝ? 对于一些类Q在状态不同时Q会有不同的表现(状态机模式),所以,cȝgetterQsetter的部分包含两U不同的Ҏ,对于属于状态的部分Q是我们要仔l分析的Q??马则属于属性类(非状?的域, 一般来Ԍ一个类的实例要能提供相应的差异服务(׃状态不?最好用不变模式[生存周期状态不变]或状态机[生存周期有状?但状态不p用者控制]来实现?BR> 5、抽象类和接?BR> ׃java的单根承特性,很多设计人员不敢定义抽象cMؓl承树根Q一定要先定义马的接口,在徏立抽象马Q作ZU?准规?无可厚非Q但我认是不愿承担责ȝ表现Q有行ؓ的基cd该可?必须?)从类定义开始,避免白马c?一旦马成ؓ接口Q白马的产生更?名正a??的出?来如果发生变化可以通过重构(导出接口和用委?Q解决问题? 6、对象的创徏(l装)和用应该分开 既然对象的状态如此重要,属性有有很大程度的不变?白马在构造时q该是白的Qƈ且一生不?Q而骑马的Z必要求马的属?!),所以,我们应该马的构造和使用分开Q领域模型更清晰。用一些Ioc容器Q比如Springp很好的解册些问题?BR> 7、分析问题的领域 说了q么多,有一个问题;如果有一个马的研I机构,专门对不同颜色的马进行专题研IӞ马的颜色可能会对马的行ؓ有很大媄响,例如战马如果是黄?l色Q哈?更利于伪装,此时"?可能是一个很关键的问题,颜色会媄响到不同的伪装策略,此时白马作为马的一个子cd是必ȝQ所以问题域不同Q类的设计就不同Q生zM的问题域比较清晰(生物学家和厨师对马的理解不同)Q而Y件徏模时往往问题域杂,q也是OO设计时比较困隄问题Q所以分析问题域也是非常重要的设计问题?BR> ]]> 我来?/title> http://www.aygfsteel.com/oofrank/archive/2006/01/19/28646.html兼听则明 兼听则明 Thu, 19 Jan 2006 06:05:00 GMT http://www.aygfsteel.com/oofrank/archive/2006/01/19/28646.html http://www.aygfsteel.com/oofrank/comments/28646.html http://www.aygfsteel.com/oofrank/archive/2006/01/19/28646.html#Feedback 1 http://www.aygfsteel.com/oofrank/comments/commentRss/28646.html http://www.aygfsteel.com/oofrank/services/trackbacks/28646.html ]]>
վ֩ģ壺
º |
ƽ |
|
|
|
|
|
|
|
ʡ |
ʡ |
|
ϲ |
|
կ |
DZɽ |
|
|
¡ |
߮ |
|
|
|
|
|
鴨 |
|
|
|
|
̨ |
|
|
|
|
Ϻ |
ƽ |
Ӱ |
|
˳ |
|