??xml version="1.0" encoding="utf-8" standalone="yes"?>男人的天堂av亚洲一区2区,久久精品国产亚洲AV电影网,亚洲精品综合一二三区在线http://www.tkk7.com/GandofYan/Q-Q-Q-Q-QԒ望星I,心中只剩下一片深?/description>zh-cnSat, 10 May 2025 17:17:12 GMTSat, 10 May 2025 17:17:12 GMT60一个简单的Java集合范围qo(h)的多个方式对?/title><link>http://www.tkk7.com/GandofYan/archive/2014/06/21/415009.html</link><dc:creator>h中立</dc:creator><author>h中立</author><pubDate>Sat, 21 Jun 2014 15:33:00 GMT</pubDate><guid>http://www.tkk7.com/GandofYan/archive/2014/06/21/415009.html</guid><wfw:comment>http://www.tkk7.com/GandofYan/comments/415009.html</wfw:comment><comments>http://www.tkk7.com/GandofYan/archive/2014/06/21/415009.html#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://www.tkk7.com/GandofYan/comments/commentRss/415009.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/GandofYan/services/trackbacks/415009.html</trackback:ping><description><![CDATA[在一个项目里面有q么一个技术需?<br />1.集合中元素个?10M<br />2.Ҏ(gu)上限和下限从一个Set中过滤出满要求的元素集?<br /><br />实际q个是个很典型的技术要? 之前的项目也遇见q?但是因ؓ(f)当时的类库不? 都是直接手写实现? 方式基本{同于第一个方?<br /><br />在这个过E中, 我写了四个方? 基本记录C?<br />W一个方?对Setq行q代器遍? 判断每个元素是否都在上限和下限范围中.如果满则添加到l果集合? 最后返回结果集?<br />            试效果:集合大小100K, q算旉 3000ms+<br />qo(h)部分的逻辑如下:<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; "> 1</span>     <span style="color: #0000FF; ">void</span> filerSet(Set<BigDecimal> targetSet, String lower, String higher) {<br /><span style="color: #008080; "> 2</span>         BigDecimal bdLower = <span style="color: #0000FF; ">new</span> BigDecimal(Double.parseDouble(lower));<br /><span style="color: #008080; "> 3</span>         BigDecimal bdHigher = <span style="color: #0000FF; ">new</span> BigDecimal(Double.parseDouble(higher));<br /><span style="color: #008080; "> 4</span> <br /><span style="color: #008080; "> 5</span>         Set<BigDecimal> returnSet = <span style="color: #0000FF; ">new</span> HashSet<BigDecimal>();<br /><span style="color: #008080; "> 6</span>         <span style="color: #0000FF; ">for</span> (BigDecimal object : targetSet) {<br /><span style="color: #008080; "> 7</span>             <span style="color: #0000FF; ">if</span> (isInRange(object, bdLower, bdHigher)) {<br /><span style="color: #008080; "> 8</span>                 returnSet.add(object);<br /><span style="color: #008080; "> 9</span>             }<br /><span style="color: #008080; ">10</span>         }<br /><span style="color: #008080; ">11</span>     }<br /><span style="color: #008080; ">12</span> <br /><span style="color: #008080; ">13</span>     <span style="color: #0000FF; ">private</span> <span style="color: #0000FF; ">boolean</span> isInRange(BigDecimal object, BigDecimal bdLower,<br /><span style="color: #008080; ">14</span>             BigDecimal bdHigher) {<br /><span style="color: #008080; ">15</span>         <span style="color: #0000FF; ">return</span> object.compareTo(bdLower) >= 0<br /><span style="color: #008080; ">16</span>                 && object.compareTo(bdHigher) <= 0;<br /><span style="color: #008080; ">17</span>     }</div>W二个方? 借助TreeSet, 原始集合q行排序, 然后直接subset.<br />            试效果: 集合大小10M, q算旉: 12000ms+(获得TreeSet) , 200ms(获得l果)<br />qo(h)部分的逻辑如下(非常J琐):<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; ">  1</span>     Set<BigDecimal> getSubSet(TreeSet<BigDecimal> targetSet, String lower,<br /><span style="color: #008080; ">  2</span>             String higher) {<br /><span style="color: #008080; ">  3</span> <br /><span style="color: #008080; ">  4</span>         BigDecimal bdLower = <span style="color: #0000FF; ">new</span> BigDecimal(Double.parseDouble(lower));<br /><span style="color: #008080; ">  5</span>         BigDecimal bdHigher = <span style="color: #0000FF; ">new</span> BigDecimal(Double.parseDouble(higher));<br /><span style="color: #008080; ">  6</span> <br /><span style="color: #008080; ">  7</span>         <span style="color: #0000FF; ">if</span> ((bdHigher.compareTo(targetSet.first()) == -1)<br /><span style="color: #008080; ">  8</span>                 || (bdLower.compareTo(targetSet.last()) == 1)) {<br /><span style="color: #008080; ">  9</span>             <span style="color: #0000FF; ">return</span> <span style="color: #0000FF; ">null</span>;<br /><span style="color: #008080; "> 10</span>         }<br /><span style="color: #008080; "> 11</span> <br /><span style="color: #008080; "> 12</span>         <span style="color: #0000FF; ">boolean</span> hasLower = targetSet.contains(bdLower);<br /><span style="color: #008080; "> 13</span>         <span style="color: #0000FF; ">boolean</span> hasHigher = targetSet.contains(bdHigher);<br /><span style="color: #008080; "> 14</span>         <span style="color: #0000FF; ">if</span> (hasLower) {<br /><span style="color: #008080; "> 15</span>             <span style="color: #0000FF; ">if</span> (hasHigher) {<br /><span style="color: #008080; "> 16</span>                 System.out.println("get start:" + bdLower);<br /><span style="color: #008080; "> 17</span>                 System.out.println("get end:" + bdHigher);<br /><span style="color: #008080; "> 18</span>                 <span style="color: #0000FF; ">return</span> targetSet.subSet(bdLower, <span style="color: #0000FF; ">true</span>, bdHigher, <span style="color: #0000FF; ">true</span>);<br /><span style="color: #008080; "> 19</span>             } <span style="color: #0000FF; ">else</span> {<br /><span style="color: #008080; "> 20</span>                 BigDecimal newEnd = <span style="color: #0000FF; ">null</span>;<br /><span style="color: #008080; "> 21</span>                 System.out.println("get start:" + bdLower);<br /><span style="color: #008080; "> 22</span>                 SortedSet<BigDecimal> returnSet = <span style="color: #0000FF; ">null</span>;<br /><span style="color: #008080; "> 23</span>                 <span style="color: #0000FF; ">if</span> (bdHigher.compareTo(targetSet.last()) != -1) {<br /><span style="color: #008080; "> 24</span>                     newEnd = targetSet.last();<br /><span style="color: #008080; "> 25</span>                 } <span style="color: #0000FF; ">else</span> {<br /><span style="color: #008080; "> 26</span>                     SortedSet<BigDecimal> newTargetSet = targetSet<br /><span style="color: #008080; "> 27</span>                             .tailSet(bdLower);<br /><span style="color: #008080; "> 28</span>                     <span style="color: #0000FF; ">for</span> (BigDecimal object : newTargetSet) {<br /><span style="color: #008080; "> 29</span>                         <span style="color: #0000FF; ">if</span> (object.compareTo(bdHigher) == 1) {<br /><span style="color: #008080; "> 30</span>                             newEnd = object;<br /><span style="color: #008080; "> 31</span>                             <span style="color: #0000FF; ">break</span>;<br /><span style="color: #008080; "> 32</span>                         } <span style="color: #0000FF; ">else</span> <span style="color: #0000FF; ">if</span> (object.compareTo(bdHigher) == 0) {<br /><span style="color: #008080; "> 33</span>                             newEnd = object;<br /><span style="color: #008080; "> 34</span>                             <span style="color: #0000FF; ">break</span>;<br /><span style="color: #008080; "> 35</span>                         }<br /><span style="color: #008080; "> 36</span>                     }<br /><span style="color: #008080; "> 37</span>                 }<br /><span style="color: #008080; "> 38</span>                 returnSet = targetSet.subSet(bdLower, <span style="color: #0000FF; ">true</span>, newEnd, <span style="color: #0000FF; ">true</span>);<br /><span style="color: #008080; "> 39</span>                 <span style="color: #0000FF; ">if</span> (newEnd.compareTo(bdHigher) == 1) {<br /><span style="color: #008080; "> 40</span>                     returnSet.remove(newEnd);<br /><span style="color: #008080; "> 41</span>                 }<br /><span style="color: #008080; "> 42</span>                 <span style="color: #0000FF; ">return</span> returnSet;<br /><span style="color: #008080; "> 43</span>             }<br /><span style="color: #008080; "> 44</span> <br /><span style="color: #008080; "> 45</span>         } <span style="color: #0000FF; ">else</span> {<br /><span style="color: #008080; "> 46</span>             <span style="color: #0000FF; ">if</span> (hasHigher) {<br /><span style="color: #008080; "> 47</span>                 System.out.println("get end:" + bdHigher);<br /><span style="color: #008080; "> 48</span>                 TreeSet<BigDecimal> newTargetSet = (TreeSet<BigDecimal>) targetSet<br /><span style="color: #008080; "> 49</span>                         .headSet(bdHigher, <span style="color: #0000FF; ">true</span>);<br /><span style="color: #008080; "> 50</span>                 BigDecimal newStart = <span style="color: #0000FF; ">null</span>;<br /><span style="color: #008080; "> 51</span>                 SortedSet<BigDecimal> returnSet = <span style="color: #0000FF; ">null</span>;<br /><span style="color: #008080; "> 52</span> <br /><span style="color: #008080; "> 53</span>                 <span style="color: #0000FF; ">if</span> (bdLower.compareTo(targetSet.first()) == -1) {<br /><span style="color: #008080; "> 54</span>                     newStart = targetSet.first();<br /><span style="color: #008080; "> 55</span>                 } <span style="color: #0000FF; ">else</span> {<br /><span style="color: #008080; "> 56</span>                     <span style="color: #0000FF; ">for</span> (BigDecimal object : newTargetSet) {<br /><span style="color: #008080; "> 57</span>                         <span style="color: #0000FF; ">if</span> (object.compareTo(bdLower) != -1) {<br /><span style="color: #008080; "> 58</span>                             newStart = object;<br /><span style="color: #008080; "> 59</span>                             <span style="color: #0000FF; ">break</span>;<br /><span style="color: #008080; "> 60</span>                         }<br /><span style="color: #008080; "> 61</span>                     }<br /><span style="color: #008080; "> 62</span>                 }<br /><span style="color: #008080; "> 63</span>                 returnSet = targetSet.subSet(newStart, <span style="color: #0000FF; ">true</span>, bdHigher, <span style="color: #0000FF; ">true</span>);<br /><span style="color: #008080; "> 64</span> <br /><span style="color: #008080; "> 65</span>                 <span style="color: #0000FF; ">return</span> returnSet;<br /><span style="color: #008080; "> 66</span>             } <span style="color: #0000FF; ">else</span> {<br /><span style="color: #008080; "> 67</span>                 System.out.println("Not get start:" + bdLower);<br /><span style="color: #008080; "> 68</span>                 System.out.println("Not get end:" + bdHigher);<br /><span style="color: #008080; "> 69</span>                 BigDecimal newStart = <span style="color: #0000FF; ">null</span>;<br /><span style="color: #008080; "> 70</span>                 BigDecimal newEnd = <span style="color: #0000FF; ">null</span>;<br /><span style="color: #008080; "> 71</span>                 <span style="color: #0000FF; ">if</span> (bdHigher.compareTo(targetSet.last()) != -1) {<br /><span style="color: #008080; "> 72</span>                     newEnd = targetSet.last();<br /><span style="color: #008080; "> 73</span>                 }<br /><span style="color: #008080; "> 74</span>                 <span style="color: #0000FF; ">if</span> (bdLower.compareTo(targetSet.first()) == -1) {<br /><span style="color: #008080; "> 75</span>                     newStart = targetSet.first();<br /><span style="color: #008080; "> 76</span>                 }<br /><span style="color: #008080; "> 77</span>                 <span style="color: #0000FF; ">for</span> (BigDecimal object : targetSet) {<br /><span style="color: #008080; "> 78</span>                     <span style="color: #0000FF; ">if</span> (newStart == <span style="color: #0000FF; ">null</span>) {<br /><span style="color: #008080; "> 79</span>                         <span style="color: #0000FF; ">if</span> (object.compareTo(bdLower) != -1) {<br /><span style="color: #008080; "> 80</span>                             newStart = object;<br /><span style="color: #008080; "> 81</span>                             <span style="color: #0000FF; ">if</span> (newEnd != <span style="color: #0000FF; ">null</span>) {<br /><span style="color: #008080; "> 82</span>                                 <span style="color: #0000FF; ">break</span>;<br /><span style="color: #008080; "> 83</span>                             }<br /><span style="color: #008080; "> 84</span>                         }<br /><span style="color: #008080; "> 85</span>                     }<br /><span style="color: #008080; "> 86</span> <br /><span style="color: #008080; "> 87</span>                     <span style="color: #0000FF; ">if</span> (newEnd == <span style="color: #0000FF; ">null</span>) {<br /><span style="color: #008080; "> 88</span>                         <span style="color: #0000FF; ">if</span> (object.compareTo(bdHigher) != -1) {<br /><span style="color: #008080; "> 89</span>                             newEnd = object;<br /><span style="color: #008080; "> 90</span>                             <span style="color: #0000FF; ">if</span> (newStart != <span style="color: #0000FF; ">null</span>) {<br /><span style="color: #008080; "> 91</span>                                 <span style="color: #0000FF; ">break</span>;<br /><span style="color: #008080; "> 92</span>                             }<br /><span style="color: #008080; "> 93</span>                         }<br /><span style="color: #008080; "> 94</span>                     }<br /><span style="color: #008080; "> 95</span>                 }<br /><span style="color: #008080; "> 96</span> <br /><span style="color: #008080; "> 97</span>                 <span style="color: #0000FF; ">if</span> (newStart == <span style="color: #0000FF; ">null</span>) {<br /><span style="color: #008080; "> 98</span>                     <span style="color: #0000FF; ">if</span> (newEnd == <span style="color: #0000FF; ">null</span>) {<br /><span style="color: #008080; "> 99</span>                         <span style="color: #0000FF; ">if</span> ((bdHigher.compareTo(targetSet.first()) == -1)<br /><span style="color: #008080; ">100</span>                                 || (bdLower.compareTo(targetSet.last()) == 1)) {<br /><span style="color: #008080; ">101</span>                             <span style="color: #0000FF; ">return</span> <span style="color: #0000FF; ">null</span>;<br /><span style="color: #008080; ">102</span>                         }<br /><span style="color: #008080; ">103</span>                         <span style="color: #0000FF; ">return</span> targetSet;<br /><span style="color: #008080; ">104</span>                     } <span style="color: #0000FF; ">else</span> {<br /><span style="color: #008080; ">105</span>                         SortedSet<BigDecimal> newTargetSet = targetSet.headSet(<br /><span style="color: #008080; ">106</span>                                 newEnd, <span style="color: #0000FF; ">true</span>);<br /><span style="color: #008080; ">107</span>                         <span style="color: #0000FF; ">if</span> (newEnd.compareTo(bdHigher) == 1) {<br /><span style="color: #008080; ">108</span>                             newTargetSet.remove(newEnd);<br /><span style="color: #008080; ">109</span>                         }<br /><span style="color: #008080; ">110</span>                         <span style="color: #0000FF; ">return</span> newTargetSet;<br /><span style="color: #008080; ">111</span>                     }<br /><span style="color: #008080; ">112</span>                 } <span style="color: #0000FF; ">else</span> {<br /><span style="color: #008080; ">113</span>                     <span style="color: #0000FF; ">if</span> (newEnd == <span style="color: #0000FF; ">null</span>) {<br /><span style="color: #008080; ">114</span>                         SortedSet<BigDecimal> newTargetSet = targetSet.tailSet(<br /><span style="color: #008080; ">115</span>                                 newStart, <span style="color: #0000FF; ">true</span>);<br /><span style="color: #008080; ">116</span>                         <span style="color: #0000FF; ">return</span> newTargetSet;<br /><span style="color: #008080; ">117</span>                     } <span style="color: #0000FF; ">else</span> {<br /><span style="color: #008080; ">118</span>                         SortedSet<BigDecimal> newTargetSet = targetSet.subSet(<br /><span style="color: #008080; ">119</span>                                 newStart, <span style="color: #0000FF; ">true</span>, newEnd, <span style="color: #0000FF; ">true</span>);<br /><span style="color: #008080; ">120</span>                         <span style="color: #0000FF; ">if</span> (newEnd.compareTo(bdHigher) == 1) {<br /><span style="color: #008080; ">121</span>                             newTargetSet.remove(newEnd);<br /><span style="color: #008080; ">122</span>                         }<br /><span style="color: #008080; ">123</span>                         <span style="color: #0000FF; ">return</span> newTargetSet;<br /><span style="color: #008080; ">124</span>                     }<br /><span style="color: #008080; ">125</span>                 }<br /><span style="color: #008080; ">126</span>             }<br /><span style="color: #008080; ">127</span>         }<br /><span style="color: #008080; ">128</span>     }</div>W三U方? 使用Apache Commons Collections, 直接对于原始Setq行filter.<br />            试效果:集合大小10M,qo(h)l果1M, q算旉: 1000ms+<br />qo(h)部分的代码如?<br /><div style="font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; background-color: #eeeeee;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; "> 1</span> <span style="color: #008000; ">//</span><span style="color: #008000; ">qo(h)的主体逻辑</span><span style="color: #008000; "><br /></span><span style="color: #008080; "> 2</span> <span style="color: #008000; "></span>    <span style="color: #0000FF; ">void</span> filterSet(Set<BigDecimal> targetSet, String lower, String higher) {<br /><span style="color: #008080; "> 3</span>         <span style="color: #0000FF; ">final</span> BigDecimal bdLower = <span style="color: #0000FF; ">new</span> BigDecimal(Double.parseDouble(lower));<br /><span style="color: #008080; "> 4</span>         <span style="color: #0000FF; ">final</span> BigDecimal bdHigher = <span style="color: #0000FF; ">new</span> BigDecimal(Double.parseDouble(higher));<br /><span style="color: #008080; "> 5</span> <br /><span style="color: #008080; "> 6</span>         Predicate predicate = <span style="color: #0000FF; ">new</span> Predicate() {<br /><span style="color: #008080; "> 7</span>             <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">boolean</span> evaluate(Object object) {<br /><span style="color: #008080; "> 8</span>                 BigDecimal bDObject = (BigDecimal) object;<br /><span style="color: #008080; "> 9</span>                 <span style="color: #0000FF; ">return</span> bDObject.compareTo(bdLower) >= 0<br /><span style="color: #008080; ">10</span>                         && bDObject.compareTo(bdHigher) <= 0;<br /><span style="color: #008080; ">11</span>             }<br /><span style="color: #008080; ">12</span>         };<br /><span style="color: #008080; ">13</span> <br /><span style="color: #008080; ">14</span>         CollectionUtils.filter(targetSet, predicate);<br /><span style="color: #008080; ">15</span>     }</div><br />W四U方?使用Guava(google Collections), 直接对于原始Setq行Filter<br />            试效果:集合大小10M,qo(h)l果1M, q算旉: 100ms-<br />qo(h)部分的代码如?<br /><div style="font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; background-color: #eeeeee;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; "> 1</span> <span style="color: #008000; ">//</span><span style="color: #008000; ">guava filter</span><span style="color: #008000; "><br /></span><span style="color: #008080; "> 2</span> <span style="color: #008000; "></span><br /><span style="color: #008080; "> 3</span>     Set<BigDecimal> filterSet(Set<BigDecimal> targetSet, String lower,<br /><span style="color: #008080; "> 4</span>             String higher) {<br /><span style="color: #008080; "> 5</span>         <span style="color: #0000FF; ">final</span> BigDecimal bdLower = <span style="color: #0000FF; ">new</span> BigDecimal(Double.parseDouble(lower));<br /><span style="color: #008080; "> 6</span>         <span style="color: #0000FF; ">final</span> BigDecimal bdHigher = <span style="color: #0000FF; ">new</span> BigDecimal(Double.parseDouble(higher));<br /><span style="color: #008080; "> 7</span> <br /><span style="color: #008080; "> 8</span>         Set<BigDecimal> filterCollection = Sets.filter(targetSet,<br /><span style="color: #008080; "> 9</span>                 <span style="color: #0000FF; ">new</span> Predicate<BigDecimal>() {<br /><span style="color: #008080; ">10</span>                     @Override<br /><span style="color: #008080; ">11</span>                     <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">boolean</span> apply(BigDecimal input) {<br /><span style="color: #008080; ">12</span>                         BigDecimal bDObject = (BigDecimal) input;<br /><span style="color: #008080; ">13</span>                         <span style="color: #0000FF; ">return</span> bDObject.compareTo(bdLower) >= 0<br /><span style="color: #008080; ">14</span>                                 && bDObject.compareTo(bdHigher) <= 0;<br /><span style="color: #008080; ">15</span>                     }<br /><span style="color: #008080; ">16</span>                 });<br /><span style="color: #008080; ">17</span> <br /><span style="color: #008080; ">18</span>         <span style="color: #0000FF; ">return</span> filterCollection;<br /><span style="color: #008080; ">19</span>     }</div><br /><br />四种方式Ҏ(gu)如下:<br />W一U方?  仅依赖于JAVA原生cd 遍历旉最? 代码量很?br />W二U方?  仅依赖于JAVA原生cd 遍历旉比较?主要慢在生成有序Set), 代码量最?br />W三U方?  依赖于Apache Commons Collections, 遍历旉比较? 代码量很?br />W四U方?  依赖于Guava, 遍历旉最? 代码量很?br /><br />Z目前个h的技术水q_视野, W四U方式可能是最佳选择.<br /><br />记录一? 以后可能q会(x)有更好的Ҏ(gu).<br /><br /><br /><br /><br /><div id="tvefpxu" class="vimiumReset vimiumHUD" style="right: 150px; opacity: 0; display: none;"></div><img src ="http://www.tkk7.com/GandofYan/aggbug/415009.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/GandofYan/" target="_blank">h中立</a> 2014-06-21 23:33 <a href="http://www.tkk7.com/GandofYan/archive/2014/06/21/415009.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于pȝ设计的一Ҏ(gu)?/title><link>http://www.tkk7.com/GandofYan/archive/2009/09/02/293549.html</link><dc:creator>h中立</dc:creator><author>h中立</author><pubDate>Wed, 02 Sep 2009 02:53:00 GMT</pubDate><guid>http://www.tkk7.com/GandofYan/archive/2009/09/02/293549.html</guid><wfw:comment>http://www.tkk7.com/GandofYan/comments/293549.html</wfw:comment><comments>http://www.tkk7.com/GandofYan/archive/2009/09/02/293549.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/GandofYan/comments/commentRss/293549.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/GandofYan/services/trackbacks/293549.html</trackback:ping><description><![CDATA[在几q之?在大学里面的时?认ؓ(f)pȝ的架构设?像建筑设计一??x)把骨架搭?然后有具体h员进行详l的开?<br /> <br /> 在后?工作?慢慢有了一些变?因ؓ(f)原先的想法不太切合实?pȝ是在变化之中的,如果固定了骨?那就很难的敏捷面对变?<br /> 所?pȝ的架构设?应该是面向接口的设计,定各个部分之间的数据接口和Ҏ(gu)接口.q样,即有了变化,只要遵@接口的定?p是可以面对变?<br /> <br /> <br /> 最q?又有了想法的变化.架构的设?应该是规则和规U的设计.设计Zpd,l一?和谐的规?在这些规则之前圈住的部分,实际是pȝ的全?<br /> 接口的设?实际只是规则和规U设计的一个部?<br /> 架构的设?不应该只是程序方面的事情,同时也包含了心理学方面和C会(x)学方面的一些规?例如:团队在面对变化时?需要采用的规则和流E?<br /> 只有包含了这些非E序上的规则之后,才能保证架构风格的统一协调.<br /> <br /> <br /> 以上,是我对系l设计的x的{变过E?记录于此,以供回溯.<br /> <br /> <br /> <br /> <br /> <img src ="http://www.tkk7.com/GandofYan/aggbug/293549.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/GandofYan/" target="_blank">h中立</a> 2009-09-02 10:53 <a href="http://www.tkk7.com/GandofYan/archive/2009/09/02/293549.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>l护E序从数l开?/title><link>http://www.tkk7.com/GandofYan/archive/2009/08/20/291938.html</link><dc:creator>h中立</dc:creator><author>h中立</author><pubDate>Thu, 20 Aug 2009 05:43:00 GMT</pubDate><guid>http://www.tkk7.com/GandofYan/archive/2009/08/20/291938.html</guid><wfw:comment>http://www.tkk7.com/GandofYan/comments/291938.html</wfw:comment><comments>http://www.tkk7.com/GandofYan/archive/2009/08/20/291938.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.tkk7.com/GandofYan/comments/commentRss/291938.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/GandofYan/services/trackbacks/291938.html</trackback:ping><description><![CDATA[面对着满屏q的E序<br /> 是三q前,目刚刚启动的时?同事写的代码.<br /> 三年q去?目q一期变成了W七?<br /> <br /> q段代码q是在这?有个属性是list,其中每个cell都是一个长?8的String数组.<br /> 数组里面攄了所需要导出到面table的内?<br /> <br /> 现在要开始修改了,需要向面的table中增??<br /> J琐的让命的工作,需要跟t这个@?判断每个pattern下面,q个长度18的数l里面放了哪些内?<br /> <br /> 好吧,对象化维护从数组开?把数l对?因ؓ(f)q个数组时一个比较数l?前面9个元素是之前的情?后面9个事之后的情?<br /> 用一个bean,攑օ两次可以了.但是bean?需要一个标?标识是之前的情况q是之后的情?<br /> <br /> 同时需要一个transformҎ(gu),把之前从几个来源q来的情?变成bean的属?<br /> 接下来需要一个valuesҎ(gu),把bean里面的属性直接按序转化成数l?<br /> 本期新增?个属?直接攑օbean中就可以?<br /> <br /> q样原来很复杂的数组,可以简单的用对象来解决.外部的接口完全没有变?<br /> <br /> l护E序,从把数组(特别是异型数l?对象化开?<br /> <br /> <img src ="http://www.tkk7.com/GandofYan/aggbug/291938.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/GandofYan/" target="_blank">h中立</a> 2009-08-20 13:43 <a href="http://www.tkk7.com/GandofYan/archive/2009/08/20/291938.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个Sudoku的java求解法http://www.tkk7.com/GandofYan/archive/2006/07/13/58004.htmlh中立h中立Thu, 13 Jul 2006 08:19:00 GMThttp://www.tkk7.com/GandofYan/archive/2006/07/13/58004.htmlhttp://www.tkk7.com/GandofYan/comments/58004.htmlhttp://www.tkk7.com/GandofYan/archive/2006/07/13/58004.html#Feedback4http://www.tkk7.com/GandofYan/comments/commentRss/58004.htmlhttp://www.tkk7.com/GandofYan/services/trackbacks/58004.html正好当时在看Uncle Bob的《Agile Software Development: Principles, Patterns, and Practices?Q敏捯Y件开发:(x)原则、模式与实践Q?所以就按照自己对书中的一些概念和Ҏ(gu)的理解,l合自己之前的开发经验写出来一D小的代码?br />
代码行数Q?< 900
cȝ个数Q?18
抽象cȝ个数Q?
工厂cȝ个数Q?
包的个数Q?

