<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_编写人生</title><subtitle type="text">写写代码，写写人生</subtitle><id>http://feed.cnblogs.com/blog/u/7606/rss</id><updated>2011-12-26T10:35:36Z</updated><author><name>编写人生</name><uri>http://www.cnblogs.com/tansm/</uri></author><generator>CNBlogs BlogServer</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/tansm/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/7606/rss"/><entry><id>http://www.cnblogs.com/tansm/archive/2011/12/26/2302421.html</id><title type="text">我喜欢吃白米饭</title><summary type="text">晚上一个人，就跑到街边的那种沙县小吃吃个快餐。小店很小，只有六张桌子，我正闷头吃饭呢，突然听见一个人怒斥着什么，我抬头，只见一个长的蛮高的小伙子，大约1米8了，冬天的衣服过的厚厚的，更显得魁梧了。旁边站着一个妇女，估计是他的妈妈，我听不清他们说什么，隐约听见什么大排还是大肉，辣椒，还有加一份青菜什么的。我又低头吃饭，一会儿他们的快餐上来了，因为他们坐下了，又坐在我的斜对角，所以听得清楚了一些。快餐只上了一份，小伙子在吃，他吃的狼吞虎咽，显然饿极了。妈妈坐在旁边，指指那个青菜，显然对额外添加的青菜不满意，在那里咕咕叨叨，小伙子没理睬他，只顾吃饭。那点饭显然不够小伙子吃，我估计也就20秒吧，饭快没</summary><published>2011-12-26T10:36:00Z</published><updated>2011-12-26T10:36:00Z</updated><author><name>编写人生</name><uri>http://www.cnblogs.com/tansm/</uri></author><link rel="alternate" href="http://www.cnblogs.com/tansm/archive/2011/12/26/2302421.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/tansm/archive/2011/12/26/2302421.html"/><content type="html">&lt;p&gt;晚上一个人，就跑到街边的那种沙县小吃吃个快餐。&lt;/p&gt;&#xD;
&lt;p&gt;小店很小，只有六张桌子，我正闷头吃饭呢，突然听见一个人怒斥着什么，我抬头，只见一个长的蛮高的小伙子，大约1米8了，冬天的衣服过的厚厚的，更显得魁梧了。旁边站着一个妇女，估计是他的妈妈，我听不清他们说什么，隐约听见什么大排还是大肉，辣椒，还有加一份青菜什么的。&lt;/p&gt;&#xD;
&lt;p&gt;我又低头吃饭，一会儿他们的快餐上来了，因为他们坐下了，又坐在我的斜对角，所以听得清楚了一些。快餐只上了一份，小伙子在吃，他吃的狼吞虎咽，显然饿极了。妈妈坐在旁边，指指那个青菜，显然对额外添加的青菜不满意，在那里咕咕叨叨，小伙子没理睬他，只顾吃饭。&lt;/p&gt;&#xD;
&lt;p&gt;那点饭显然不够小伙子吃，我估计也就20秒吧，饭快没有了，小伙子到：老板加饭。老板立即盛饭去了，他的妈妈四周望了望，小心翼翼的问道：老板，你们这里米饭多少钱一碗。老板大声道：不要钱。她似乎不相信自己的耳朵，坐在旁边的民工又提醒道：加米饭不要钱。米饭上来了，老板很爽快，盛了满满一盘子，正准备倒在小伙子的盘子里呢，小伙子立马叫道：不用那么多，不用那么多。于是就只放了大半。&lt;/p&gt;&#xD;
&lt;p&gt;老板走后，妈妈又唠叨起来，但压低了声音，不要钱你干嘛不多加点。儿子还是没有理睬她，只顾着吃饭。她坐在儿子旁边，开始东张西望，过了一会儿，她又问老板：单独买米饭多少钱啊，老板说：两块。又过了好半会儿，她对老板说，那给我来分白米饭。当然，她没有忘记对坐在旁边的民工师傅说：&lt;strong&gt;我喜欢吃白米饭&lt;/strong&gt;。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/tansm/aggbug/2302421.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/tansm/archive/2011/12/26/2302421.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/tansm/archive/2011/12/25/2301081.html</id><title type="text">IT沙龙 共同成长计划</title><summary type="text">继续上次说的IT沙龙，首先，我打算把名字由：助您成长 改为 共同成长。助您成长有那么一点点恩惠别人的意思，虽然的确是，但我相信讲师自己也会成长，听众成长之后，也反过来帮助大家，那就是共同成长了。首先，是网站的建设，我挑选了一下，觉得Codeplex上的Orchard项目不错，他是一个C#编写的CMS开源项目。总体设计思想不错，项目也比较活跃。网站的主菜单包括：主页：显示最新的活动安排、博文列表、宣传性链接；活动：罗列所有的活动列表；博客：罗列所有的博文，这些博文是所有会员写的博文。会员：罗列了所有会员，以及他们的信息，包括所有参加的活动，积分等。财务：接受会员的捐款、捐物，在这里罗列，以及费用</summary><published>2011-12-25T08:50:00Z</published><updated>2011-12-25T08:50:00Z</updated><author><name>编写人生</name><uri>http://www.cnblogs.com/tansm/</uri></author><link rel="alternate" href="http://www.cnblogs.com/tansm/archive/2011/12/25/2301081.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/tansm/archive/2011/12/25/2301081.html"/><content type="html">&lt;p&gt;继续上次说的IT沙龙，首先，我打算把名字由：助您成长 改为 共同成长。助您成长有那么一点点恩惠别人的意思，虽然的确是，但我相信讲师自己也会成长，听众成长之后，也反过来帮助大家，那就是共同成长了。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;首先，是网站的建设，我挑选了一下，觉得Codeplex上的&lt;a href="http://www.orchardproject.net/" target="_blank"&gt;Orchard&lt;/a&gt;项目不错，他是一个C#编写的&lt;a href="http://orchard.codeplex.com/" target="_blank"&gt;CMS开源项目&lt;/a&gt;。总体设计思想不错，项目也比较活跃。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;网站的主菜单包括：&lt;/p&gt;&#xD;
&lt;p&gt;主页：显示最新的活动安排、博文列表、宣传性链接；&lt;/p&gt;&#xD;
&lt;p&gt;活动：罗列所有的活动列表；&lt;/p&gt;&#xD;
&lt;p&gt;博客：罗列所有的博文，这些博文是所有会员写的博文。&lt;/p&gt;&#xD;
&lt;p&gt;会员：罗列了所有会员，以及他们的信息，包括所有参加的活动，积分等。&lt;/p&gt;&#xD;
&lt;p&gt;财务：接受会员的捐款、捐物，在这里罗列，以及费用的情况。&lt;/p&gt;&#xD;
&lt;p&gt;关于：介绍主要的核心成员和讲师。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/tansm/aggbug/2301081.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/tansm/archive/2011/12/25/2301081.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/tansm/archive/2011/12/24/2300313.html</id><title type="text">快餐店的流程优化思考</title><summary type="text">今天中午去一家饺子馆吃饺子,生意很好,是几个小年轻开的,可惜流程没有搞好,好几个人忙不过来,乱糟糟的,所以我就在想这种快餐店如何流程优化。如果进入店后，进入自助点餐台，点餐台其实就是一个放了平板电脑的台子。好处：减少了前台的空间，也没有了前台的服务人员。平板的画面中使用视频告诉客户：请拿一个旁边的餐桌号牌。然后在平板旁边的扫描枪扫一下。（如果用RFID或IC卡之类的，体验最好了）。当然，因为我找不到合适的照片，实际的餐桌号牌应该包含大大的条码或者RFID之类的。客户拿到后，在平板旁边扫描一下，这样我们就能够确定这个客户，后面的流程要靠这个确定客户。现在，开始点餐了，当客户扫描了餐桌号牌后，屏幕</summary><published>2011-12-24T06:46:00Z</published><updated>2011-12-24T06:46:00Z</updated><author><name>编写人生</name><uri>http://www.cnblogs.com/tansm/</uri></author><link rel="alternate" href="http://www.cnblogs.com/tansm/archive/2011/12/24/2300313.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/tansm/archive/2011/12/24/2300313.html"/><content type="html">&lt;p&gt;今天中午去一家饺子馆吃饺子,生意很好,是几个小年轻开的,可惜流程没有搞好,好几个人忙不过来,乱糟糟的,所以我就在想这种快餐店如何流程优化。&lt;/p&gt;&#xD;
&lt;p&gt;如果进入店后，进入自助点餐台，点餐台其实就是一个放了平板电脑的台子。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;好处：减少了前台的空间，也没有了前台的服务人员。&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;平板的画面中使用视频告诉客户：请拿一个旁边的餐桌号牌。然后在平板旁边的扫描枪扫一下。&lt;/p&gt;&#xD;
&lt;p&gt;（如果用RFID或IC卡之类的，体验最好了）。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/4491/2011122413511973.png" alt="" width="120" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;当然，因为我找不到合适的照片，实际的餐桌号牌应该包含大大的条码或者RFID之类的。&lt;/p&gt;&#xD;
&lt;p&gt;客户拿到后，在平板旁边扫描一下，这样我们就能够确定这个客户，后面的流程要靠这个确定客户。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;现在，开始点餐了，当客户扫描了餐桌号牌后，屏幕切换到点餐界面，如果是已经点餐的，将显示已经点餐的数据。&lt;/p&gt;&#xD;
&lt;p&gt;点餐界面就自由发挥了，一般来说大大的图标或图片是最好的形式。&lt;/p&gt;&#xD;
&lt;p&gt;在明显的位置包含&amp;ldquo;下单&amp;rdquo;按钮，当点击下单后，画面出现提示：总计多少钱，如果又优惠券也可以扫描一下。&lt;/p&gt;&#xD;
&lt;p&gt;最关键：还需要有一个，您有多少零钱的提示。由于后续的服务员才能一次完成找零工作。&lt;/p&gt;&#xD;
&lt;p&gt;点击：完成，拿着餐桌号牌，找个餐桌等等吧。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;好处：完全不需要前台服务员，减少付款时的时间。&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;厨房在接收到指定的订单后，就可以制作了。&lt;/p&gt;&#xD;
&lt;p&gt;厨师的现成的食物或做好食物后，服务员在后台的触摸屏上点击将要送出的食物（他的屏幕上是未出的食物），大概是这个样子的：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/4491/2011122414372647.png" alt="" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;画面中，底背景色表示客户已经等待的时间。&lt;/p&gt;&#xD;
&lt;p&gt;那个抹去的标志表示已经完成。辣椒图标表示客户需要的特殊口味，服务员将点击可以送出的食物，最后点击&amp;rdquo;送出按钮&amp;ldquo;。&lt;/p&gt;&#xD;
&lt;p&gt;这时，如果有送出的食物是此餐台第一次送出，屏幕将提示准备的零钱。（就是通过客户之前输入的信息）。并且打印对应的小票。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;服务员按顺序将食物送出到对应的餐桌，如果某餐桌首次送餐，将会要求客户付款并支付零钱给客户。递交小票并在已经送到的食物划勾。&lt;/p&gt;&#xD;
&lt;p&gt;如果此餐桌已经全部上菜完毕，还要做一个动作，将餐牌收回，并提示客户用完餐后将托盘和碗筷放到哪个位置。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;餐桌号牌收回扫描给电脑，并存入客户的付款。&lt;/p&gt;&#xD;
&lt;p&gt;基本上，餐厅就只剩下打扫地面和餐桌的服务员了。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/tansm/aggbug/2300313.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/tansm/archive/2011/12/24/2300313.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/tansm/archive/2011/12/24/2300126.html</id><title type="text">宅男网上购买大家电对各大网站的总结</title><summary type="text">家里要买一些家电，我又正好在家闲着，那这个光荣的任务当然是我来做，但我可不愿意到国美苏宁这样的商场去逛，我是技术指标狂，到那种地方服务员还没我懂，关键是还价了半天还没有网上的便宜，费那个力气干啥。我需要购买的商品如下：基于价格与指标的平衡，我目标是这些商品，他们都是非常节能，质量又不错的产品。（注：LG的洗衣机也可以选择WD-T12235D，是7公斤的，仅仅贵300多）。下面是我购买这些商品时的体验。其他的淘宝商城、亚马逊、新蛋等，毕竟不是做大家电的，完全不在一个层次就不评价了。www.360buy.com体验★★★★★分类准确细致，参数详细可查询。易用性好，注重细节价格★★★★价格相对线下还</summary><published>2011-12-24T02:44:00Z</published><updated>2011-12-24T02:44:00Z</updated><author><name>编写人生</name><uri>http://www.cnblogs.com/tansm/</uri></author><link rel="alternate" href="http://www.cnblogs.com/tansm/archive/2011/12/24/2300126.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/tansm/archive/2011/12/24/2300126.html"/><content type="html">&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;家里要买一些家电，我又正好在家闲着，那这个光荣的任务当然是我来做，但我可不愿意到国美苏宁这样的商场去逛，我是技术指标狂，到那种地方服务员还没我懂，关键是还价了半天还没有网上的便宜，费那个力气干啥。&lt;/p&gt;&#xD;
&lt;p&gt;我需要购买的商品如下：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/4491/2011122409091250.png" alt="" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;基于价格与指标的平衡，我目标是这些商品，他们都是非常节能，质量又不错的产品。（注：LG的洗衣机也可以选择WD-T12235D，是7公斤的，仅仅贵300多）。&lt;/p&gt;&#xD;
&lt;p&gt;下面是我购买这些商品时的体验。其他的淘宝商城、亚马逊、新蛋等，毕竟不是做大家电的，完全不在一个层次就不评价了。&lt;/p&gt;&#xD;
&lt;table border="0" align="left"&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td colspan="3"&gt;&#xD;
&lt;p&gt;&lt;a href="http://www.360buy.com/" target="_blank"&gt;www.360buy.com&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/4491/2011122409425372.png" alt="" /&gt;&lt;/p&gt;&#xD;
&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td&gt;体验&lt;/td&gt;&#xD;
&lt;td&gt;★&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;/td&gt;&#xD;
&lt;td&gt;分类准确细致，参数详细可查询。易用性好，注重细节&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td&gt;价格&lt;/td&gt;&#xD;
&lt;td&gt;&amp;nbsp;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;/td&gt;&#xD;
&lt;td&gt;&#xD;
&lt;p&gt;价格相对线下还是很有优势，但是在库巴和苏宁面前，还是要贵个几百，但是优惠活动多。&amp;nbsp;&lt;/p&gt;&#xD;
&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td&gt;货源&lt;/td&gt;&#xD;
&lt;td&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&#xD;
&lt;td&gt;总体来说，货物种类非常多，也基本都有货，但真正畅销的往往脱销没货。&amp;nbsp;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td&gt;综合评价&lt;/td&gt;&#xD;
&lt;td&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&#xD;
&lt;td&gt;作为最老牌的网上电器购物，仍然是群龙之首，但价格没有苏宁给力了。&amp;nbsp;&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;table border="0" align="left"&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td colspan="3"&gt;&#xD;
&lt;p&gt;&lt;a href="http://www.coo8.com/"&gt;http://www.coo8.com/&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/4491/2011122409482744.png" alt="" /&gt;&lt;/p&gt;&#xD;
&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td&gt;体验&lt;/td&gt;&#xD;
&lt;td&gt;★&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;/td&gt;&#xD;
&lt;td&gt;这呀的太卑鄙，完全照抄京东的设计，但毕竟是仿制品，细节欠火候。&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td&gt;价格&lt;/td&gt;&#xD;
&lt;td&gt;&amp;nbsp;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;span&gt;★&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;&#xD;
&lt;td&gt;&#xD;
&lt;p&gt;价格简直太给力了， 我上面的图就是在库巴的订单。&lt;/p&gt;&#xD;
&lt;p&gt;如果说网上购物比线下可能便宜一千，那么库巴你仔细找，很可能比其他网站还要再便宜几百。&lt;/p&gt;&#xD;
&lt;p&gt;他给力的价格促销好像非常短，在我欣喜的下订单后支付出了问题，第二天再次购买时已经两个商品涨价了。&lt;/p&gt;&#xD;
&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td&gt;货源&lt;/td&gt;&#xD;
&lt;td&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;span&gt;★&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&#xD;
&lt;td&gt;从网站的提示看，货源种类比较多的，货源也充足。很多抢手货他都提示有，但具体有没有没试过。&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td&gt;综合评价&lt;/td&gt;&#xD;
&lt;td&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;span&gt;★&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&#xD;
&lt;td&gt;&#xD;
&lt;p&gt;价格太给力了，很多大城市市区还支持货到付款。&lt;/p&gt;&#xD;
&lt;p&gt;国美2010年收购了他，应该不错。&lt;/p&gt;&#xD;
&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;table border="0" align="left"&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td colspan="3"&gt;&#xD;
&lt;p&gt;&lt;a href="http://www.suning.com/"&gt;http://www.suning.com/&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/4491/2011122410174842.png" alt="" /&gt;&lt;/p&gt;&#xD;
&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td&gt;体验&lt;/td&gt;&#xD;
&lt;td&gt;★&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;/td&gt;&#xD;
&lt;td&gt;&#xD;
&lt;p&gt;界面中等，但还是新手，比如将洗衣机先按照波轮和滚筒，这是一个低级错误。&lt;/p&gt;&#xD;
&lt;p&gt;如果客户没钱只想买波轮，他就会直接进入波轮，然后看见有特价就买了，这很可能让他错失滚筒的另外一个特价。&lt;/p&gt;&#xD;
&lt;p&gt;这样的问题还很多，包括没有专门的参数对比。&lt;/p&gt;&#xD;
&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td&gt;价格&lt;/td&gt;&#xD;
&lt;td&gt;&amp;nbsp;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;/td&gt;&#xD;
&lt;td&gt;&#xD;
&lt;p&gt;可能是不想做千年老二吧，这个网上的价格很给力，比库巴贵一点，但比其他的都便宜很多。&lt;/p&gt;&#xD;
&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td&gt;货源&lt;/td&gt;&#xD;
&lt;td&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&#xD;
&lt;td&gt;货源种类比较多的，货源还行吧，至少比京东的货源充足。&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td&gt;综合评价&lt;/td&gt;&#xD;
&lt;td&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&#xD;
&lt;td&gt;&#xD;
&lt;p&gt;价格给力，又是苏宁的正太子，支持还行。&lt;/p&gt;&#xD;
&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;table border="0" align="left"&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td colspan="3"&gt;&#xD;
&lt;p&gt;&lt;a href="http://www.gome.com.cn/"&gt;http://www.gome.com.cn/&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/4491/2011122410364485.png" alt="" /&gt;&lt;/p&gt;&#xD;
&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td&gt;体验&lt;/td&gt;&#xD;
&lt;td&gt;★&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;/td&gt;&#xD;
&lt;td&gt;&#xD;
&lt;p&gt;界面中等，但还是新手，没有专门的参数对比。&lt;/p&gt;&#xD;
&lt;p&gt;出现几次JSP错误，直接把调用堆栈显示出来，圣诞节白天竟然&amp;ldquo;系统升级中&amp;rdquo;。&lt;/p&gt;&#xD;
&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td&gt;价格&lt;/td&gt;&#xD;
&lt;td&gt;&amp;nbsp;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;/td&gt;&#xD;
&lt;td&gt;&#xD;
&lt;p&gt;国美即想搞网上商城，又怕价格阻碍了线下，两边不讨好，所以价格高企。&lt;/p&gt;&#xD;
&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td&gt;货源&lt;/td&gt;&#xD;
&lt;td&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;span&gt;★&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;/td&gt;&#xD;
&lt;td&gt;货源有比国美的多的吗。&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td&gt;综合评价&lt;/td&gt;&#xD;
&lt;td&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;span&gt;★&lt;/span&gt;&lt;/td&gt;&#xD;
&lt;td&gt;&#xD;
&lt;p&gt;一般一般，实在不推荐，只能期望哪次突然搞大活动。&lt;/p&gt;&#xD;
&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&lt;img src="http://www.cnblogs.com/tansm/aggbug/2300126.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/tansm/archive/2011/12/24/2300126.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/tansm/archive/2011/12/20/2295156.html</id><title type="text">助您成长计划</title><summary type="text">想法随着自己年龄的增大，生活也逐渐安定下来，越来越觉得很多的事情可以去做，回想过去，自己不是科班出生，所以需要自己慢慢的学习，幸运的是，我身边有很多热情的同事，他们给了我很多的帮助。现在，我看见一些和我一样从农村走出来的程序员朋友，他们都很年轻，由于缺乏实战经验，拿着微薄的工资却仍然需要加班加点，看不到美好的希望。我虽然没有什么钱，但我算是肚子有点墨水，所以想出一个主意，就是通过一些形式帮助他们快速的成长，当然，我希望这些成长不仅仅是技术上，还包括思想、人格等各个方面。比较现实点的形式，是使用沙龙这样的方式，原因如下：1、几乎不占用什么资金，如果需要很多资金，我估计不能一直坚持，沙龙比较简单，</summary><published>2011-12-20T13:24:00Z</published><updated>2011-12-20T13:24:00Z</updated><author><name>编写人生</name><uri>http://www.cnblogs.com/tansm/</uri></author><link rel="alternate" href="http://www.cnblogs.com/tansm/archive/2011/12/20/2295156.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/tansm/archive/2011/12/20/2295156.html"/><content type="html">&lt;p&gt;&lt;strong&gt;想法&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;随着自己年龄的增大，生活也逐渐安定下来，越来越觉得很多的事情可以去做，回想过去，自己不是科班出生，所以需要自己慢慢的学习，幸运的是，我身边有很多热情的同事，他们给了我很多的帮助。&lt;br /&gt;现在，我看见一些和我一样从农村走出来的程序员朋友，他们都很年轻，由于缺乏实战经验，拿着微薄的工资却仍然需要加班加点，看不到美好的希望。我虽然没有什么钱，但我算是肚子有点墨水，所以想出一个主意，就是通过一些形式帮助他们快速的成长，当然，我希望这些成长不仅仅是技术上，还包括思想、人格等各个方面。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;比较现实点的形式，是使用沙龙这样的方式，原因如下：&lt;br /&gt;1、几乎不占用什么资金，如果需要很多资金，我估计不能一直坚持，沙龙比较简单，买点零食有个场地即可。&lt;br /&gt;2、参加的人可能参差不齐，搞讲座啥的会众口难调。沙龙形式主题随意，技术好的可以自己来讲，不好的来听。&lt;br /&gt;3、沙龙能够比较好的促进共同成长，有经验的引导新生，等他们成熟后成为新的力量。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;实施&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;具体安排上，我觉得每个月举行两次，一次小型活动，一次正式活动。安排在周二或周六比较合适。&lt;br /&gt;小型活动限制为一个主题，人数少，比较随意，正式活动一般安排2-3个讲演主题。&lt;br /&gt;另外，建立一个简单的网站，以便展示活动安排、成果以及记录会员的积分等信息。参加沙龙的所有人需要注册为会员，这样一方面可以互相交流，另外一方面也可以记录积分。&lt;br /&gt;会员在参加一次活动后会获得参与积分，但也同时扣除分享积分，如果组织活动（文职）或主持活动，就可以获得分享积分，用于归还扣除的积分。这样做主要是期望大家能一起建设。&lt;/p&gt;&#xD;
&lt;p&gt;网站上包含了会员的姓名、联系方式、专长、参加过的活动和积分，联系方式只能是会员才能看见。&lt;br /&gt;活动会设置文职的工作，活动前负责了解讲师的主题，发布到网站，购买零食和准备场地和设备，在活动期间登记参加的人员，录制讲师的视频，并在最后发布到网站。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;这是我目前大致的想法，更重要的是我希望有志同道合的一些朋友能够和我一起共同建设。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/tansm/aggbug/2295156.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/tansm/archive/2011/12/20/2295156.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/tansm/archive/2011/12/04/2275652.html</id><title type="text">WinRT比.NET快了，还是Win8比Win7快</title><summary type="text">我对WinRT的理解是，WinRT是吸收了.net设计经验，一套非托管的Win32 API替代品。对于.net程序员来说，当我们调用WINRT库时，理论上，要比调用.NET自带的库要快，是吗？我今天就自己验证一下。我的想法是使用WinRT自带的List&amp;lt;T&amp;gt;和.net Framework自带的List&amp;lt;T&amp;gt;进行比较，创建一个List&amp;lt;int&amp;gt;实例，然后添加两个实例，循环1亿次。在Windows 8 64位开发者预览版下，我创建了一个页面，然后执行下面的代码：private void ListAddTest(){ System.Diagnostics.Stop</summary><published>2011-12-04T10:44:00Z</published><updated>2011-12-04T10:44:00Z</updated><author><name>编写人生</name><uri>http://www.cnblogs.com/tansm/</uri></author><link rel="alternate" href="http://www.cnblogs.com/tansm/archive/2011/12/04/2275652.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/tansm/archive/2011/12/04/2275652.html"/><content type="html">&lt;p&gt;我对WinRT的理解是，WinRT是吸收了.net设计经验，一套非托管的Win32 API替代品。对于.net程序员来说，当我们调用WINRT库时，理论上，要比调用.NET自带的库要快，是吗？我今天就自己验证一下。&lt;/p&gt;&#xD;
&lt;p&gt;我的想法是使用WinRT自带的List&amp;lt;T&amp;gt;和.net Framework自带的List&amp;lt;T&amp;gt;进行比较，创建一个List&amp;lt;int&amp;gt;实例，然后添加两个实例，循环1亿次。&lt;/p&gt;&#xD;
&lt;p&gt;在Windows 8 64位开发者预览版下，我创建了一个页面，然后执行下面的代码：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; ListAddTest()&lt;br /&gt;{&lt;br /&gt;    System.Diagnostics.Stopwatch watch = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; System.Diagnostics.Stopwatch();&lt;br /&gt;    watch.Start();&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; i = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;; i &amp;lt; &lt;span style="color: #800080;"&gt;100000000&lt;/span&gt;; i++)&lt;br /&gt;    {&lt;br /&gt;        List&amp;lt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&amp;gt; list = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; List&amp;lt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&amp;gt;();&lt;br /&gt;        list.Add(i);&lt;br /&gt;        list.Add(i++);&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     watch.Stop();&lt;br /&gt;     lstOutput.Items.Add(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Time=&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; + watch.Elapsed.ToString());&lt;br /&gt;}&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;测试结果基本在3.1-3.2之间，比较稳定。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;然后，我重新启动，切换到本机另外一个操作系统,Windows 7 32位中文版，编写了一个控制台程序，使用.net framework 4 client profile。代码和上面一样。&lt;/p&gt;&#xD;
&lt;p&gt;测试结果基本在5.2-5.3之间，但很不稳定，偶发性的会快到4.7。&lt;/p&gt;&#xD;
&lt;p&gt;至此，我认为WinRT比.net快了，对吗？&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;我将Windows 7编译的程序重新在Windows 8环境下运行，测试结果竟然稳定在2.7-2.9秒之间。大出我意料！！&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;好吧，我犯糊涂了，&lt;/p&gt;&#xD;
&lt;p&gt;是Windows 8下，.net 运行效率提高很多？&lt;/p&gt;&#xD;
&lt;p&gt;是Windows 8下，程序自动切换到.net 4.5？是4.5比4.0快多了？&lt;/p&gt;&#xD;
&lt;p&gt;其实,WinRT下我并没有找到List&amp;lt;T&amp;gt;实现，其Windows.Runtime的DLL下，只有接口没有实现，我是在System.Collection.dll下找到的，是不是意味着我测试的实际上是.net 4.5与.net 4.0的比较？&lt;/p&gt;&#xD;
&lt;p&gt;求解？？&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;备注：&lt;/p&gt;&#xD;
&lt;p&gt;测试硬件为：Intel i3 M350 2.27GHz ，2GB 内存。&lt;/p&gt;&#xD;
&lt;p&gt;软件为：一个是Windows 7 32位中文版，一个是Windows 8 64位英文版（开发者预览版）。&lt;/p&gt;&#xD;
&lt;p&gt;编译环境：控制台程序在VS 2010 .net 4编译，WinRT程序在VS 12 .net 4.5下编译。所以编译均为Release版本，直接运行无调试。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/tansm/aggbug/2275652.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/tansm/archive/2011/12/04/2275652.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/tansm/archive/2011/11/29/2268193.html</id><title type="text">一个并发环境下的BUG分析</title><summary type="text">今天接手一个并发压力下的一个BUG，程序报：“字典中已经添加了重复的键”，出错的代码如下：lock (connectionList){ // Next we&amp;#39;ll see if there is already a connection. If not, we&amp;#39;ll create a new connection and add it // to the transaction&amp;#39;s list of connections. // This collection should only be modified by the thread where the transac</summary><published>2011-11-29T12:41:00Z</published><updated>2011-11-29T12:41:00Z</updated><author><name>编写人生</name><uri>http://www.cnblogs.com/tansm/</uri></author><link rel="alternate" href="http://www.cnblogs.com/tansm/archive/2011/11/29/2268193.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/tansm/archive/2011/11/29/2268193.html"/><content type="html">&lt;p&gt;今天接手一个并发压力下的一个BUG，程序报：&amp;ldquo;字典中已经添加了重复的键&amp;rdquo;，出错的代码如下：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #0000ff;"&gt;lock&lt;/span&gt; (connectionList)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Next we'll see if there is already a connection. If not, we'll create a new connection and add it&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; to the transaction's list of connections.&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; This collection should only be modified by the thread where the transaction scope was created&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; while the transaction scope is active.&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; However there's no documentation to confirm this, so we err on the safe side and lock.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;    &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (!connectionList.TryGetValue(db.ConnectionString, &lt;span style="color: #0000ff;"&gt;out&lt;/span&gt; connection))&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; we're betting the cost of acquiring a new finer-grained lock is less than &lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; that of opening a new connection, and besides this allows threads to work in parallel&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; dbConnection = db.GetNewOpenConnection();&lt;br /&gt;        connection = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; DatabaseConnectionWrapper(dbConnection);&lt;br /&gt;        connectionList.Add(db.ConnectionString, connection);&lt;br /&gt;    }&lt;br /&gt;    connection.AddRef();&lt;br /&gt;}&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;br /&gt;这段代码是企业库的一段代码（参见：&lt;a href="http://entlib.codeplex.com/SourceControl/changeset/view/90009#526470"&gt;http://entlib.codeplex.com/SourceControl/changeset/view/90009#526470&lt;/a&gt;）&lt;/p&gt;&#xD;
&lt;p&gt;那个Add方法出错的，我得承认，我花了很长时间想这段代码在哪种情况下会造成锁定失败呢？怎么可能有两个线程进来。你看出来了吗？&lt;/p&gt;&#xD;
&lt;p&gt;好吧，答案是，问题并不是在lock上，而是在两次调用db.ConnectionString上。&lt;/p&gt;&#xD;
&lt;p&gt;在并行环境下，外界错误的使用了静态变量共享了IDatabase实例（这个db对象），这是主因。但是在这段代码中，判断字典是否存在某个key时使用了db.ConnectionString获取，但很不幸，在并行环境下，这个静态共享的db对象被其他线程替换成了另外一个连接字符串，于是在Add时，使用了另外一个字符串作为key,又不幸的是，字典中已经存在了此键。&lt;/p&gt;&#xD;
&lt;p&gt;修改的方法当然是先取消外部静态共享IDatabase对象。但这个地方也不妥，严密的代码应该是：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; key = db.ConnectionString;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;lock&lt;/span&gt; (connectionList)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; 使用同一个Key值，而不是两次访问属性，可能不一致。&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;    &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (!connectionList.TryGetValue(key, &lt;span style="color: #0000ff;"&gt;out&lt;/span&gt; connection))&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; dbConnection = db.GetNewOpenConnection();&lt;br /&gt;        connection = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; DatabaseConnectionWrapper(dbConnection);&lt;br /&gt;        connectionList.Add(key, connection);&lt;br /&gt;    }&lt;br /&gt;    connection.AddRef();&lt;br /&gt;}&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;br /&gt;总结：&lt;/p&gt;&#xD;
&lt;p&gt;1、慎用静态变量，他经常是内存泄露、并发冲突的元凶；&lt;/p&gt;&#xD;
&lt;p&gt;2、注意属性可能在并发下中途被修改，可以使用字段备份一份。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/tansm/aggbug/2268193.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/tansm/archive/2011/11/29/2268193.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/tansm/archive/2011/11/06/2237193.html</id><title type="text">简单关系型结构的依赖运算模型</title><summary type="text">简介：本文阐述了在数据型应用程序中，对各种运算的关系的分析，简化这些应用程序的开发以及提高性能的方法。概述在数据型的应用程序中，我们经常面对关系型的数据结构，即经典的表、字段和关系的结构。在这种关系型结构下，我们需要在某个字段或关系的数据发生改变后，作出相应的反应。这些反应可能是数据处理的，例如当单价发生改变后，需要对金额进行重算，金额=单价*数量。也有可能这种反应是界面上的，例如未录入物料时，单价和数量均不能录入（Enabled=false)，但是，一旦录入后，界面作出反应，其单价和数量就可以录入了。我们称这种反应为计算单元。我们注意到，这些计算单元，依赖某个字段或关系的数据更改，例如计算金</summary><published>2011-11-06T10:21:00Z</published><updated>2011-11-06T10:21:00Z</updated><author><name>编写人生</name><uri>http://www.cnblogs.com/tansm/</uri></author><link rel="alternate" href="http://www.cnblogs.com/tansm/archive/2011/11/06/2237193.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/tansm/archive/2011/11/06/2237193.html"/><content type="html">&lt;div&gt;&#xD;
&lt;p&gt;简介：本文阐述了在数据型应用程序中，对各种运算的关系的分析，简化这些应用程序的开发以及提高性能的方法。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&amp;nbsp;概述&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;在数据型的应用程序中，我们经常面对关系型的数据结构，即经典的表、字段和关系的结构。在这种关系型结构下，我们需要在某个字段或关系的数据发生改变后，作出相应的反应。&lt;/p&gt;&#xD;
&lt;p&gt;这些反应可能是数据处理的，例如当单价发生改变后，需要对金额进行重算，金额=单价*数量。也有可能这种反应是界面上的，例如未录入物料时，单价和数量均不能录入（Enabled=false)，但是，一旦录入后，界面作出反应，其单价和数量就可以录入了。我们称这种反应为计算单元。&lt;/p&gt;&#xD;
&lt;p&gt;我们注意到，这些计算单元，依赖某个字段或关系的数据更改，例如计算金额的计算单元，依赖单价或数量字段更改，而计算单价和数量是否有效的计算单元，依赖物料字段。我们也可以理解为，计算单元依赖的数据未发生改变时，无需重新执行这些计算单元。&lt;/p&gt;&#xD;
&lt;p&gt;我们理解这个&amp;ldquo;简单关系型结构的依赖运算模型&amp;rdquo;就是：在数据装载或发生改变后，智能的执行对应的计算单元的一套模型。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&amp;nbsp;数据结构&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;既然我们在这个标题中已经限定了其是：关系型结构，那么一切的基础就是关系型的数据结构。在这个模型中，我们需要定义表、字段和关系。&lt;/p&gt;&#xD;
&lt;p&gt;表包含很多的字段，这些字段都是简单的数据结构，不能再拆分。在当前模型中，我们只能做到有且只有一个根表，所有的表都是此根表的子表或间接子表，以后将取消此限制。&lt;/p&gt;&#xD;
&lt;p&gt;关系描述了表与表之间的关系，一端是父表，一端是子表，在目前的模型中，我们只能支持固定的关联关系，那些动态的关联关系还未考虑。多对多的关系也还需要全面评估。&lt;/p&gt;&#xD;
&lt;p&gt;在实际的应用中，这个数据结构最佳实践应该是能够支持动态的数据结构，例如在某些界面中，基于性能的考虑，可能希望在用户点击某个页签时，才加载某个关系，关于此问题我们在其他的文章再讨论。&lt;/p&gt;&#xD;
&lt;p&gt;还需要注意的是，目前的应用程序，很多都是使用面向对象的数据结构，我们今天还使用关系型结构，是不是老套了。事实上，我一开始就是基于面向对象的数据结构设计此模型，但随着经验的增加，我发现，复杂的对象只会把事情越搞越复杂，而对象的结构最终都可以映射到关系型结构的模型上。因此，我将对象的结构映射到关系型结构上，从而使用关系型的结构处理对象的复杂情况。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;计算单元&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;有了数据结构，我们就可以基于此定义计算单元，每个计算单元都包含一个批量执行的方法，在需要的时候，引擎负责调用此方法以便完成计算。&lt;/p&gt;&#xD;
&lt;p&gt;为简化具体的计算单元编写，要求计算单元必须提供一个TargetTable属性，他指向一个表，引擎执行计算单元时，将永远提供此表的数据。&lt;/p&gt;&#xD;
&lt;p&gt;假设在销售订单中，单据根表包含一个折扣字段，明细上包含金额和折后金额，当金额或折扣字段发生改变后，我们期望能够执行这个计算单元，以便更新折后金额。在传统的编程模型中，当折扣发生改变后，我们需要自己编码获取所有的明细，以便更新全部明细，而用户仅更改了某行明细的金额时，我们又需要仅计算此行的折后金额。&lt;/p&gt;&#xD;
&lt;p&gt;TargetTable属性就是向引擎声明：不论更改的字段在哪里，请帮我智能的转换成此Table上的数据。这样编写计算单元的程序员就很简单了，循环计算就是了。在这个例子中，当折扣发生改变时，引擎将提供所有明细给计算单元，而某行的金额发生改变后，引擎将提供仅包含发生行一条记录的集合。&lt;/p&gt;&#xD;
&lt;p&gt;在这里例子中，你也许注意到，此计算单元仅希望折扣或金额字段发生改变后才执行，其它字段改变就不要让我再执行了。我们称这种特性为依赖字段，此计算单元的DependencyFields为折扣和金额字段。&lt;/p&gt;&#xD;
&lt;p&gt;但你需要注意的是，计算单元不仅可以依赖字段，还可以依赖关系，一个典型的场景是：Items.Count&amp;nbsp;公式的计算，依赖关系Items的变更，当Items关系有新增、删除或重置时，需要重算此公式。当然，为统一概念，我们认为关系也是一个字段，称为集合字段，就像面向对象中一个集合属性一样。&lt;/p&gt;&#xD;
&lt;p&gt;与DependencyFields相对应的，当计算单元计算完毕后，可能会影响某些字段和关系，在这个例子中，此计算单元完成计算后将更新&amp;ldquo;折后金额&amp;rdquo;字段，引擎需要这样的信息，以便将依赖&amp;ldquo;折后金额&amp;rdquo;字段的计算单元放在此计算单元之后。我们称此特性为ApplyToFields。&lt;/p&gt;&#xD;
&lt;p&gt;与阐述DependencyFields一样，ApplyToFields也可以更改影响关系。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;工作区及引擎&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;所有的数据结构定义及计算单元都被存储在一起，即一个工作区，引擎是工作区平行的部分，他负责调度这些计算单元。&lt;/p&gt;&#xD;
&lt;p&gt;在一个工作区中，会包含很多的计算单元，此模型的引擎在某些字段或关系数据发生改变后，分析哪些计算单元需要执行、执行的先后顺序，以及避免在批量处理时的重复计算。&lt;/p&gt;&#xD;
&lt;p&gt;引擎在初始化时，分析每个计算单元的DependencyFields属性，并建立数据结构以便在某个字段（或关系）发生更改后快速的找到其对应的计算单元。另外，还分析计算单元的ApplyToFields属性，建立数据结构以便快速的决定计算单元的执行顺序。&lt;/p&gt;&#xD;
&lt;p&gt;由于各种实体的更改通知机制不同，所以引擎本身并不包含对实体更改的追踪部分，而是让外界手动的通知引擎。可以建立一个适配器跟踪实体的更改，然后通知引擎。&lt;/p&gt;&#xD;
&lt;p&gt;更改通知包括字段的DataChanged和关系的CollectionChanged俩种，字段DataChanged比较容易理解。关系的CollectonChanged包括三种更改方式：插入、删除和重置。&lt;/p&gt;&#xD;
&lt;p&gt;引擎在收到更改通知后，将启动一个事物（事物处理由外界管理），以便能够在后续的计算发生错误后回滚现场。&lt;/p&gt;&#xD;
&lt;p&gt;根据此通知信息找到所有依赖更改字段的计算单元。找到的计算单元可能有重复，可以很容易的先去除重复的部分。然后，引擎再根据之前的数据结构很容易再推算出执行的先后顺序。&lt;/p&gt;&#xD;
&lt;p&gt;由于计算单元有TargetTable属性，所以引擎一种重要的工作就是分析出对应的目标数据。更改的字段所在表称为EventSouceTable，由于EventSourceTable与TargetTable存在某种联系，因此，可以通过EventSourceTable的数据推导出TargetTable的数据，这种运算很像执行一个SQL查询，例如：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #0000ff;"&gt;Select&lt;/span&gt; TargetField1 &lt;span style="color: #0000ff;"&gt;From&lt;/span&gt; TagetTable &lt;span style="color: #808080;"&gt;Left&lt;/span&gt; &lt;span style="color: #808080;"&gt;Join&lt;/span&gt; EventSourceTable &lt;span style="color: #0000ff;"&gt;On&lt;/span&gt; XX&lt;span style="color: #808080;"&gt;=&lt;/span&gt;YY &lt;span style="color: #0000ff;"&gt;Where&lt;/span&gt; EventField &lt;span style="color: #808080;"&gt;=&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;01&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;'&lt;/span&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;此算法有些复杂，我们将在另外的文章讨论此算法。&lt;/p&gt;&#xD;
&lt;p&gt;在CollectionChanged中，有一个叫&amp;ldquo;插入&amp;rdquo;的事件类型，这个过程很像我们的单据的新增或者新增某行明细，我们通常会在此过程中初始化一些字段的默认值。&lt;/p&gt;&#xD;
&lt;p&gt;当我们获取了需要执行的计算单元、先后顺序，以及各个计算单元对应的数据，我们就可以调用它们了。最后提交事务。&lt;/p&gt;&#xD;
&lt;p&gt;在执行计算单元时，某些计算单元不会影响其它的字段，即AppToFields为空，这种计算单元都可以最后执行，甚至异步执行。例如界面样式的计算、校验等。&lt;/p&gt;&#xD;
&lt;p&gt;另外一种特殊的通知是装载初始化通知，他发生在初始化数据或切换数据阶段，你可以理解为执行所有的计算单元，但事实上，计算单元还有一个属性指示是否在初始化时执行，大多数的计算单元此属性为false，因为当重新加载一个单据时，你并不希望重新再计算一遍折后金额，因为它们已经计算过了。但是那一定希望重新计算某个控件的Enabled值，因为数据已经切换了，锁定性也需要重新计算了。&lt;/p&gt;&#xD;
&lt;p&gt;引擎另外一个非常重要的特性是批量处理，Excel导入、剪贴板的粘贴、单据转换、邮件导入都是批量处理的典型应用。我认为，我们应该将所有的输入统一在一个模型上，看起来是一个&amp;ldquo;神键手&amp;rdquo;快速的录入数据，这样可以大大减少开发的工作量。&lt;/p&gt;&#xD;
&lt;p&gt;批量处理的重要点在于排除重复的执行，这可以通过分析最终的计算单元和对应的目标数据来完成。另外一个重点是，需要考虑数据录入的先后顺序，例如在销售订单中，必须先录入客户，再录入商品，因为商品要根据客户来决定他的销售策略。&lt;/p&gt;&#xD;
&lt;p&gt;此模型是一个复杂的项目，本文仅阐述其基本的组成及执行原理，更多的知识我们在后续的文章中介绍。&lt;/p&gt;&#xD;
&lt;/div&gt;&lt;img src="http://www.cnblogs.com/tansm/aggbug/2237193.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/tansm/archive/2011/11/06/2237193.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/tansm/archive/2011/10/28/2228152.html</id><title type="text">新产品开发后期的主要技术工作：质量、性能、效率和推广</title><summary type="text">新产品开发的后期以及发版后的一段时间内，很多的工作要做，作为技术人员，我的观点是，重点技术工作应落实到质量、性能、效率和推广。质量对于一个新产品来说，质量真的是比任何事情都重要了，一个动不动就死机的手机，其它方面再好估计你也不会用。第一个版本一旦出现质量差的影响，一般很难再翻身了，即所谓的第一印象。要控制好质量，最好的方法我认为就是大量的单元测试，在产品开发后期，平台接口相对稳定了，不像早期的时候，接口一改，大量的单元测试要重写。在后期，最怕的是修一个BUG又制造了一堆的BUG，单元测试是最好的工具。顺便提一句，所有的单元测试必须保持全部通过，注意是全部通过，否则单元测试将毫无用处，因为当你改</summary><published>2011-10-28T13:35:00Z</published><updated>2011-10-28T13:35:00Z</updated><author><name>编写人生</name><uri>http://www.cnblogs.com/tansm/</uri></author><link rel="alternate" href="http://www.cnblogs.com/tansm/archive/2011/10/28/2228152.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/tansm/archive/2011/10/28/2228152.html"/><content type="html">&lt;div &gt;&#xD;
&lt;p &gt;新产品开发的后期以及发版后的一段时间内，很多的工作要做，作为技术人员，我的观点是，重点技术工作应落实到质量、性能、效率和推广。&lt;/p&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li &gt;质量&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;p &gt;对于一个新产品来说，质量真的是比任何事情都重要了，一个动不动就死机的手机，其它方面再好估计你也不会用。第一个版本一旦出现质量差的影响，一般很难再翻身了，即所谓的第一印象。&lt;/p&gt;&#xD;
&lt;p &gt;要控制好质量，最好的方法我认为就是大量的单元测试，在产品开发后期，平台接口相对稳定了，不像早期的时候，接口一改，大量的单元测试要重写。在后期，最怕的是修一个&lt;span style="font-family: Verdana;"&gt;BUG&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;又制造了一堆的&lt;/span&gt;&lt;span style="font-family: Verdana;"&gt;BUG&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，单元测试是最好的工具。顺便提一句，所有的单元测试必须保持全部通过，注意是全部通过，否则单元测试将毫无用处，因为当你改动了一个功能后，你很难知道未通过的测试用例是你造成的还是原先就不能通过。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li &gt;性能&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;p &gt;质量是第一步，第二步就是性能，这个教训，在&lt;span style="font-family: 'Times New Roman';"&gt;Windows&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;上是最好的佐证了。你看，微软这不&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;Win8&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;强调很低的配置也可以跑的很快吗？在没有选择的情况下，大家也就忍了，有选择的时候你客户跑的有多快啊，哈哈。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;关于性能，我认为不要走火入魔，一个买十几万的产品，要搞千万级产品的负载是不妥的，性能优化也是要成本的。再比如，已经优化某个指令在&lt;span style="font-family: 'Times New Roman';"&gt;100&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;毫秒内完成，就没有必要要花很大的成本降低到&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;10&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;毫秒，客户能区分&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;10&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;秒比&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;1&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;秒快，但无法区分&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;10&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;毫秒比&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;100&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;毫秒快。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;我们知道，底层平台的一个优化，会让上千的上层应用加快。但你也要记得，底层平台好不容易减少的几个毫秒，业务代码可能一个循环&lt;span style="font-family: 'Times New Roman';"&gt;SQL&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;就把这个应用搞的糟糕，因此，在调优底层后，代码检查业务代码也很重要。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li &gt;效率&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;p &gt;在新产品的开发过程中，我们知道工具非常重要，可现实是，除非非常重要且相对简单的工具，往往被&lt;span style="font-family: 'Times New Roman';"&gt;&amp;ldquo;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;更重要&lt;/span&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&amp;rdquo;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的需求所排队的后面。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;在交付新产品后，应该对过去的开发进行总结，访问一线的开发人员，找到影响开发效率的点。例如在我们的开发中：&lt;/p&gt;&#xD;
&lt;p &gt;&amp;mdash;&amp;nbsp;要加载太多的工程文件，机器运行缓慢；&lt;/p&gt;&#xD;
&lt;p &gt;&amp;mdash;&amp;nbsp;附加方式的调试造成&lt;span style="font-family: 'Times New Roman';"&gt;VS&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;不能实现&amp;ldquo;编辑即运行&amp;rdquo;，每次发现错误都要停止调试；&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&amp;mdash;&amp;nbsp;配置的修改不能即时应用，要重新启动产品；&lt;/p&gt;&#xD;
&lt;p &gt;&amp;mdash;&amp;nbsp;不能在运行时，使用即时脚本查看运行的变量值，运行日志；&lt;/p&gt;&#xD;
&lt;p &gt;&amp;mdash;&amp;nbsp;造数据，要花很多的时间&lt;/p&gt;&#xD;
&lt;p &gt;这些点点滴滴的地方，你会发现一天的时间中，你只有很少的时间花在代码的编写上，大部分是在调试。&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li &gt;推广&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;p &gt;我这里指的推广，指规范的开发方法在开发组的推广。在产品形成初期，大家也都是在摸着石头过河，代码写的是五花八门。现在，底层也稳定了，该经历的也经历了，有了这些丰富的经验，就需要总结各种应用其开发的模式形成文档和范例，这样，在产品功能的后续开发中才能规范和快速。&lt;/p&gt;&#xD;
&lt;p &gt;我认为可以建立诸如&lt;span style="font-family: 'Times New Roman';"&gt;MSDN&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;这样的网站，包含文档库、范例、教程视频和论坛。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;/div&gt;&lt;img src="http://www.cnblogs.com/tansm/aggbug/2228152.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/tansm/archive/2011/10/28/2228152.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/tansm/archive/2011/10/17/2215846.html</id><title type="text">简化策略模型的代码</title><summary type="text">在我们编写代码时，经常遇到一次策略模式（俺不会背那个啥设计模式，暂时叫他策略模式吧），例如，在反序列化时，已知一个名称和命名空间，获取其对应的类型，使用下面的策略：尝试从绑定期中获取，如果不成功，尝试从基类获取；如果还不成功，尝试播发事件获取。看起来，一个个尝试，如果不成功，下一个。代码是这个样子的。 private IEntityType BindToType(XElement element,IEntityType baseType, out IEnumerable&amp;lt;DcxmlBinder.CustomAttribute&amp;gt; attributes) { ...</summary><published>2011-10-17T14:03:00Z</published><updated>2011-10-17T14:03:00Z</updated><author><name>编写人生</name><uri>http://www.cnblogs.com/tansm/</uri></author><link rel="alternate" href="http://www.cnblogs.com/tansm/archive/2011/10/17/2215846.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/tansm/archive/2011/10/17/2215846.html"/><content type="html">&lt;p&gt;在我们编写代码时，经常遇到一次策略模式（俺不会背那个啥设计模式，暂时叫他策略模式吧），例如，在反序列化时，已知一个名称和命名空间，获取其对应的类型，使用下面的策略：&lt;/p&gt;&#xD;
&lt;p&gt;尝试从绑定期中获取，&lt;/p&gt;&#xD;
&lt;p&gt;如果不成功，尝试从基类获取；&lt;/p&gt;&#xD;
&lt;p&gt;如果还不成功，尝试播发事件获取。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;看起来，一个个尝试，如果不成功，下一个。代码是这个样子的。&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;private IEntityType BindToType(XElement element,IEntityType baseType, out IEnumerable&amp;lt;DcxmlBinder.CustomAttribute&amp;gt; attributes)&#xD;
        {&#xD;
            //第一级策略&#xD;
            var name = element.Name;&#xD;
            attributes = from p in element.Attributes()&#xD;
                         select new DcxmlBinder.CustomAttribute() { Namespace = p.Name.NamespaceName, Name = p.Name.LocalName, Value = p.Value };&#xD;
            IEntityType dt = _binder.BindToType(name.NamespaceName, name.LocalName,attributes);&#xD;
&#xD;
            if (dt == null)&#xD;
            {&#xD;
                //第二级策略:如果没有，看看是否有缺省类型。&#xD;
                if (baseType != null)&#xD;
                {&#xD;
                    //检查此类型的确正好是此名称&#xD;
                    string n1, n2;&#xD;
                    _binder.BindToName(baseType, out n1, out n2);&#xD;
                    if (string.Equals(name.NamespaceName, n1, _binder.StringComparison) &amp;amp;&amp;amp;&#xD;
                        string.Equals(name.LocalName, n2, _binder.StringComparison))&#xD;
                    {&#xD;
                        //不用检测派生关系，直接返回。&#xD;
                        return baseType;&#xD;
                    }&#xD;
                }&#xD;
                &#xD;
                //第三级策略&#xD;
                //TODO:应该先播发event System.Xml.Serialization.XmlElementEventHandler UnknownElement事件。外界获取类型。&#xD;
                throw new ApplicationException();&#xD;
            }&#xD;
&#xD;
            //检查派生关系是否正确，即dt必须是baseDt的派生类型。&#xD;
            if ((baseType != null) &amp;amp;&amp;amp; (!baseType.IsAssignableFrom(dt)))&#xD;
            {&#xD;
                throw new ApplicationException("设计错误，返回的数据类型没有派生自baseType");&#xD;
            }&#xD;
&#xD;
            return dt;&#xD;
        }&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;有点乱糟糟的，老实说，我也觉得乱糟糟的。于是我也想优化这样的代码，最终，我利用了C# 的或短路的特性，代码如下：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;private IEntityType BindToType(XElement element,IEntityType baseType, out IEnumerable&amp;lt;DcxmlBinder.CustomAttribute&amp;gt; attributes)&#xD;
        {&#xD;
            IEntityType dt;&#xD;
            if (TryBindFromBinder(element,out dt,out attributes) ||&#xD;
                TryBindFromBase(element,baseType,out dt) ||&#xD;
                TryBindFromEvent(element,baseType,out dt))&#xD;
            {&#xD;
                //检查派生关系是否正确，即dt必须是baseDt的派生类型。&#xD;
                if ((baseType != null) &amp;amp;&amp;amp; (!baseType.IsAssignableFrom(dt)))&#xD;
                {&#xD;
                    throw new ApplicationException("设计错误，返回的数据类型没有派生自baseType");&#xD;
                }&#xD;
            }&#xD;
            &#xD;
            return dt;&#xD;
        }&#xD;