一些关于类和包作用的说明:(x)
1.Cell:表示一个CellQ是一个游戏中的一个单元格?br />  Cell主要?个部分组成,Point,Value,Status.
2.Point:表示一个坐标,主要格式?(2,3).
  Q!Q注意:(x)׃个h比较?所以开始的错误被诏M下来?br />  q个错误是Q?Q?Q表C的是由最左上的位|ؓ(f)坐标原点Q第二行和第三列所定的那个单元格。也是U坐标在前,横坐标在后了?br />3.Value:表示一个?br />4.Status:表示Cell的状态,只有两个状态,一个是NotSure,另一个是Sure.

5.AbstractCellsQ表CZ些cell的集合,主要有三个子c?br />     BlockCellsQ表CZ个由多个Celll成的块Q例如一?*2?个Celll成的块Q或者一?*3?个Celll成的块
     HorizonCells:表示一个横行,卻I(x)从(0Q?Q到(0,n)坐标定的所有Cell的集合?br />     VerticalCells:表示一个纵行,卻I(x)从(0Q?Q到(n,0)坐标定的所有Cell的集合?br />6.AbstractPolicy:是游戏的策略?br />   q个主要表示的是Q?*4的游戏,q是9*9的游戏?br />   可以在以后对此类q行l承和扩展,例如16*16的游戏我没有实现?br />   主要扩展3个方法:(x)
                  1QgetValueRangeQ返回当前policy的value的个数?*4的游戏的getValueRangeq回的就应该??br />          2QgetStepQ表C当前policy中相?c)两个BlockCells的坐标差?br />          3QgetIncreaseQ说不明白了Q)Q只可意?x)不可言传。)
7.GameQ进行Policy的场所Q我一直想抛弃q个c)
8.TestGame:游戏q行的地方,包括从PolicyFactory取得指定的Policy,讄输入输出文g的\径?br />9.PolicyFactoryQ取得Policy的工厂?br />    getPolicy(int x) :q个Ҏ(gu)获得的是正方形的sudoku的策略。例?4*4的,9*9,16*16?br />    getPolicy(int x, int y)Q这个方法获得的是长方Ş的Sudoku的策略。例如:(x)9*12的?br />

虽然是尽量避免bad code smellQ但是由于能力有限,q是出现了一些不好的地方?br />例如Q之间的兌关系q是很多Q而且很强Q抽象的Ҏ(gu)和抽象类的个数偏等{?br />
里面实现了三个解决sudoku的方法:(x)
1.在一个Cell中出现的Value,不会(x)在和q个Cell处在同一个AbstractCells中的所有Cell中出玎ͼ
2.如果一个Cell中,所有可能出现的Value的个Cؓ(f)1Q那么Cell的Value必然是这个最后的ValueQ?br />2.如果一个Value,如果在当前AbstractCells的所有其他的Cell中都不可能出玎ͼ那么它必然是最后一个Cell的Value?br />
附g1Qsrc code
http://www.tkk7.com/Files/GandofYan/sudoku.rar
附g2Q输入输出文件的example
http://www.tkk7.com/Files/GandofYan/temp.rar



h中立 2006-07-13 16:19 发表评论
]]>
OO设计中的度量http://www.tkk7.com/GandofYan/archive/2006/06/07/51054.htmlh中立h中立Wed, 07 Jun 2006 02:52:00 GMThttp://www.tkk7.com/GandofYan/archive/2006/06/07/51054.htmlhttp://www.tkk7.com/GandofYan/comments/51054.htmlhttp://www.tkk7.com/GandofYan/archive/2006/06/07/51054.html#Feedback3http://www.tkk7.com/GandofYan/comments/commentRss/51054.htmlhttp://www.tkk7.com/GandofYan/services/trackbacks/51054.html
软g的度量对于设计者和开发者非帔R要,之前只是对这些有一个简单的了解。今天看来,了解的还q远不够?br />
  • Cyclomatic Complexity Q圈复杂性)
  • Response for Class Q类的响应)
  • Weighted methods per class Q每个类重量Ҏ(gu)Q?/li>
一个系l中的所有类的这三个度量能够说明q个pȝ的设计上的一些问题(不是全部Q,q三个度量越大越不好?br />如果一个类q三个度量很高,证明了这个类需要重构了?br />
以第一个度量来_(d)有下面的一个表|(x)

CC Value

Risk

1-10

Low risk program

11-20

Moderate risk

21-50

High risk

>50

Most complex and highly unstable method


CC数值高Q可以通过减少if elseQswitch case也算Q判断来辑ֈ目的Q?br />可以通过减少cM其他cȝ调用来减RFCQ?br />通过分割大方法和大类来达到减WMPC.

而Uncle Bob和Jdepend的度量标准应该算是另一个度量系l?br />
  • 关系内聚性(HQ?/span>
用包中的每个cd^均的内部关系数目作ؓ(f)包内聚性的一U表C方式。用于表C包和它的所有类之间的关pR?br />H=(R+1)/N
R:包内cȝ关系数目Q与包外部的cL有关p)
N:包内cȝ数量

  • Number of Classes (Cc)
被分析package的具体和抽象c(和接口)的数量,用于衡量package的可扩展性?br />
  • Afferent Couplings (Ca)
依赖于被分析package的其他package的数量,用于衡量pacakge的职责?br />
  • Efferent Couplings (Ce)
被分析package的类所依赖的其他package的数量,用于衡量package的独立性?br />
  • Abstractness (A)
被分析package中的抽象cd接口与所在package所有类数量的比例,取D围ؓ(f)0Q??br />A=Cc/N
  • Instability (I)
用于衡量package的不E_性,取D围ؓ(f)0Q?。IQ?表示最E_QIQ?表示最不稳定?br />IQCe/QCeQCaQ?br />
  • Distance (D)
          被分析package和理xUAQIQ?的垂直距,用于衡量package在稳定性和抽象性之间的q。理ꐠ ?      的package要么完全是抽象类和稳定(xQ?QyQ?Q,要么完全是具体类和不E_QxQ?QyQ?Q?br />          取D围ؓ(f)0Q?QDQ?表示完全W合理想标准QDQ?表示package最大程度地偏离了理x准?br />          D = |A+I-1|/0.70710678
          注:(x)0.70710678*0.70710678 =2Q既为“根??br />
我认为D是一个综合的度量Q架构和设计的改善可以通过D数值的减少来体玎ͼ反之可以认为是设计和架构的退化?br />

读过http://javaboutique.internet.com/tutorials/metrics/index.html之后的一些想?br />
另一中文的内容相近的文章可以参考http://www.jdon.com/artichect/coupling.htm

不过W二的中文文章中间关于Cyclomatic ComplexityQ有一个情况遗漏了
public void findApplications(String id, String name){

if(id!=null && name!=null) {
//do something
}else{
//do something
}
}
q种情况的CC不是2+1Q而是2+1+1Q依据是公式Q?Q。公?2)应该是公式(1Q的化版?pre>Cyclomatic Complexity Q?code>CCQ?= no of decision points + no of logical operations +1 Q?Q?br />
Cyclomatic Complexity (CC) = number of decision points +1 Q?Q?br />
参考了JDepend的参数和Uncle Bob的?/code>Agile Software Development: Principles, Patterns, and Practices?Q敏捯Y件开发:(x)原则、模式与实践Q?/pre>

h中立 2006-06-07 10:52 发表评论
]]>
RETE法的描q??http://www.tkk7.com/GandofYan/archive/2006/05/30/49012.htmlh中立h中立Tue, 30 May 2006 07:30:00 GMThttp://www.tkk7.com/GandofYan/archive/2006/05/30/49012.htmlhttp://www.tkk7.com/GandofYan/comments/49012.htmlhttp://www.tkk7.com/GandofYan/archive/2006/05/30/49012.html#Feedback2http://www.tkk7.com/GandofYan/comments/commentRss/49012.htmlhttp://www.tkk7.com/GandofYan/services/trackbacks/49012.html转自:http://www.keyusoft.cn/Contentview.aspx?year=2005&month=$10&day=$6&postid=123