&#xD;
        private bool TryBindFromBinder(XElement element, out IEntityType dt, out IEnumerable&amp;lt;DcxmlBinder.CustomAttribute&amp;gt; attributes)&#xD;
        {&#xD;
            //第一级策略&#xD;
            var name = element.Name;&#xD;
            attributes = from p in element.Attributes()&#xD;
                         select new DcxmlBinder.CustomAttribute() { Namespace = p.Name.NamespaceName, Name = p.Name.LocalName, Value = p.Value };&#xD;
            dt = _binder.BindToType(name.NamespaceName, name.LocalName,attributes);&#xD;
&#xD;
            return (dt != null);&#xD;
        }&#xD;
&#xD;
        private bool TryBindFromBase(XElement element, IEntityType baseType, out IEntityType dt)&#xD;
        {&#xD;
            //第二级策略:如果没有，看看是否有缺省类型。&#xD;
            if (baseType != null)&#xD;
            {&#xD;
                var name = element.Name;&#xD;
                //检查此类型的确正好是此名称&#xD;
                string n1, n2;&#xD;
                _binder.BindToName(baseType, out n1, out n2);&#xD;
                if (string.Equals(name.NamespaceName, n1, _binder.StringComparison) &amp;amp;&amp;amp;&#xD;
                    string.Equals(name.LocalName, n2, _binder.StringComparison))&#xD;
                {&#xD;
                    //不用检测派生关系，直接返回。&#xD;
                    dt = baseType;&#xD;
                    return true;&#xD;
                }&#xD;
            }&#xD;
&#xD;
            dt = null;&#xD;
            return false;&#xD;
        }&#xD;
&#xD;
        private bool TryBindFromEvent(XElement element, IEntityType baseType, out IEntityType dt)&#xD;
        {&#xD;
            //第三级策略&#xD;
            //TODO:应该先播发event System.Xml.Serialization.XmlElementEventHandler UnknownElement事件。外界获取类型。&#xD;
            throw new ApplicationException();&#xD;
        }&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;虽然代码比以前多了，但是看起来清晰了很多。而且，通常第一个策略都能完成搜索，所以就不会调用后面的方法，也就不会初始化其变量了。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/tansm/aggbug/2215846.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/tansm/archive/2011/10/17/2215846.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