通过一周左右的研究Q对规则引擎有了一定的了解。现在写点东西跟大家一起交,本文主要针对RETE法q行描述。我的文W不太好Q如果有什么没讲明白的或是说错的地方,L(fng)我留a?/div>
首先xQ我的帖子借鉴了网上很行的一帖子,好像是来自CSDNQ还有一点,我不惛_太多的名词解释,因ؓ(f)我也不是个研I很q人,定义的不好怕被W话?/div>
好现在我们开始?/div>
首先介绍一些网上对于规则引擎比较好的帖子?/div>
1?来自JAVA视频|?
2、?RETE法的最原始的描qͼ我不知道在哪里找到的Q想要的人可以留下E-mail
3、?CMU的一位博士生的毕业论文,个h觉得非常好,我的很多观点都是来自q里的,要的Z可以l我发mail   mailto:ipointer@163.com
 
接着l一一下术语,很多资料里的术语都非常؜乱?/div>
1、?facts 事实Q我们实现的时候,?x)有一个事实库。用F表示?/div>
2、?patterns 模板Q事实的一个模型,所有事实库中的事实都必Lx板中的一个。用P表示?/div>
3?   conditions 条g,规则的组成部分。也必须满模板库中的一条模ѝ用C表示。我们可以这L(fng)解facts、patterns、conditions之间的关pR? Patterns是一个接口,conditions则是实现q个接口的类Q而facts是这个类的实例?/div>
4、?rules 规则Q由一到多个条件构成。一般用and或orq接conditions。用R表示?/div>
5、?actions 动作Q激zM条rule执行的动作。我们这里不作讨论?/div>
6、?q有一些术语,如:(x)working-memory、production-memoryQ跟q里的概念大同小异?/div>
7、?q有一些,如:(x)alpha-network、beta-network、join-nodeQ我们下面会(x)用到Q先放一下,一?x)讨论?/div>
 
引用一下网上很行的例子,我觉得没讲明白,我在用我的想法解释一下?/div>
 
假设在规则记忆中有下列三条规?/div>
 
if A(x) and B(x) and C(y) then add D(x)
if A(x) and B(y) and D(x) then add E(x)
if A(x) and B(x) and E(x) then delete A(x)
 
RETE法?x)先规则编译成下列的?wi)状架构排序网l?/div>

而工作记忆内容及(qing)序为{A(1)QA(2)QB(2)QB(3)QB(4)QC(5)}Q当工作记忆依序q入|络后,?x)依序储存在W合条g的节点中Q直到完全符合条件的推论规则推出推论。以上述例子而言Q?最后推得D(2)?/div>
 
让我们来分析q个例子?/div>
 
模板库:(x)Q这个例子中只有一个模板,法原描qC有不同的例子, 一般我们会(x)用tuple,元组的Ş式来定义facts,patterns,conditionQ?/div>
P: (?A , ?x)  其中的A可能代表一定的操作Q如例子中的A,B,C,D,E ; x代表操作的参数。看看这个模板是不是已经可以描述所有的事实?/div>
 
条g库:(x)(q里元组的第一代表实际的操作Q第二项代表形参)
C1: (A , <x>)
C2: (B , <x>)
C3: (C , <y>)
C4: (D , <x>)
C5: (E , <x>)
C6: (B , <y>)
 
事实库:(x)Q第二项代表实参Q?/div>
F1: (A,1)
F2: (A,2)
F3: (B,2)
F4: (B,3)
F5: (B,4)
F6: (C,5)
 
       规则库:(x)
         R1: c1^c2^c3
         R2: c1^c2^c4
         R3: c1^c2^c5
 
      
       有h可能?x)质疑R1: c1^c2^c3Q没有描q出Q原式中Q?/div>
if A(x) and B(x) and C(y) then add D(x)QA=B的关pR但请仔l看一下,q一点已l在条g库中定义出来了?/div>
 
       下面我来描述一下,规则引擎中RETE法的实现?/div>
       首先Q我们要定一些规则,Ҏ(gu)q些规则Q我们的引擎可以~译Z个树(wi)状结构,上面的那张图中是一U简易的表现Q其实在实现的时候不是这个样子的?/div>
       q就是beta-network出场的时候了Q根据rules我们可以确定beta-networkQ下面,我就d本例中的beta-networkQؓ(f)了描q方便,我把alpha-network也画出来了?/div>
      
 
上图中,左边的部分就是beta-network,双是alpha-network,圆圈是join-node.
从上图中Q我们可以验证,在beta-network中,表现Zrules的内容,其中r1,r2,r3׃n了许多BM和join-node,q是׃q些规则中有共同的部分,q样能加快match的速度?/div>
? 边的alpha-network是根据事实库构徏的,其中除alpha-network节点的节炚w是根据每一条condition,从事实库? matchq来的,q一q程是静态的Q即在编译构建网l的q程中已l徏立的。只要事实库是稳定的Q即没有大幅度的变化QRETE法的执行效率应该是非常 高的Q其原因是已经通过静态的~译Q构Zalpha-network。我们可以验证一下,满c1的事实确实是w1,w2?/div>
? 面我们就看一下,q个法是怎么来运行的Q即怎么来确定被Ȁzȝrules的。从top-node往下遍历,C个join-node,与AM for c1的节Ҏ(gu)合,q行到match c1节点。此Ӟmatch c1节点的内容就是:(x)w1,w2。l往下,与AM for c2汇合Q所有可能的l合应该是w1^w3,w1^w4,w1^w5,w2^w3,w2^w4,w2^w5Q,因ؓ(f)c1^c2要求参数相同Q因此, match c1^c2的内Ҏ(gu)Qw2^w3。再l箋Q这里有一个扇出(fan-outQ,其中只有一个join-node可以被激z,因ؓ(f)旁边的AM只有一个非I? 因此Q也只有R1被激zM?/div>
解决扇出带来的效率降低的问题Q我们可以用hashtable来解册个问题?/div>
RETE法q有一些问题,如:(x)facts库变化,我们怎么才能高效的重建alpha-networkQ同理包括rules的变化对beta-network的媄(jing)响。这一部分我还没细看,到时候再贴出来吧?/div>

h中立 2006-05-30 15:30 发表评论
]]>再次重装eclipsehttp://www.tkk7.com/GandofYan/archive/2006/05/30/48962.htmlh中立h中立Tue, 30 May 2006 05:48:00 GMThttp://www.tkk7.com/GandofYan/archive/2006/05/30/48962.htmlhttp://www.tkk7.com/GandofYan/comments/48962.htmlhttp://www.tkk7.com/GandofYan/archive/2006/05/30/48962.html#Feedback0http://www.tkk7.com/GandofYan/comments/commentRss/48962.htmlhttp://www.tkk7.com/GandofYan/services/trackbacks/48962.html最q插件又加多?eclipse老是L
 
一怒之?删除重装
 
以前因ؓ(f)?没有把插件的目录和主体的目录分开,q次也给它分开?/div>
 
 
插g了之后,eclipse实快了不少
 
附eclipse启动参数: -nl en_US vmargs -Xverify:none -Xms256M -Xmx1024M -XX:PermSize=50M  -XX:+UseParallelGC


h中立 2006-05-30 13:48 发表评论
]]>free mind 和mind manager ,q有visiohttp://www.tkk7.com/GandofYan/archive/2006/05/30/48955.htmlh中立h中立Tue, 30 May 2006 05:36:00 GMThttp://www.tkk7.com/GandofYan/archive/2006/05/30/48955.htmlhttp://www.tkk7.com/GandofYan/comments/48955.htmlhttp://www.tkk7.com/GandofYan/archive/2006/05/30/48955.html#Feedback2http://www.tkk7.com/GandofYan/comments/commentRss/48955.htmlhttp://www.tkk7.com/GandofYan/services/trackbacks/48955.html freemind一个比较不错free? mind map 软g,很多人徏议用这个来理自己的思\.
 
mind manager另一个比较不错的mind map的Y?可以和office兼容.不过是商业的
 
visio,׃介绍?office里面有的东西.做流E图来说,实是比较好的Y?但是在思\不清楚的时?很难d什么有用的东西?q点比不上前面两个东西?不过Ҏ(gu)来说visio可能更顺?因ؓ(f)我经常画的是软g程?.......


h中立 2006-05-30 13:36 发表评论
]]>javaEye上面对于domain object的讨?/title><link>http://www.tkk7.com/GandofYan/archive/2006/05/30/48954.html</link><dc:creator>h中立</dc:creator><author>h中立</author><pubDate>Tue, 30 May 2006 05:31:00 GMT</pubDate><guid>http://www.tkk7.com/GandofYan/archive/2006/05/30/48954.html</guid><wfw:comment>http://www.tkk7.com/GandofYan/comments/48954.html</wfw:comment><comments>http://www.tkk7.com/GandofYan/archive/2006/05/30/48954.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.tkk7.com/GandofYan/comments/commentRss/48954.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/GandofYan/services/trackbacks/48954.html</trackback:ping><description><![CDATA[ <div> <a > <u> <font color="#0000ff">ȝ一下最q关于domain object以及(qing)相关的讨?/font> </u> </a> </div> <div> </div> <div> <span>在最q的围绕domain object的讨Z现出来了三U模型,(q有一些其他的旁枝Q不一一分析?Q经q一番讨论,各种问题逐渐清晰hQ在q里我试囑ց一个ȝQ便于大家了解和掌握? <br /><br />W一U模型:(x)只有getter/setterҎ(gu)的纯数据c,所有的业务逻辑完全由business object来完?又称TransactionScript)Q这U模型下的domain object被Martin FowlerUC为“血的domain object”。下面用举一个具体的代码来说明,代码来自Hibernate的caveatemptorQ但l过我的改写Q? <br /><br />一个实体类叫做ItemQ指的是一个拍卖项?<br />一个DAO接口cd做ItemDao <br />一个DAO接口实现cd做ItemDaoHibernateImpl <br />一个业务逻辑cd做ItemManager(或者叫做ItemService) <br /><br /></span> <table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"> <tbody> <tr> <td> <span> <b>java代码: </b> </span> </td> </tr> <tr> <td> <div style="font-family: 'Courier New',Courier,monospace;"> <br /> <font face="Courier New"> <span style="font-weight: bold; color: rgb(153, 0, 102);">public</span> <span style="font-weight: bold; color: rgb(153, 0, 102);">class</span> Item <span style="font-weight: bold; color: rgb(153, 0, 102);">implements</span><span style="color: rgb(170, 170, 221);">Serializable</span><span style="color: rgb(0, 0, 0);">{</span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">private</span><span style="color: rgb(170, 170, 221);">Long</span> id = <span style="font-weight: bold; color: rgb(153, 0, 102);">null</span>; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">private</span><span style="font-weight: bold; color: rgb(153, 0, 102);">int</span> version; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">private</span><span style="color: rgb(170, 170, 221);">String</span> name; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">private</span> User seller; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">private</span><span style="color: rgb(170, 170, 221);">String</span> description; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">private</span> MonetaryAmount initialPrice; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">private</span> MonetaryAmount reservePrice; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">private</span><span style="color: rgb(170, 170, 221);">Date</span> startDate; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">private</span><span style="color: rgb(170, 170, 221);">Date</span> endDate; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">private</span><span style="color: rgb(170, 170, 221);">Set</span> categorizedItems = <span style="font-weight: bold; color: rgb(153, 0, 102);">new</span><span style="color: rgb(170, 170, 221);">HashSet</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span>; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">private</span><span style="color: rgb(170, 170, 221);">Collection</span> bids = <span style="font-weight: bold; color: rgb(153, 0, 102);">new</span><span style="color: rgb(170, 170, 221);">ArrayList</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span>; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">private</span> Bid successfulBid; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">private</span> ItemState state; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">private</span> User approvedBy; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">private</span><span style="color: rgb(170, 170, 221);">Date</span> approvalDatetime; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">private</span><span style="color: rgb(170, 170, 221);">Date</span> created = <span style="font-weight: bold; color: rgb(153, 0, 102);">new</span><span style="color: rgb(170, 170, 221);">Date</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span>; <br />    <span style="color: rgb(102, 102, 255);">//  getter/setterҎ(gu)省略不写Q避免篇q太?/span><br /><span style="color: rgb(0, 0, 0);">}</span></font> </div> <br /> </td> </tr> </tbody> </table> <span> <br /> <br /> </span> <table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"> <tbody> <tr> <td> <span> <b>java代码: </b> </span> </td> </tr> <tr> <td> <div style="font-family: 'Courier New',Courier,monospace;"> <br /> <font face="Courier New"> <span style="font-weight: bold; color: rgb(153, 0, 102);">public</span> <span style="font-weight: bold; color: rgb(153, 0, 102);">interface</span> ItemDao <span style="color: rgb(0, 0, 0);">{</span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">public</span> Item getItemById<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(170, 170, 221);">Long</span> id<span style="color: rgb(0, 0, 0);">)</span>; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">public</span><span style="color: rgb(170, 170, 221);">Collection</span> findAll<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span>; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">public</span><span style="font-weight: bold; color: rgb(153, 0, 102);">void</span> updateItem<span style="color: rgb(0, 0, 0);">(</span>Item item<span style="color: rgb(0, 0, 0);">)</span>; <br /><span style="color: rgb(0, 0, 0);">}</span></font> </div> <br /> </td> </tr> </tbody> </table> <span> <br /> <br />ItemDao定义持久化操作的接口Q用于隔L久化代码? <br /><br /></span> <table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"> <tbody> <tr> <td> <span> <b>java代码: </b> </span> </td> </tr> <tr> <td> <div style="font-family: 'Courier New',Courier,monospace;"> <br /> <font face="Courier New"> <span style="font-weight: bold; color: rgb(153, 0, 102);">public</span> <span style="font-weight: bold; color: rgb(153, 0, 102);">class</span> ItemDaoHibernateImpl <span style="font-weight: bold; color: rgb(153, 0, 102);">implements</span> ItemDao <span style="font-weight: bold; color: rgb(153, 0, 102);">extends</span> HibernateDaoSupport <span style="color: rgb(0, 0, 0);">{</span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">public</span> Item getItemById<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(170, 170, 221);">Long</span> id<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">{</span><br />        <span style="font-weight: bold; color: rgb(153, 0, 102);">return</span><span style="color: rgb(0, 0, 0);">(</span>Item<span style="color: rgb(0, 0, 0);">)</span> getHibernateTemplate<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span>.<span style="color: rgb(0, 0, 0);">load</span><span style="color: rgb(0, 0, 0);">(</span>Item.<span style="color: rgb(0, 0, 0);">class</span>, id<span style="color: rgb(0, 0, 0);">)</span>; <br />    <span style="color: rgb(0, 0, 0);">}</span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">public</span><span style="color: rgb(170, 170, 221);">Collection</span> findAll<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">{</span><br />        <span style="font-weight: bold; color: rgb(153, 0, 102);">return</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(170, 170, 221);">List</span><span style="color: rgb(0, 0, 0);">)</span> getHibernateTemplate<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span>.<span style="color: rgb(0, 0, 0);">find</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">"from Item"</span><span style="color: rgb(0, 0, 0);">)</span>; <br />    <span style="color: rgb(0, 0, 0);">}</span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">public</span><span style="font-weight: bold; color: rgb(153, 0, 102);">void</span> updateItem<span style="color: rgb(0, 0, 0);">(</span>Item item<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">{</span><br />        getHibernateTemplate<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span>.<span style="color: rgb(0, 0, 0);">update</span><span style="color: rgb(0, 0, 0);">(</span>item<span style="color: rgb(0, 0, 0);">)</span>; <br />    <span style="color: rgb(0, 0, 0);">}</span><br /><span style="color: rgb(0, 0, 0);">}</span></font> </div> <br /> </td> </tr> </tbody> </table> <span> <br />ItemDaoHibernateImpl完成具体的持久化工作Q请注意Q数据库资源的获取和释放是在ItemDaoHibernateImpl 里面处理的,每个DAOҎ(gu)调用之前打开SessionQDAOҎ(gu)调用之后Q关闭Session?Session攑֜ThreadLocal中,保证一ơ调用只打开关闭一? <br /><br /></span> <table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"> <tbody> <tr> <td> <span> <b>java代码: </b> </span> </td> </tr> <tr> <td> <div style="font-family: 'Courier New',Courier,monospace;"> <br /> <font face="Courier New"> <span style="font-weight: bold; color: rgb(153, 0, 102);">public</span> <span style="font-weight: bold; color: rgb(153, 0, 102);">class</span> ItemManager <span style="color: rgb(0, 0, 0);">{</span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">private</span> ItemDao itemDao; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">public</span><span style="font-weight: bold; color: rgb(153, 0, 102);">void</span> setItemDao<span style="color: rgb(0, 0, 0);">(</span>ItemDao itemDao<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">{</span> this.<span style="color: rgb(0, 0, 0);">itemDao</span> = itemDao;<span style="color: rgb(0, 0, 0);">}</span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">public</span> Bid loadItemById<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(170, 170, 221);">Long</span> id<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">{</span><br />        itemDao.<span style="color: rgb(0, 0, 0);">loadItemById</span><span style="color: rgb(0, 0, 0);">(</span>id<span style="color: rgb(0, 0, 0);">)</span>; <br />    <span style="color: rgb(0, 0, 0);">}</span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">public</span><span style="color: rgb(170, 170, 221);">Collection</span> listAllItems<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">{</span><br />        <span style="font-weight: bold; color: rgb(153, 0, 102);">return</span>  itemDao.<span style="color: rgb(0, 0, 0);">findAll</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span>; <br />    <span style="color: rgb(0, 0, 0);">}</span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">public</span> Bid placeBid<span style="color: rgb(0, 0, 0);">(</span>Item item, User bidder, MonetaryAmount bidAmount, <br />                            Bid currentMaxBid, Bid currentMinBid<span style="color: rgb(0, 0, 0);">)</span><span style="font-weight: bold; color: rgb(153, 0, 102);">throws</span> BusinessException <span style="color: rgb(0, 0, 0);">{</span><br />            <span style="font-weight: bold; color: rgb(153, 0, 102);">if</span><span style="color: rgb(0, 0, 0);">(</span>currentMaxBid != <span style="font-weight: bold; color: rgb(153, 0, 102);">null</span> && currentMaxBid.<span style="color: rgb(0, 0, 0);">getAmount</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span>.<span style="color: rgb(0, 0, 0);">compareTo</span><span style="color: rgb(0, 0, 0);">(</span>bidAmount<span style="color: rgb(0, 0, 0);">)</span> > <span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">{</span><br />            throw <span style="font-weight: bold; color: rgb(153, 0, 102);">new</span> BusinessException<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">"Bid too low."</span><span style="color: rgb(0, 0, 0);">)</span>; <br />    <span style="color: rgb(0, 0, 0);">}</span><br />    <br />    <span style="color: rgb(102, 102, 255);">// Auction is active</span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">if</span><span style="color: rgb(0, 0, 0);">(</span> !state.<span style="color: rgb(0, 0, 0);">equals</span><span style="color: rgb(0, 0, 0);">(</span>ItemState.<span style="color: rgb(0, 0, 0);">ACTIVE</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">)</span><br />            throw <span style="font-weight: bold; color: rgb(153, 0, 102);">new</span> BusinessException<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">"Auction is not active yet."</span><span style="color: rgb(0, 0, 0);">)</span>; <br />    <br />    <span style="color: rgb(102, 102, 255);">// Auction still valid</span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">if</span><span style="color: rgb(0, 0, 0);">(</span> item.<span style="color: rgb(0, 0, 0);">getEndDate</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span>.<span style="color: rgb(0, 0, 0);">before</span><span style="color: rgb(0, 0, 0);">(</span><span style="font-weight: bold; color: rgb(153, 0, 102);">new</span><span style="color: rgb(170, 170, 221);">Date</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">)</span><br />            throw <span style="font-weight: bold; color: rgb(153, 0, 102);">new</span> BusinessException<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">"Can't place new bid, auction already ended."</span><span style="color: rgb(0, 0, 0);">)</span>; <br />    <br />    <span style="color: rgb(102, 102, 255);">// Create new Bid</span><br />    Bid newBid = <span style="font-weight: bold; color: rgb(153, 0, 102);">new</span> Bid<span style="color: rgb(0, 0, 0);">(</span>bidAmount, item, bidder<span style="color: rgb(0, 0, 0);">)</span>; <br />    <br />    <span style="color: rgb(102, 102, 255);">// Place bid for this Item</span><br />    item.<span style="color: rgb(0, 0, 0);">getBids</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span>.<span style="color: rgb(0, 0, 0);">add</span><span style="color: rgb(0, 0, 0);">(</span>newBid<span style="color: rgb(0, 0, 0);">)</span>; <br />    itemDao.<span style="color: rgb(0, 0, 0);">update</span><span style="color: rgb(0, 0, 0);">(</span>item<span style="color: rgb(0, 0, 0);">)</span>;     <span style="color: rgb(102, 102, 255);">//  调用DAO完成持久化操?/span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">return</span> newBid; <br />    <span style="color: rgb(0, 0, 0);">}</span><br /><span style="color: rgb(0, 0, 0);">}</span></font> </div> <br /> </td> </tr> </tbody> </table> <span> <br /> <br />事务的管理是在ItemMangerq一层完成的QItemManager实现具体的业务逻辑。除了常见的和CRUD有关的简单逻辑之外Q这里还有一个placeBid的逻辑Q即目的竞标? <br /><br />以上是一个完整的W一U模型的CZ代码。在q个CZ中,placeBidQloadItemByIdQfindAll{等业务逻辑l统攑֜ItemManager中实玎ͼ而Item只有getter/setterҎ(gu)?/span> </div> <p> </p> <p> </p> <p> <span>W二U模型,也就是Martin Fowler指的rich domain object是下面这样子的:(x) <br /><br />一个带有业务逻辑的实体类Q即domain object是Item <br />一个DAO接口ItemDao <br />一个DAO实现ItemDaoHibernateImpl <br />一个业务逻辑对象ItemManager <br /><br /></span> </p> <table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"> <tbody> <tr> <td> <span> <b>java代码: </b> </span> </td> </tr> <tr> <td> <div style="font-family: 'Courier New',Courier,monospace;"> <br /> <font face="Courier New"> <span style="font-weight: bold; color: rgb(153, 0, 102);">public</span> <span style="font-weight: bold; color: rgb(153, 0, 102);">class</span> Item <span style="font-weight: bold; color: rgb(153, 0, 102);">implements</span><span style="color: rgb(170, 170, 221);">Serializable</span><span style="color: rgb(0, 0, 0);">{</span><br />    <span style="color: rgb(102, 102, 255);">//  所有的属性和getter/setterҎ(gu)同上Q省?/span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">public</span> Bid placeBid<span style="color: rgb(0, 0, 0);">(</span>User bidder, MonetaryAmount bidAmount, <br />                        Bid currentMaxBid, Bid currentMinBid<span style="color: rgb(0, 0, 0);">)</span><br />            <span style="font-weight: bold; color: rgb(153, 0, 102);">throws</span> BusinessException <span style="color: rgb(0, 0, 0);">{</span><br />    <br />            <span style="color: rgb(102, 102, 255);">// Check highest bid (can also be a different Strategy (pattern))</span><br />            <span style="font-weight: bold; color: rgb(153, 0, 102);">if</span><span style="color: rgb(0, 0, 0);">(</span>currentMaxBid != <span style="font-weight: bold; color: rgb(153, 0, 102);">null</span> && currentMaxBid.<span style="color: rgb(0, 0, 0);">getAmount</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span>.<span style="color: rgb(0, 0, 0);">compareTo</span><span style="color: rgb(0, 0, 0);">(</span>bidAmount<span style="color: rgb(0, 0, 0);">)</span> > <span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">{</span><br />                    throw <span style="font-weight: bold; color: rgb(153, 0, 102);">new</span> BusinessException<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">"Bid too low."</span><span style="color: rgb(0, 0, 0);">)</span>; <br />            <span style="color: rgb(0, 0, 0);">}</span><br />    <br />            <span style="color: rgb(102, 102, 255);">// Auction is active</span><br />            <span style="font-weight: bold; color: rgb(153, 0, 102);">if</span><span style="color: rgb(0, 0, 0);">(</span> !state.<span style="color: rgb(0, 0, 0);">equals</span><span style="color: rgb(0, 0, 0);">(</span>ItemState.<span style="color: rgb(0, 0, 0);">ACTIVE</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">)</span><br />                    throw <span style="font-weight: bold; color: rgb(153, 0, 102);">new</span> BusinessException<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">"Auction is not active yet."</span><span style="color: rgb(0, 0, 0);">)</span>; <br />    <br />            <span style="color: rgb(102, 102, 255);">// Auction still valid</span><br />            <span style="font-weight: bold; color: rgb(153, 0, 102);">if</span><span style="color: rgb(0, 0, 0);">(</span> this.<span style="color: rgb(0, 0, 0);">getEndDate</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span>.<span style="color: rgb(0, 0, 0);">before</span><span style="color: rgb(0, 0, 0);">(</span><span style="font-weight: bold; color: rgb(153, 0, 102);">new</span><span style="color: rgb(170, 170, 221);">Date</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">)</span><br />                    throw <span style="font-weight: bold; color: rgb(153, 0, 102);">new</span> BusinessException<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">"Can't place new bid, auction already ended."</span><span style="color: rgb(0, 0, 0);">)</span>; <br />    <br />            <span style="color: rgb(102, 102, 255);">// Create new Bid</span><br />            Bid newBid = <span style="font-weight: bold; color: rgb(153, 0, 102);">new</span> Bid<span style="color: rgb(0, 0, 0);">(</span>bidAmount, this, bidder<span style="color: rgb(0, 0, 0);">)</span>; <br />    <br />            <span style="color: rgb(102, 102, 255);">// Place bid for this Item</span><br />            this.<span style="color: rgb(0, 0, 0);">getBids</span>.<span style="color: rgb(0, 0, 0);">add</span><span style="color: rgb(0, 0, 0);">(</span>newBid<span style="color: rgb(0, 0, 0);">)</span>;  <span style="color: rgb(102, 102, 255);">// h意这一句,透明的进行了持久化,但是不能在这里调用ItemDaoQItem不能对ItemDao产生依赖Q?/span><br />    <br />            <span style="font-weight: bold; color: rgb(153, 0, 102);">return</span> newBid; <br />    <span style="color: rgb(0, 0, 0);">}</span><br /><span style="color: rgb(0, 0, 0);">}</span></font> </div> <br /> </td> </tr> </tbody> </table> <span> <br /> <br />竞标q个业务逻辑被放入到Item中来。请注意this.getBids.add(newBid); 如果没有Hibernate或者JDOq种O/R Mapping的支持,我们是无法实现这U透明的持久化行ؓ(f)的。但是请注意QItem里面不能去调用ItemDAOQ对ItemDAO产生依赖Q? <br /><br />ItemDao和ItemDaoHibernateImpl的代码同上,省略?<br /><br /></span> <table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"> <tbody> <tr> <td> <span> <b>java代码: </b> </span> </td> </tr> <tr> <td> <div style="font-family: 'Courier New',Courier,monospace;"> <br /> <font face="Courier New"> <span style="font-weight: bold; color: rgb(153, 0, 102);">public</span> <span style="font-weight: bold; color: rgb(153, 0, 102);">class</span> ItemManager <span style="color: rgb(0, 0, 0);">{</span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">private</span> ItemDao itemDao; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">public</span><span style="font-weight: bold; color: rgb(153, 0, 102);">void</span> setItemDao<span style="color: rgb(0, 0, 0);">(</span>ItemDao itemDao<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">{</span> this.<span style="color: rgb(0, 0, 0);">itemDao</span> = itemDao;<span style="color: rgb(0, 0, 0);">}</span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">public</span> Bid loadItemById<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(170, 170, 221);">Long</span> id<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">{</span><br />        itemDao.<span style="color: rgb(0, 0, 0);">loadItemById</span><span style="color: rgb(0, 0, 0);">(</span>id<span style="color: rgb(0, 0, 0);">)</span>; <br />    <span style="color: rgb(0, 0, 0);">}</span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">public</span><span style="color: rgb(170, 170, 221);">Collection</span> listAllItems<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">{</span><br />        <span style="font-weight: bold; color: rgb(153, 0, 102);">return</span>  itemDao.<span style="color: rgb(0, 0, 0);">findAll</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span>; <br />    <span style="color: rgb(0, 0, 0);">}</span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">public</span> Bid placeBid<span style="color: rgb(0, 0, 0);">(</span>Item item, User bidder, MonetaryAmount bidAmount, <br />                            Bid currentMaxBid, Bid currentMinBid<span style="color: rgb(0, 0, 0);">)</span><span style="font-weight: bold; color: rgb(153, 0, 102);">throws</span> BusinessException <span style="color: rgb(0, 0, 0);">{</span><br />        item.<span style="color: rgb(0, 0, 0);">placeBid</span><span style="color: rgb(0, 0, 0);">(</span>bidder, bidAmount, currentMaxBid, currentMinBid<span style="color: rgb(0, 0, 0);">)</span>; <br />        itemDao.<span style="color: rgb(0, 0, 0);">update</span><span style="color: rgb(0, 0, 0);">(</span>item<span style="color: rgb(0, 0, 0);">)</span>;    <span style="color: rgb(102, 102, 255);">// 必须昑ּ的调用DAOQ保持持久化</span><br />    <span style="color: rgb(0, 0, 0);">}</span><br /><span style="color: rgb(0, 0, 0);">}</span></font> </div> <br /> </td> </tr> </tbody> </table> <span> <br /> <br />在第二种模型中,placeBid业务逻辑是放在Item中实现的Q而loadItemById和findAll业务逻辑是放? ItemManager中实现的。不q值得注意的是Q即使placeBid业务逻辑攑֜Item中,你仍焉要在ItemManager中简单的装一层,以保证对placeBid业务逻辑q行事务的管理和持久化的触发? <br /><br />q种模型是Martin Fowler所指的真正的domain model。在q种模型中,有三个业务逻辑Ҏ(gu)QplaceBidQloadItemById和findAllQ现在的问题是哪个逻辑应该攑֜Item 中,哪个逻辑应该攑֜ItemManager中。在我们q个例子中,placeBid攑֜Item?但是ItemManager也需要对它进行简单的装)QloadItemById和findAll是放在ItemManager中的? <br /><br />切分的原则是什么呢Q?Rod Johnson提出原则是“case by case”,可重用度高的Q和domain object状态密切关联的攑֜Item中,可重用度低的Q和domain object状态没有密切关联的攑֜ItemManager中?<br /><br /><span style="color: red;">我提出的原则是:(x)看业务方法是否显式的依赖持久化?/span><br /><br />Item的placeBidq个业务逻辑Ҏ(gu)没有昑ּ的对持久化ItemDao接口产生依赖Q所以要攑֜Item中?span style="color: red;">h意,如果q了Hibernateq个持久化框ӞItemq个domain object是可以进行单元测试的Q他不依赖于Hibernate的持久化机制。它是一个独立的Q可UL的,完整的,自包含的域对?/span>? <br /><br />而loadItemById和findAllq两个业务逻辑Ҏ(gu)是必L式的Ҏ(gu)久化ItemDao接口产生依赖Q否则这个业务逻辑无法完成。如果你要把q两个方法放在Item中,那么Item无法脱Hibernate框架Q无法在Hibernate框架之外独立存在?/span> <p> </p> <p> </p> <p> <span>W三U模型印象中好像是firebody或者是Archie提出?也有可能不是Q记不清楚了)Q简单的来说Q这U模型就是把W二U模型的domain object和business object合二Z了。所以ItemManager׃需要了Q在q种模型下面Q只有三个类Q他们分别是Q? <br /><br />ItemQ包含了实体cM息,也包含了所有的业务逻辑 <br />ItemDaoQ持久化DAO接口c? <br />ItemDaoHibernateImplQDAO接口的实现类 <br /><br />׃ItemDao和ItemDaoHibernateImpl和上面完全相同,q略了?<br /><br /></span> </p> <table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"> <tbody> <tr> <td> <span> <b>java代码: </b> </span> </td> </tr> <tr> <td> <div style="font-family: 'Courier New',Courier,monospace;"> <br /> <font face="Courier New"> <span style="font-weight: bold; color: rgb(153, 0, 102);">public</span> <span style="font-weight: bold; color: rgb(153, 0, 102);">class</span> Item <span style="font-weight: bold; color: rgb(153, 0, 102);">implements</span><span style="color: rgb(170, 170, 221);">Serializable</span><span style="color: rgb(0, 0, 0);">{</span><br />    <span style="color: rgb(102, 102, 255);">//  所有的属性和getter/setterҎ(gu)都省?/span><br />   <span style="font-weight: bold; color: rgb(153, 0, 102);">private</span><span style="font-weight: bold; color: rgb(153, 0, 102);">static</span> ItemDao itemDao; <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">public</span><span style="font-weight: bold; color: rgb(153, 0, 102);">void</span> setItemDao<span style="color: rgb(0, 0, 0);">(</span>ItemDao itemDao<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">{</span>this.<span style="color: rgb(0, 0, 0);">itemDao</span> = itemDao;<span style="color: rgb(0, 0, 0);">}</span><br />    <br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">public</span><span style="font-weight: bold; color: rgb(153, 0, 102);">static</span> Item loadItemById<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(170, 170, 221);">Long</span> id<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">{</span><br />        <span style="font-weight: bold; color: rgb(153, 0, 102);">return</span><span style="color: rgb(0, 0, 0);">(</span>Item<span style="color: rgb(0, 0, 0);">)</span> itemDao.<span style="color: rgb(0, 0, 0);">loadItemById</span><span style="color: rgb(0, 0, 0);">(</span>id<span style="color: rgb(0, 0, 0);">)</span>; <br />    <span style="color: rgb(0, 0, 0);">}</span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">public</span><span style="font-weight: bold; color: rgb(153, 0, 102);">static</span><span style="color: rgb(170, 170, 221);">Collection</span> findAll<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">{</span><br />        <span style="font-weight: bold; color: rgb(153, 0, 102);">return</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(170, 170, 221);">List</span><span style="color: rgb(0, 0, 0);">)</span> itemDao.<span style="color: rgb(0, 0, 0);">findAll</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span>; <br />    <span style="color: rgb(0, 0, 0);">}</span><br /><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">public</span> Bid placeBid<span style="color: rgb(0, 0, 0);">(</span>User bidder, MonetaryAmount bidAmount, <br />                    Bid currentMaxBid, Bid currentMinBid<span style="color: rgb(0, 0, 0);">)</span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">throws</span> BusinessException <span style="color: rgb(0, 0, 0);">{</span><br />    <br />        <span style="color: rgb(102, 102, 255);">// Check highest bid (can also be a different Strategy (pattern))</span><br />        <span style="font-weight: bold; color: rgb(153, 0, 102);">if</span><span style="color: rgb(0, 0, 0);">(</span>currentMaxBid != <span style="font-weight: bold; color: rgb(153, 0, 102);">null</span> && currentMaxBid.<span style="color: rgb(0, 0, 0);">getAmount</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span>.<span style="color: rgb(0, 0, 0);">compareTo</span><span style="color: rgb(0, 0, 0);">(</span>bidAmount<span style="color: rgb(0, 0, 0);">)</span> > <span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">{</span><br />                throw <span style="font-weight: bold; color: rgb(153, 0, 102);">new</span> BusinessException<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">"Bid too low."</span><span style="color: rgb(0, 0, 0);">)</span>; <br />        <span style="color: rgb(0, 0, 0);">}</span><br />        <br />        <span style="color: rgb(102, 102, 255);">// Auction is active</span><br />        <span style="font-weight: bold; color: rgb(153, 0, 102);">if</span><span style="color: rgb(0, 0, 0);">(</span> !state.<span style="color: rgb(0, 0, 0);">equals</span><span style="color: rgb(0, 0, 0);">(</span>ItemState.<span style="color: rgb(0, 0, 0);">ACTIVE</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">)</span><br />                throw <span style="font-weight: bold; color: rgb(153, 0, 102);">new</span> BusinessException<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">"Auction is not active yet."</span><span style="color: rgb(0, 0, 0);">)</span>; <br />        <br />        <span style="color: rgb(102, 102, 255);">// Auction still valid</span><br />        <span style="font-weight: bold; color: rgb(153, 0, 102);">if</span><span style="color: rgb(0, 0, 0);">(</span> this.<span style="color: rgb(0, 0, 0);">getEndDate</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span>.<span style="color: rgb(0, 0, 0);">before</span><span style="color: rgb(0, 0, 0);">(</span><span style="font-weight: bold; color: rgb(153, 0, 102);">new</span><span style="color: rgb(170, 170, 221);">Date</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">)</span><br />                throw <span style="font-weight: bold; color: rgb(153, 0, 102);">new</span> BusinessException<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">"Can't place new bid, auction already ended."</span><span style="color: rgb(0, 0, 0);">)</span>; <br />        <br />        <span style="color: rgb(102, 102, 255);">// Create new Bid</span><br />        Bid newBid = <span style="font-weight: bold; color: rgb(153, 0, 102);">new</span> Bid<span style="color: rgb(0, 0, 0);">(</span>bidAmount, this, bidder<span style="color: rgb(0, 0, 0);">)</span>; <br />        <br />        <span style="color: rgb(102, 102, 255);">// Place bid for this Item</span><br />        this.<span style="color: rgb(0, 0, 0);">addBid</span><span style="color: rgb(0, 0, 0);">(</span>newBid<span style="color: rgb(0, 0, 0);">)</span>; <br />        itemDao.<span style="color: rgb(0, 0, 0);">update</span><span style="color: rgb(0, 0, 0);">(</span>this<span style="color: rgb(0, 0, 0);">)</span>;      <span style="color: rgb(102, 102, 255);">//  调用DAOq行昑ּ持久?/span><br />        <span style="font-weight: bold; color: rgb(153, 0, 102);">return</span> newBid; <br />    <span style="color: rgb(0, 0, 0);">}</span><br /><span style="color: rgb(0, 0, 0);">}</span></font> </div> <br /> </td> </tr> </tbody> </table> <span> <br /> <br />在这U模型中Q所有的业务逻辑全部都在Item中,事务理也在Item中实现?/span> <p> </p> <p> </p> <p> <span>在上面三U模型之外,q有很多q三U模型的变种Q例如partech的模型就是把W二U模型中的DAO? Manager三个cdqؓ(f)一个类后Ş成的模型Q例如frain....(id很长C?的模型就是把W三U模型的三个cd全合qؓ(f)一个单cd形成的模型;例如Archie是把W三U模型的Item又分出来一些纯数据c?可能是,不确?形成的一个模型? <br /><br />但是不管怎么变,基本模型归纳h是上面的三U模型,下面分别单评价一下:(x) <br /><br />W一U模型绝大多Ch都反对,因此反对理由我也不多讲了。但遗憾的是Q我观察到的实际情Ş是,很多使用Hibernate的公司最后都是这U模型,q里面有很大的原因是很多公司的技术水qx有达到这U层ơ,所以导致了q种贫血模型的出现。从q一Ҏ(gu)_(d)Martin Fowler的批评声音不是太响了Q而是太弱了,q需要再l箋呐喊?<br /><br />W二U模型就是Martin Fowler一直主张的模型Q实际上也是我一直在实际目中采用这U模型。我没有看过Martin的POEAAQ之所以能够自己摸索到q种模型Q也是因Z02q我已经开始思考这个问题ƈ且寻求解x案了Q但是当时没有看到HibernateQ那时候做的一个小型项目我已经按照q种模型来做了,但是׃没有O/R Mapping的支持,写到后来又不得不全部Ҏ(gu)贫血的domain objectQ项目做完以后再l箋找,随后发CHibernate。当Ӟ现在很多Z开始就是用Hibernate做项目,没有l历q我l历的那个阶Dc(din)? <br /><br />不过我觉得这U模型仍然不够完,因ؓ(f)你还是需要一个业务逻辑层来装所有的domain logicQ这昑־非常|嗦Qƈ且业务逻辑对象的接口也不够E_。如果不考虑业务逻辑对象的重用性的?业务逻辑对象的可重用性也不可能好)Q很多hq脆去掉了xxxManagerq一层,在Web层的Action代码直接调用xxxDaoQ同时容器事务管理配|到Actionq一层上来? Hibernate的caveatemptor是q样架构的一个典型应用?<br /><br />W三U模型是我很反对的一U模型,q种模型下面QDomain Object和DAO形成了双向依赖关p,无法q框架试Qƈ且业务逻辑层的服务也和持久层对象的状态耦合C一P?x)造成E序的高度的复杂性,很差的灵zL和p糕的可l护性。也许将来技术进步导致的O/R Mapping理下的domain object发展到够的动态持久透明化的话,q种模型才会(x)成ؓ(f)一个理想的选择。就像O/R Mapping的流行得第二种模型成ؓ(f)了可?O/R Mapping行以前Q我们只能用W一U模型,W二U模型那时候是不现实的)?/span> </p> <p> </p> <p> </p> <p> <span>既然大家都统一了观点,那么有了一个很好的讨论问题的基了。Martin Fowler的Domain ModelQ或者说我们的第二种模型N是完无~的吗?当然不是Q接下来我就要分析一下它的不I以及(qing)可能的解军_法,而这些都来源于我个h的实跉|索? <br /><br />在第二种模型中,我们可以清楚的把q?个类分ؓ(f)三层Q?<br /><br />1、实体类层,即ItemQ带有domain logic的domain object <br />2、DAO层,即ItemDao和ItemDaoHibernateImplQ抽象持久化操作的接口和实现c? <br />3、业务逻辑层,即ItemManagerQ接受容器事务控Ӟ向Web层提供统一的服务调?<br /><br />在这三层中我们大家可以看刎ͼdomain object和DAO都是非常E_的层Q其实原因也很简单,因ؓ(f)domain object是映数据库字段的,数据库字D不?x)频J变动,所以domain object也相对稳定,而面向数据库持久化编E的DAO层也不过是CRUD而已Q不?x)有更多的花P所以也很稳定? <br /><br />问题在于这个充当business workflow facade的业务逻辑对象Q它的变动是相当频繁的?span style="color: red;">业务逻辑对象通常都是无状态的、受事务控制的、Singletonc?/span>Q我们可以考察一下业务逻辑对象都有哪几cM务逻辑Ҏ(gu)Q? <br /><br /><span style="color: red;">W一c:(x)DAO接口Ҏ(gu)的代?/span>Q就是上面例子中的loadItemByIdҎ(gu)和findAllҎ(gu)? <br /><br />ItemManager之所以要代理q种c,目的有两个:(x)<span style="color: red;">向Web层提供统一的服务调用入口点和给持久化方法增加事务控制功?/span>。这两点都很Ҏ(gu)理解Q你不能既给Web层程序员提供xxxManagerQ也l他提供xxxDaoQ所以你需要用xxxManager装xxxDaoQ在q里Q充当了一个简单代理功能;而事务控制也是持久化Ҏ(gu)必须的,事务可能需要跨多个DAOҎ(gu)调用Q所以必L在业务逻辑层,而不能放在DAO层? <br /><br />但是必须看到Q对于一个典型的web应用来说Q绝大多数的业务逻辑都是单的CRUD逻辑Q所以这U情况下Q针Ҏ(gu)个DAOҎ(gu)QxxxManager都需要提供一个对应的装Ҏ(gu)Q这不但是非常枯燥的Q也是o(h)人感觉非怸好的? <br /><br /><br /><span style="color: red;">W二c:(x)domain logic的方法代?/span>。就是上面例子中placeBidҎ(gu)。虽然Item已经有了placeBidҎ(gu)Q但是ItemManager仍然需要封装一下Item的placeBidQ然后再提供一个简单封装之后的代理Ҏ(gu)? <br /><br />q和W一U情늱|其原因也一P也是ZlWeb层提供一个统一的服务调用入口点和给隐式的持久化动作提供事务控制? <br /><br />同样Q和W一U情况一P针对每个domain logicҎ(gu)QxxxManager都需要提供一个对应的装Ҏ(gu)Q同h枯燥的,令h不爽的? <br /><br /><br /><span style="color: red;">W三c:(x)需要多个domain object和DAO参与协作的business workflow</span>。这U情冉|业务逻辑对象真正应该完成的职责? <br /><br />在这个简单的例子中,没有涉及(qing)到这U情况,不过大家都可以想像的出来q种应用场景Q因此不必D例说明了? <br /><br />通过上面的分析可以看出,只有W三cM务逻辑Ҏ(gu)才是业务逻辑对象真正应该承担的职责,而前两类业务逻辑Ҏ(gu)都是“无奈之䏀,不得不ؓ(f)之的事情Q不但枯燥,而且令h沮? <br /><br /><br /><br /><br />分析完了业务逻辑对象Q我们再回头看一下domain objectQ我们要仔细考察一下domain logic的话Q会(x)发现domain logic也分Zc:(x) <br /><br /><span style="color: red;">W一c:(x)需要持久层框架隐式的实现透明持久化的domain logic</span>Q例如Item的placeBidҎ(gu)中的q一句:(x) <br /></span> </p> <table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"> <tbody> <tr> <td> <span> <b>java代码: </b> </span> </td> </tr> <tr> <td> <div style="font-family: 'Courier New',Courier,monospace;"> <br />this.<font face="Courier New"><span style="color: rgb(0, 0, 0);">getBids</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span>.<span style="color: rgb(0, 0, 0);">add</span><span style="color: rgb(0, 0, 0);">(</span>newBid<span style="color: rgb(0, 0, 0);">)</span></font>;</div> <br /> </td> </tr> </tbody> </table> <span> <br />上面已经着重提刎ͼ虽然q仅仅只是一个Java集合的添加新元素的操作,但是实际上通过事务的控Ӟ?x)潜在的触发两条SQLQ一条是insert一条记录到bid表,一条是更新item表相应的记录。如果我们让ItemqHibernateq行单元试Q它?yu)是一个单U的Java集合操作Q如果我们把他加入到Hibernate框架中,他就?x)潜在的触发两条SQLQ?span style="color: red;">q就是隐式的依赖于持久化的domain logic</span>? <br />特别h意的一Ҏ(gu)Q在没有Hibernate/JDOq类可以实现“透明的持久化”工具出C前,q类domain logic是无法实现的? <br /><br />对于q一cdomain logicQ业务逻辑对象必须提供相应的封装方法,以实C务控制?<br /><br /><br /><span style="color: red;">W二c:(x)完全不依赖持久化的domain logic</span>Q例如readonly例子中的TopicQ如下:(x) <br /><br /></span> <table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"> <tbody> <tr> <td> <span> <b>java代码: </b> </span> </td> </tr> <tr> <td> <div style="font-family: 'Courier New',Courier,monospace;"> <br /> <font face="Courier New"> <span style="font-weight: bold; color: rgb(153, 0, 102);">class</span> Topic <span style="color: rgb(0, 0, 0);">{</span><br />    <span style="font-weight: bold; color: rgb(153, 0, 102);">boolean</span> isAllowReply<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">{</span><br />        <span style="color: rgb(170, 170, 221);">Calendar</span> dueDate = <span style="color: rgb(170, 170, 221);">Calendar</span>.<span style="color: rgb(0, 0, 0);">getInstance</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span>; <br />        dueDate.<span style="color: rgb(0, 0, 0);">setTime</span><span style="color: rgb(0, 0, 0);">(</span>lastUpdatedTime<span style="color: rgb(0, 0, 0);">)</span>; <br />        dueDate.<span style="color: rgb(0, 0, 0);">add</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(170, 170, 221);">Calendar</span>.<span style="color: rgb(0, 0, 0);">DATE</span>, forum.<span style="color: rgb(0, 0, 0);">timeToLive</span><span style="color: rgb(0, 0, 0);">)</span>; <br />    <br />        <span style="color: rgb(170, 170, 221);">Date</span> now = <span style="font-weight: bold; color: rgb(153, 0, 102);">new</span><span style="color: rgb(170, 170, 221);">Date</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span>; <br />        <span style="font-weight: bold; color: rgb(153, 0, 102);">return</span> now.<span style="color: rgb(0, 0, 0);">after</span><span style="color: rgb(0, 0, 0);">(</span>dueDate.<span style="color: rgb(0, 0, 0);">getTime</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">)</span>; <br />    <span style="color: rgb(0, 0, 0);">}</span><br /><span style="color: rgb(0, 0, 0);">}</span></font> </div> <br /> </td> </tr> </tbody> </table> <span> <br /> <br />注意q个isAllowReplyҎ(gu)Q他和持久化完全不发生一丁点关系。在实际的开发中Q我们同样会(x)遇到很多q种不需要持久化的业务逻辑(主要发生在日期运、数D和枚Dq算斚w)Q这Udomain logic不管q不脱L在的框架Q它的行为都是一致的。对于这Udomain logicQ业务逻辑层ƈ不需要提供封装方法,它可以适用于Q何场合?/span> <img src ="http://www.tkk7.com/GandofYan/aggbug/48954.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/GandofYan/" target="_blank">h中立</a> 2006-05-30 13:31 <a href="http://www.tkk7.com/GandofYan/archive/2006/05/30/48954.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]O/R Mapping 基本概念http://www.tkk7.com/GandofYan/archive/2006/05/30/48945.htmlh中立h中立Tue, 30 May 2006 05:20:00 GMThttp://www.tkk7.com/GandofYan/archive/2006/05/30/48945.htmlhttp://www.tkk7.com/GandofYan/comments/48945.htmlhttp://www.tkk7.com/GandofYan/archive/2006/05/30/48945.html#Feedback0http://www.tkk7.com/GandofYan/comments/commentRss/48945.htmlhttp://www.tkk7.com/GandofYan/services/trackbacks/48945.html
原文地址Q?a >http://www.cnblogs.com/idior/archive/2005/07/04/186086.html

q日 有关o/r m的讨论突然多了v? 在这里觉得有必要澄清一些概? 免的大家讨论来讨论去, 才发现最Ҏ(gu)的理解有问题.

1. 何谓实体?
实体(cM于j2ee中的Entity Bean)通常指一个承载数据的对象, 但是注意它也是可以有行ؓ(f)? 只不q它的行Z般只操作自n的数? 比如下面q个例子:


class Person
{
  string firstName;
  string lastName;

  public void GetName()
  {
     return  lastName+firstName;
  }   
}


GetName是它的一个行?

2 何谓对象?
对象最重要的特性在于它拥有行ؓ(f). 仅仅拥有数据,你可以称它ؓ(f)对象, 但是它却失去它最重要的灵? 


class Person
{
  string firstName;
  string lastName;
  Role role;
  int baseWage;
  public void GetSalary()
  {
     return baseWage*role.GetFactory();
  }   
}

q样需要和别的对象(不是Value Object)打交道的对象,我就不再U其为实? 领域模型是指由q些h业务逻辑的对象构成的模型.

3. E/R M or O/R M?!!
仔细x我们Z么需要o/r m,无非是想利用oo的多态来处理复杂的业务逻辑, 而不是靠一堆的if else. 
而现在在很多人的手上o/r m全变成了e/r m.他们不考虑对象的行? 而全x于如何保存数?q样也难怪他们会(x)产生CRUDq些操作攑օ对象中的念头. 如果你不能深ȝ解oo, 那么我不推荐你用o/r m, Table Gateway, Row Gateway才是你想要的东西.


作ؓ(f)一个O/R M框架Q很重要的一点就是实现映的透明性(TransparentQ,比较显著的特点就是在代码中我们是看不到SQL语句的(框架自动生成了)。这里所指的O/R M是cM于此的框Ӟ

4. POEAA中的相关概念
  很多ơ发现有人错用其中的概念, q里Zȝ一?
  1. Table Gateway
    以表为单位的实体,基本没有行ؓ(f),只有CRUD操作.
  2. Row Gateway
    以行为单位的实体,基本没有行ؓ(f),只有CRUD操作.
  3. Active Record
    以行为单位的实体,拥有一些基本的操作自n数据的行?如上例中的GetName),同时包含有CRUD操作.
其实Active Record最W合某些单的需? 接近于E/R m.
通常也有很多人把它当作O/R m.不过需要注意的是Active Record中是充满了SQL语句?不像orm的SQL透明), 所以有人想h利用O/R m来实?Active Record", 虽然在他们眼里看h很方? 其实Ҏ(gu)是q祖.
用CodeGenerator来实现Active Record也许是一个比较好的方?
  4. Data Mapper
q才是真正的O/R m,Hibernate{等工具的目?

5.O/R M需要关注的地方 (希望大家帮忙完善一?
 1. 兌, O/R M是如何管理类之间的关?当然q不仅于o/r m有关与设计者的设计水^也有很大关系.
 2. O/R M对承关pȝ处理.
 3. O/R M对事务的支持.
 4. O/R MҎ(gu)询的支持.
 
以上观点仅属个h意见, 不过在大家讨论有关O/R m之前, 希望先就一些基本概念达成共? 不然讨论下去?x)越越q? 


(: 如果对oo以及(qing)dp没有一定程度的了解, 最好别使用o/r m, dataset 加上codesmith或许是更好的选择)


h中立 2006-05-30 13:20 发表评论
]]> վ֩ģ壺 ޾Ʒھþ| ҹ޸˾| avר߹ۿ| þþþù˾Ʒҹ| ŷպۺϰȥ| ƵѲ| ߹ۿ| 97޳| ҹƷ| Ұһ| ŮƵӴȫƵѵ| ѹۿСˮ| þ99Ʒѿ| þþþAVƬ| ձػػƴ̼Ƭ| ѹۿĹƵ| ޹ֻ߹ۿ | ˳˳ۺ| þþƷ| һëƬ߹ۿ| 91㽹߹ۿ| ձѸ| ձɱ˹ۿ| þþƷavƷ| ޳ҹӰ| heyzo޾Ʒպ| ձvaҹĻþ | һƵ| һƷ| Ů18ëƬaëƬ| ĻƵ| һësuvÿĹվ| ޳aƬ߹ۿ| ޵ӰպƷ| һѿ| ޾Ʒ| Ļ޵һ| ޺Ļ| ɫɫWWW| ӰԺδʮվ| һػaƬ|