﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>博客园-专注于ASP.NET技术</title><link>http://www.cnblogs.com/netfocus/</link><description>个人网站,http://www.netfocus.cn</description><language>zh-cn</language><lastBuildDate>Wed, 03 Dec 2008 18:52:59 GMT</lastBuildDate><pubDate>Wed, 03 Dec 2008 18:52:59 GMT</pubDate><ttl>60</ttl><item><title>最近开发了一个简洁清爽的论坛, 源代码分享给大家! 希望能结识一些好朋友.</title><link>http://www.cnblogs.com/netfocus/archive/2008/12/02/1345765.html</link><dc:creator>netfocus</dc:creator><author>netfocus</author><pubDate>Tue, 02 Dec 2008 06:03:00 GMT</pubDate><guid>http://www.cnblogs.com/netfocus/archive/2008/12/02/1345765.html</guid><wfw:comment>http://www.cnblogs.com/netfocus/comments/1345765.html</wfw:comment><comments>http://www.cnblogs.com/netfocus/archive/2008/12/02/1345765.html#Feedback</comments><slash:comments>45</slash:comments><wfw:commentRss>http://www.cnblogs.com/netfocus/comments/commentRss/1345765.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/netfocus/services/trackbacks/1345765.html</trackback:ping><description><![CDATA[<p><strong>论坛演示地址:</strong><br /><a href="http://netfocus.b13.cnwg.cn" target="_blank">http://netfocus.b13.cnwg.cn</a></p>
<p>源代码下载地址:<br /><a href="http://download.csdn.net/source/823721">http://download.csdn.net/source/823721</a></p>
<p><strong>系统管理员帐号:</strong>admin,howareyou</p>
<p><strong>论坛特色:</strong></p>
<ol>
<li>简洁,清晰;</li>
<li><span style="color: #0000ff;">自行设计的抽象核心类库, 高度可重用; 站在哲学的角度来思考如何设计一个通用的框架；</span></li>
<li>简单清晰的用户、角色、权限管理体系与验证模型;</li>
<li>高性能;</li>
<li>MasterPage母版页技术，代码界面最大限度分离；</li>
</ol>
<p><br /><strong>论坛主要功能描述</strong></p>
<ul>
<li><strong>前台：</strong><br />1. 用户注册、登陆、注销；<br />2. 版块导航：显示所有的版块分组和版块；<br />3. 帖子列表：显示当前版块下所有的帖子，可以区分置顶帖子、精华帖子、推荐帖子；<br />4. 帖子内容：显示帖子内容；<br />5. 帖子回复：显示帖子的回复列表；<br />6. 添加帖子：用户添加新帖；<br />7. 添加回复：用户添加回复；<br />8. 精华帖子列表：显示所有的精华帖子；<br />9. 推荐帖子列表：显示所有的推荐帖子；<br />10. 帖子管理：具有帖子管理权限的人对帖子进行管理；<br />11. 回复管理：具有帖子回复管理权限的人对帖子回复进行管理；</li>
<li><strong>后台：<br /></strong>1. 版块组管理：添加、删除、修改；<br />2. 版块管理：添加、删除、修改，添加或修改时通过下拉框选择版块组；<br />3. 版主管理：可以管理论坛中每个版块的版主，如添加、删除版主；<br />4. 用户管理：查看用户资料、删除用户、封锁用户、解锁用户、重置密码；<br />5. 角色管理：添加、删除、修改；<br /><span style="color: #800080;">默认定义如下角色：<br />系统管理员、用户管理员、角色管理员、版块管理员、版主管理员、版主、所有者、注册用户、所有人；其中所有者指发帖人，回复人；另外系统管理员、注册用户、所有者、所有人是内置角色，不能修改或删除；下面分别对每种角色的含义进行说明：<br />1) 系统管理员：拥有论坛所有权限；<br />2) 用户管理员：拥有用户管理权限；<br />3) 角色管理员：拥有角色管理权限；<br />4) 版块管理员：拥有版块管理权限；<br />5) 版主管理员：拥有版主管理权限；<br />6) 版主：拥有所有论坛事务管理权限；<br />7) 所有者：拥有对自己发表的帖子或回复的内容进行修改的权限；（此角色可以考虑禁用，出于数据真实性考虑，因为任何人都要对他或她所说的言行负责，不允许随便修改）；<br />8) 注册用户：拥有一部分论坛事务，如看帖，发帖，回帖，管理和自己相关的一些帖子；<br />9) 所有人：这个角色只是一个映射角色，任何登陆网站的人都自动拥有此角色；此角色可以表示匿名用户；仅拥有此角色的人一般只能看帖，不能做其他任何事情。当然如果愿意，我们也可以给它分配更多的权限，如发帖，回帖。如果这样，那就意味着运行匿名用户发帖或回帖了。<br />6. 用户角色管理：对任意一个用户的所属角色进行管理（包括添加和删除用户所属角色）；<br /></span>7. 角色权限管理：分为两类进行管理；<br /><span style="color: #800080;">系统管理权限：用户管理、角色管理、版块管理、版主管理；<br />论坛事务管理权限：浏览帖子、发表帖子、编辑帖子、置顶帖子、设为推荐帖子、设为精华帖子、删除帖子、修改回复、删除回复；<br />因为权限分为两种，所以角色权限管理也可以采用两个界面实现。这两个界面的行就是所有角色，列就是当前权限类型下的所有权限点。<br /></span>8. 头像设置：设置用户的头像；<br />9. 密码修改；<br />10. 我的帖子管理：有我发布的帖子，我回复的帖子；<br /><br /><span style="color: #999999;"><span style="color: #808000;"><span style="color: #333399;">另外，一个论坛可能还常常有星级评定，积分设置，界面管理，等等其他辅助功能。这些东西可以在日后慢慢补充。 </span></span></span></li>
</ul>
<p><span style="color: #999999;"><span style="color: #808000;"><span style="color: #333399;">希望能认识志同道合的朋友，呵呵。我的MSN:txh_723@hotmail.com, QQ:94388050&nbsp; (我在公司只能用MSN)</span></span></span></p>
<p><span style="color: #999999;"><span style="color: #808000;"></span></span>&nbsp;</p><img src ="http://www.cnblogs.com/netfocus/aggbug/1345765.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43776/" target="_blank">[新闻]针对LINQ to SQL及ADO.NET Entity Framework的元数据同步工具</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>发布自己最新做的一个网站框架源代码，基于一个抽象数据库，希望各位达人能给予评价。</title><link>http://www.cnblogs.com/netfocus/archive/2008/10/04/1303710.html</link><dc:creator>netfocus</dc:creator><author>netfocus</author><pubDate>Sat, 04 Oct 2008 02:19:00 GMT</pubDate><guid>http://www.cnblogs.com/netfocus/archive/2008/10/04/1303710.html</guid><wfw:comment>http://www.cnblogs.com/netfocus/comments/1303710.html</wfw:comment><comments>http://www.cnblogs.com/netfocus/archive/2008/10/04/1303710.html#Feedback</comments><slash:comments>12</slash:comments><wfw:commentRss>http://www.cnblogs.com/netfocus/comments/commentRss/1303710.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/netfocus/services/trackbacks/1303710.html</trackback:ping><description><![CDATA[<p>源代码下载地址： <br /> http://www.netfocus.cn/downloaddetail10387.html <br />  <br /> 数据库设计说明文档地址： <br /> http://www.netfocus.cn/article10415.html</p>
<p>两年前，我接触了.NET开源社区CommunityServer（简称CS），发现它巧妙的通过设计Groups、Sections、Threads、Posts、PostCategories、PostsInCategories这六张表，将一个社区中可能出现的所有数据都放在了这六张表中。它的设计给了我很多想法，原来数据库可以这样设计。</p>
<p>从那之后，我就一直致力于研究它的实现，后来我慢慢发现它还有很多不足之处，所以下定决心一定要设计出一套比它更可扩展，更高效，更抽象的一个数据库以及一套面向该数据库的抽象通用数据访问层。这样，就可以使我们以后的网站开发工作变得轻松很多，因为我们不必再去重新设计数据库表，存储过程，访问数据库的代码等。我们要做的仅仅使编写和特定业务相关的代码，以及UI实现即可。</p>
<p>当然，因为表越抽象，就意味着表越少，也就意味着查询时链接会越多，最终就可能会导致查询速度不快。为了避免这个问题，我在设计数据库时在性能方面画了很多时间去考虑，必要时还牺牲了一点点数据冗余换取良好的性能。使用了很多技巧。后来经过测试，在100W条数据情况下，通过一个一般复杂的SQL语句查询出200条数据，只需要大概1秒时间。所以我觉得，性能应该问题不大，总算松了一口气。</p>
<p>下面是这个框架的一些设计要点： <br /> 1）通过三个抽象表存放任何数据实体以及实体之间的关系； <br /> 2）通过两种扩展字段设计方式实现任何数据实体的字段扩展需要，并且扩展的字段支持数据库级别的排序搜索功能；扩展字段的添加和一般字段没有什么大的区别，仅仅只是添加了一个特性而已。 <br /> 3）由于将实体与实体之间的关系进行高度抽象（最终抽象为平行和父子递归两种关系），导致数据库访问层的接口的通用性非常广泛，可以最大限度的支持各种可能出现的业务逻辑查询需求。<br /> 4）吸取了CS中的很多好的设计，如Provider模式，动态构建SQL实现自定义查询，缓存，多语言资源文件设计，自定义Url重写，Ajax功能，etc； <br /> 5）优秀的运行性能； <br /> 6）通过一个简单的文章发布系统的后台管理系统作为Demo，展示本框架的部分功能；</p>
<p>如何运行Demo见readme.txt</p><img src ="http://www.cnblogs.com/netfocus/aggbug/1303710.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43762/" target="_blank">[新闻]TinEye - 用图像搜索图像</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>Community Server分析系列2：配置信息读取与存储</title><link>http://www.cnblogs.com/netfocus/articles/1035652.html</link><dc:creator>netfocus</dc:creator><author>netfocus</author><pubDate>Fri, 11 Jan 2008 10:36:00 GMT</pubDate><guid>http://www.cnblogs.com/netfocus/articles/1035652.html</guid><wfw:comment>http://www.cnblogs.com/netfocus/comments/1035652.html</wfw:comment><comments>http://www.cnblogs.com/netfocus/articles/1035652.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/netfocus/comments/commentRss/1035652.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/netfocus/services/trackbacks/1035652.html</trackback:ping><description><![CDATA[<span style="background-color: #c0c0c0;">Community&nbsp;
Server，它是用ASP.NET开发的一款著名的开源社区系统。刚开始基于.NET框架1.1开发，后来转到.NET框架2.0，它的版本也从1.1
到2.0、2.1，现在最新版本是Communtiy Server
2007。通过一段时间的学习，终于对这个系统有所了解，所以，想把我的一些学习成果和心得拿出来和大家分享。以后我所有的分析都是基于我最新的学习成果
NetFocus网站，之所以不基于Community
Server是因为这个项目内容太杂，对于分析其设计思想不够方便，另外是由于NetFocus网站本身就是完全基于Community
Server架构的，并且保留了大部分好的设计思想。关于NetFocus网站源代码可以在我的个人网站上可以下载得到：</span><a style="background-color: #ffffff;" target="_blank" href="http://www.netfocus.cn/download.html">http://www.netfocus.cn/download.html</a><br />
<hr size="1" width="100%" />
<br />
第二篇，分析一下CS中整个系统的配置信息是如何配置、如何读取、如何保存的。<br />
<br />
整个CS系统中所有的配置信息基本上都存放在communityserver.config文件中，该配置文件中的所有的配置信息的读取和存放都是通过CSConfiguration这个类来实现的。通过以下函数就实现了所有配置信息的读取和存储。<br />
<br />
<div style="background-color: #dddddd;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static CSConfiguration GetConfig()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CSConfiguration config = CSCache.Get(CacheKey) as CSConfiguration;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (config == null)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string path = null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HttpContext context = HttpContext.Current;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (context != null)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; path = context.Server.MapPath("~/communityserver.config");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "communityserver.config");<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmlDocument doc = new XmlDocument();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; doc.Load(path);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; config = new CSConfiguration(doc);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CSCache.Max(CacheKey, config, new CacheDependency(path));<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CSCache.ReSetFactor(config.CacheFactor);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return config;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </div>
<br />
上面的函数先查看缓存中是否存在配置信息，如果存在，则直接从缓存读取。如果不存在，则读取配置文件中的信息，然后讲配置信息放入缓存并设置缓存依赖。最
后返回配置信息。可以看出所有的配置信息的初始化操作都是在这个类的构造函数中进行的。接下来我们看看构造函数做了什么？<br />
<br />
<div style="background-color: #dddddd;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public CSConfiguration(XmlDocument doc)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmlDoc = doc;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LoadValuesFromConfigurationXml();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
</div>
<br />
非常简单，只是把一个包含所有配置信息的xml文档对象保存起来，然后调用函数LoadValuesFromConfigurationXml加载所有的配置信息。该函数也很简单，只是按照顺序一个个读取配置文件中的信息保存在相应的属性或集合中。<br />
<br />
需要注意的是，从代码上可以看出，CS的设计人员希望通过一个唯一的入口来访问CSConfiguration这个类，所以使用了GetConfig这个
静态方法，但是并没有私有化这个类的构造函数，这样就意味着我们可以创建任意多个CSConfiguration类的实例。所以，感觉这里就设计的不够严
谨，应该用Singleton设计模式比较稳妥一点。<br />
<br />
好了，相信只要你用最多一个小时看一下这个类中的代码，就会对整个CS中的配置信息的读取和保存比较了解了。为今后分析其他功能奠定了基础。
<img src ="http://www.cnblogs.com/netfocus/aggbug/1035652.html?type=2" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43773/" target="_blank">[新闻]Silverlight开源版本Moonlight 1.0 beta发布</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>Community Server分析系列1：项目结构与数据库结构</title><link>http://www.cnblogs.com/netfocus/articles/1035651.html</link><dc:creator>netfocus</dc:creator><author>netfocus</author><pubDate>Fri, 11 Jan 2008 10:35:00 GMT</pubDate><guid>http://www.cnblogs.com/netfocus/articles/1035651.html</guid><wfw:comment>http://www.cnblogs.com/netfocus/comments/1035651.html</wfw:comment><comments>http://www.cnblogs.com/netfocus/articles/1035651.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/netfocus/comments/commentRss/1035651.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/netfocus/services/trackbacks/1035651.html</trackback:ping><description><![CDATA[<span style="background-color: #c0c0c0;">Community&nbsp;
Server，它是用ASP.NET开发的一款著名的开源社区系统。刚开始基于.NET框架1.1开发，后来转到.NET框架2.0，它的版本也从1.1
到2.0、2.1，现在最新版本是Communtiy Server
2007。通过一段时间的学习，终于对这个系统有所了解，所以，想把我的一些学习成果和心得拿出来和大家分享。以后我所有的分析都是基于我最新的学习成果
NetFocus网站，之所以不基于Community
Server是因为这个项目内容太杂，对于分析其设计思想不够方便，另外是由于NetFocus网站本身就是完全基于Community
Server架构的，并且保留了大部分好的设计思想。关于NetFocus网站源代码可以在我的个人网站上可以下载得到：</span><a style="background-color: #ffffff;" target="_blank" href="http://www.netfocus.cn/download.html">http://www.netfocus.cn/download.html</a><br />
<hr size="1" width="100%" />
<br />
今天是第一篇，就先说说如何利用它的优秀的架构，为我们将来做网站奠定一个好的网站框架。<br />
<br />
CS中总体的架构是：核心组件项目Components、通用控件项目Controls、业务应用项目也就是所谓的一个CSApplication（比如
Blog、Forum、Gallery,etc.）、数据访问项目DataProviders、用户管理项目MemberShip、界面UI项目Web。
其中<br />
<br />
1：Components提供了整个系统的基础架构：网站配置读取与存储、抽象接口声明、异常处理、用户信息初始化处理、缓存处理、日志记录、资源管理（多语言支持）、用户管理、统一的URL管理、Ajax管理、事件处理、Job处理。<br />
<br />
2：Controls提供了整个系统中所有的基类控件或实用控件；另外，由于CS也是采用MasterPage技术的，我为了学习方便，特地把和
MasterPage相关的几个类也放到了Controls项目中，这几个类实现了整个系统中所有页面的显示。总得来说，Controls项目非常简单，
说白了只要理解了TemplatedWebControl.cs这个文件后，其他的所有控件都很容易理解，因为其他的所有控件几乎都是继承自该控件的。<br />
<br />
3：CSApplication：一个CSApplication实现了一个社区系统中某个独立的子系统，比如Forum代表社区中的一个论坛子系统、
Blog代表博客子系统、Gallery代表相册子系统；需要注意的是，由于CS在设计时对整个社区系统中所有的东西都做了很好抽象，所以，所有这些子系
统的实现都非常类似，包括文件目录结构和类的实现。因为它们要实现自己的业务逻辑只要继承并重写Components、Controls中的一些已经定义
好的抽象类或基类即可，自己要重写的代码很少。大家看一下我的NetFocus网站的源代码就知道了。<br />
<br />
4：DataProviders提供了整个系统的所有的数据库访问操作。这个项目其实也非常简单，因为这个项目中几乎没什么高深的设计，这个项目中所有的
数据访问类中的方法都已经在基类中定义好了，它所做的工作仅仅是重写基类中定义的方法。每个方法里面的实现基本都是连接数据库，指定存储过程，执行存储过
程，返回结果，关闭连接。<br />
<br />
5：MemberShip：这个项目就是大家所熟悉的微软的MemberShip，功能就是提供所有和用户、角色相关的操作。本来完全可以直接使用.
NET框架2.0中的MemberShip组件，后来我在网上找到了别人破解的版本，所以就拿破解版了，并且整合到了NetFocus网站中。这样的一个
好处就是对于理解和调试代码很方便。<br />
<br />
6：Web项目，这个项目也就是大家熟悉的UI界面层。对于这个项目，也许第一次接触的人可能觉得不知如何下手，因为对于这个项目中所有的页面中的内容似
乎你都看不懂，因为东西太少了。你看不到你平时所熟悉的div,td,tr,table等，基本上每个aspx页面中的内容都不会操作30行，而且都是自
定义服务器控件或用户控件。不过不用急，看一遍不懂，多看几遍就会懂了，当你懂了之后，你会发现，其实这个项目最简单，因为所有页面的实现都是一样的：
MasterPage+用户控件（或服务器控件），另外，所有控件的后台代码都分离到了对应的CSApplication中或Controls中。其实所
有控件的ascx文件和其对应的cs文件的连接都是在TemplatedWebControl这个类中实现了。后面我还会仔细分析。 <br />
<br />
好了，上面简单的介绍了CS中最核心典型的几个项目。如果不考虑数据库的情况下，我们就已经确定了需要分离和研究的目标了，那就是：
Components、Controls、某个CSApplication、DataProviders、MemberShip、Web，这6个项目也就
是我们未来的网站的基本框架了。也就是说，如果我们的理解是正确的，那应该只要这6个项目就可以把CS运行起来了。要知道真正的CS可不止6个项目哦，起
码也要10个以上。各位看官可以查看一下我的NetFocus网站中的项目结构是否和我说的一致。<br />
<br />
到这里，我们知道了CS的总体结构，并且知道了哪些项目是必须的，哪些项目不是必须的。这样，我们就有了更小的范围，学习目标也更加明确了。只要把这6个项目研究一下就行了 ，对吧<img alt="" src="http://www.netfocus.cn/Utility/FCKeditor/editor/images/smiley/msn/regular_smile.gif" /><br />
<br />
最后，再简单的说说数据库中哪些是最重要的，必须要学习研究的。<br />
<br />
我总结了一下，必须要清楚知道的表有如下这些：<br />
0：aspnet打头的表<br />
1：cs_Users&nbsp;&nbsp;&nbsp; 用户表<br />
2：cs_Groups&nbsp;&nbsp; 后续讨论<br />
3：cs_Sections&nbsp; 后续讨论<br />
4：cs_Posts、cs_PostAttachments、cs_Posts_InCategories&nbsp; 后续讨论<br />
5：cs_Post_Categories、cs_Post_Categories_Parents&nbsp; 后续讨论<br />
6：cs_Threads&nbsp; 后续讨论<br />
7：cs_ProductPermissions&nbsp; 后续讨论<br />
8：cs_SectionPermissions&nbsp; 后续讨论<br />
<br />
我觉得只要完全掌握了以上这些表，就知道了CS中所有关键的数据是如何存放的。这样我们就可以从原本比这些多好多的表中确定出最关键的表，着重分析即可。
而对于存储过程，原本有几百个之多，而现在我们也只要关注和这几个表相关的存储过程即可。具体NetFocus中的表和存储过程各位看官打开实际的数据库
一看就应该很清楚了。<br />
<br />
在接下来的文章中，我把上面提到的每个项目和表做详细的分析，分析每个项目中最重要的东西的设计与实现，在这个过程中也会对相关的表和存储过程进行讨论。我想只要我们真正掌握了这六个项目和所有这些表，那我们也就拥有了一套比较不错的属于自己的灵活的网站框架了。
<img src ="http://www.cnblogs.com/netfocus/aggbug/1035651.html?type=2" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43773/" target="_blank">[新闻]Silverlight开源版本Moonlight 1.0 beta发布</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>谈由CommunityServer而想到的一些设计思想</title><link>http://www.cnblogs.com/netfocus/articles/1035646.html</link><dc:creator>netfocus</dc:creator><author>netfocus</author><pubDate>Fri, 11 Jan 2008 10:34:00 GMT</pubDate><guid>http://www.cnblogs.com/netfocus/articles/1035646.html</guid><wfw:comment>http://www.cnblogs.com/netfocus/comments/1035646.html</wfw:comment><comments>http://www.cnblogs.com/netfocus/articles/1035646.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/netfocus/comments/commentRss/1035646.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/netfocus/services/trackbacks/1035646.html</trackback:ping><description><![CDATA[<div class="body">
<div class="body">
<p>前段时间，我已经对CommunityServer写过几篇相关的感想类文章，表述了自己对CommunityServer中一些设计的感想以及自
己想到的一些设计思想。今天我想再写最后一篇，以后就不打算写了。其实对于CS这么一个庞大的系统来说，还有太多的东西值得我们去深入思考，但是由于时间
关系以及自身以后研究的方向会有所改变，所以以后可能不会再继续写下去了。对这个系统有兴趣的朋友可以联系我和我讨论，我非常欢迎。</p>
<p>今天我想写的是一个大范围的和CS相关的一些设计思想。我总结了一下，发现CS中是通过这样一些相互联系的因素来工作的：</p>
<p>第一，定义了一些相关的实体，不管是抽象的还是非抽象的，比如Post。</p>
<p>第二，在定义一些管理器类，比如Posts，这些管理器类负责对实体类进行管理，一般为CRUD四种典型的操作。</p>
<p>第三，还会定义一些辅助类，比如查询类，查询结果类，比如ThreadQuery，ThreadSet，SearchQuery等。</p>
<p>第四，还会定义一些存放数据访问接口的抽象类以及具体的实现类。</p>
<p>第五，还会有一些实用的类，比如CSContext，CSCache，等。</p>
<p>第六，当显示内容时，还会定义很多控件类，包括服务器控件和用户控件两种，有些控件还使用了AJAX技术。</p>
<p>第七，也是最简单轻量级的就是定义一些页面，用来供用户操作。这些页面里面仅仅放了几个相互独立或简单相关的控件。</p>
<p>对于，上面我说的七种因素是具体如何有效的联系起来的，由于一下子也说不清楚，所以就不说了。不过我个人觉得这个并不是最重要的，因为这些东西你只
要去认真研究一下代码就会明白了。我想说的是，为什么CS的设计人员会以这样的方式去构建一个系统，即为什么会设计出这七种性质的类而不用其他的一些类？
我现在发现，只要是稍微大一点的系统，几乎都是这样设计的，以前我分析过SharpDevelop，也是这样来设计，应该说比CS还要远远复杂。</p>
<p>我觉得，这里包含了一种很重要的设计思想，就是1：高内聚，低耦合；2：将职责分配给拥有执行该职责所必须信息的类；</p>
<p>1：为什么要创建一些实体类？ </p>
<p>当我们在做一个一般信息管理系统时，首先会考虑需求，然后确定它的功能，然后就会知道有哪些需要处理的实体，比如类别、书本、帖子、文章、照片、通
知、留言、回复，等等。对于这些实体，人们为了能够方便的管理（所谓的方便的管理是指，需要提供一种方便的操作方法，可以使你一次性添加或更新一个实体的
所有相关属性，或者方便的根据一个实体的唯一标识就可以删除该实体，或者需要一次性看到一个实体的所有相关属性，这里强调的是一次性，即不需要将一个实体
的所有属性通过两次操作才可以得到。），就为每个实体定义一个对应的类，这个类至少包含了对应实体所有相关的属性，这个类就是所谓的实体类。</p>
<p>2：为什么要创建一些管理类？</p>
<p>在现实生活中实体和实体是有联系的，比如一本书的评论肯定和这本书相关，一本书正常情况下肯定属于某个已知的类别等。对于一个软件系统的用户来说，
只要知道这种层次上的联系即可。但是从软件的角度来看，联系就意味着会产生相应的业务逻辑，联系越复杂，业务逻辑也就越复杂。在现实生活中联系是生活中某
个实体和实体的关系，对应到软件系统中就是软件实体和软件实体之间的关联，这种关联可以是简单的一对一，一对多，多对多，也可能是通过一个复杂的数学公式
进行关联，或者可能是通过一些其它的对象来进行关联。所以，为了实现现实生活中各种实体之间的联系，我们一般会在软件系统中创建一个业务逻辑层，在这一层
中，存放的都是一些业务逻辑类，也就是我上面所说的管理类。一般一个管理类负责管理一个软件中的实体。这里所谓的管理就是针对该实体的各种各样的操作，所
有这些操作目的都是为了实现现实生活中对该实体的使用需求。一般一个典型的CMS系统，即内容管理系统，它的业务逻辑层不会太复杂。而一个具有复杂业务流
程的软件系统，它的业务逻辑层就相对很复杂了。一般情况下，管理类和实体类是不同的两个类。我认为这是正确的，因为它们的任务决定了他们应该被定义在两个
地方。实体类负责表达某个事物的所有相关方面，管理类负责管理实体类；但是并不是说一个实体类中就不可以包含业务逻辑了，当然也可以，关键是看它是不是适
合包含这些业务逻辑，要判断适不适合就需要用到我上面提到的一句话：&#8220;将职责分配给拥有执行该职责所必须信息的类&#8221;。举个例子，订单Order类，订单项
目OrderItem，通常一个Order中会有多个OrderItem，那么当你要删除某个OrderItem的时候，应该把这个删除逻辑放在
Order类中，即使Order类是一个实体类。因为一个Order知道所有的子OrderItem的情况，所以它完全可以对它负责的所有的
OrderItem进行管理，通常的操作有CRUD四种。</p>
<p>但是上面的原则也不一定是最好的，因为它会一定程度上破坏实体对象的内聚性。还是以上面的例子来说明，如果我要在一张订单中添加一个订单项目，那可
能就会在Order类中定义一个相应的逻辑，比如叫做AddOrderItem，这个方法需要接受一个参数，参数的类型为OrderItem。这样，我们
无形中就破坏了Order类的内聚性了，因为它有一个对OrderItem的引用。所以，有的时候，我们为了不破坏一个对象的内聚性，会把
AddOrderItem操作放在一个单独的管理类中实现。CS目前的实现方式就是这样的，在CS中，所有的实体类几乎都不包含任何逻辑操作，所有的逻辑
操作都是由相应的管理类来实现的。比如，Section类是一个实体类，它代表的是一个分组，Post也是一个实体类（抽象实体类），它代表的可能是一个
帖子，一个产品，或者是一个任何可能的实体。按照第一个原则，应该在Section类里面定义一些针对Post的操作，但是CS中没有这样做，而是将对所
有Post的操作都放在了Posts类（注：实际的CS系统中没有Posts类，只有比如GalleryPosts类，但是是同一个意思。）中，可以说整
个CS系统都是用这种方式来管理实体类的。依我看来，这两个处理方式各有有缺点。前者的做法相对比较人性化，因为比较合乎人们的常规理解，但是会最终使得
各个业务逻辑类之间生成复杂的关联或引用。后面的做法，我认为更像是从软件的专业角度或软件设计经验的角度去处理对象的关联。人们在经过长期的软件开发之
后总结出了一个规则就是&#8220;高内聚，低耦合&#8221;。这是有道理的，但是并不是说是最合乎情理的，而是说这样会使我们更加容易的设计软件，这样做在正常情况下都会
减少我们编写软件系统的复杂度。所以，用一句简单的话来说就是，前者从实体关联的角度总结出来的应验，后者是从软件设计经验的角度总结出来的经验。在现实
生活中，我认为应该要两者结合比较好。</p>
<p>3：为什么要定义一些辅助类？</p>
<p>在现实生活中，当一个实体和另一个实体发生联系时，往往会通过某种工具。比如我要去ATM机取款，则必须插入卡，然后输入密码。在这个过程中，有两
个关键的实体：我、钱，另外我取钱是通过插入卡、输入密码这两个条件完成的。&#8220;取钱&#8221;其实就是一种联系，或者说是一种潜在的联系，这种联系需要依赖于两个
条件&#8220;卡号、密码&#8221;，只有当这两个条件都满足时，这种联系才成立。好，这个例子对于软件来说，就是实体A要获取实体B的信息，需要通过两个条件C1、
C2。这个时候，我们一般就会把C1、C2放在辅助类里面了，因为这些条件通常是为了辅助一个联系的正常运作而两个或多个互相组合的。所以，在一个软件系
统中，我们为了方便软件对象和软件对象之间关联的方便建立，就将所有会有助于关联建立的条件都存放在一个容器中，这个容器就是所谓的辅助类。举个CS中的
例子，当我要查询一些符合条件的帖子的时候，我需要组合一些条件然后传递给某个接口，这个接口接收这些条件后返回所需的查询结果。那么我们为了方便，就定
义了一个辅助类：ThreadQuery，这个类里面存放了所有可能出现的查询条件。当我们要根据某几个条件查询时，只要设置ThreadQuery这个
类中的几个相关的属性即可。这样是不是就给我们带来了很多的方便呢？呵呵，是的！所以，用一句话来说，辅助类是存放了一个实体和另外一个实体发生关联的所
有条件的一个容器类。</p>
<p>4：为什么要定义存放数据访问接口的类和实用类？</p>
<p>这个问题我想应该这样来回答，不一定必须要定义一些存放数据访问接口的类和实体类，定义这些类仅仅是为了我们软件实现的方便。因为，通常在一个系统
中会有很多对实体的操作，为了方便管理，人们把所有的操作都定义在一起或分组定义在一些文件中。将所有的数据访问接口定义在一起有很多好处，比如我们可以
很方便的查找某个操作的在哪里被实现，通过工厂方法设计模式还可以将所有的操作的逻辑独立于数据库。另外，将所有的其它一些实用操作存放在一起也有很多好
处，比如我们可以最大限度的重用某个实用操作而不必将该操作重复定义在多个地方。比如CS中的CSContext类，在我看来就是一个实用类，因为它里面
存放了所有和当前请求上下文相关的所有信息，其中即包括了一些系统自带的信息，也包括了所有的特定信息，比如URL的参数信息，当前用户的所有信息。CS
中所有存放数据访问接口的类都是采用Provider类的，应该说Provider模式是充分利用了工厂方法设计模式。所以可以做到业务操作逻辑和真实数
据分离。</p>
<p>5：控件、页面</p>
<p>这两个设计我想就不必多说了吧，它们只是人类用来显示数据的一种方式，你完全可以用微软的ASP.NET来呈现信息，也可以用JSP页面来呈现。如何选择完全看个人的喜好和需求了。</p>
<p>结论，上面我大致说明我对CS中为什么要设计这些类的原因，这些完全属于我个人的理解。其实我说这么多，想表达的意思只有一个，就是希望我们程序员
在平时设计软件的时候，要多想想这样设计是不是比较&#8220;优雅&#8221;了？是不是还有很多不妥的地方？另外一点就是，当我们接触一个新的复杂的系统时，除了了解它的
功能之外，更重要的是要弄清楚它的原理以及为什么会产生这样的原理，这点是最重要的。我写的所有的文章都不是只是直白的介绍技术，更多的是为了说明一种思
想，一种原理（至少在我看来是这样的），也正是为了这个目的。也许，你看到这里，会真的觉得我和很多其他人是不一样的，如果你真这么认为了，那我很欣慰，
呵呵。</p>
<p>好了，现在松了一口气，因为终于把所有我要写的都写出来了。你一定发现我废话很多吧，如果你真的看到这里了，那说明你还是很有耐心的，呵呵！这篇文
章是我对整个CS系统的最后文章了，这篇文章的标题虽然说是对CS的理解，但是更多的是讲了我对软件开发的一种理解。我不知道自己理解的有没有正确或者过
于偏激，但是就算是错误的，我也很希望可以写出来，因为知道自己是错误的就意味着你已经得到了很多，不是吗？最怕的就是自己什么都不说出来，然后也不知道
是不是真的是对的，这样就不利于自身的完善了，对吧！</p>
<p>好了，该去理发了，弄得帅一点，明天去见我女朋友，呵呵。</p>
</div>
</div>
<img src ="http://www.cnblogs.com/netfocus/aggbug/1035646.html?type=2" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43773/" target="_blank">[新闻]Silverlight开源版本Moonlight 1.0 beta发布</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>CommunityServer中关于分类的最新思考成果</title><link>http://www.cnblogs.com/netfocus/articles/1035642.html</link><dc:creator>netfocus</dc:creator><author>netfocus</author><pubDate>Fri, 11 Jan 2008 10:32:00 GMT</pubDate><guid>http://www.cnblogs.com/netfocus/articles/1035642.html</guid><wfw:comment>http://www.cnblogs.com/netfocus/comments/1035642.html</wfw:comment><comments>http://www.cnblogs.com/netfocus/articles/1035642.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/netfocus/comments/commentRss/1035642.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/netfocus/services/trackbacks/1035642.html</trackback:ping><description><![CDATA[<div class="body">
<p>又有好长时间没有写文章了，最近几天正在思考如何利用目前CS的架构做一个网上书店。在设计书本类别、出版社、最新图书、推荐图书，等等功能时发现只要稍微修改一下目前CS中关于类别的设计就可以实现所有的功能，下面我开始慢慢分析。</p>
<p>研究过CS的朋友应该知道，CS中一个category(类别)是属于某一个section的，当初CS的设计者这样设计的原因我想因该主要是为了
实现某个人的blog中的文章分类或者某个人的相册中的照片分类的，没错这种设计在blog系统或者相册系统中是满足需要了，但是在一些更加复杂的应用中
比如电子商务系统中就不能满足需要了。目前CS中对section下分类的实现的致命的缺点是某个section下的所有的类别都是平等的，所以，我们就
不能对这些类别进行进一步分组，关于这个问题我记得前面也写过一篇关于分类的相关文章，那篇文章是以不改变目前CS表结构的方式实现各种分类需求。</p>
<p>当我的个人网站采用了当初第一篇文章中所描述的分类方法后，发现这样做虽然可以实现我要的任意功能，但是需要建很多不必要的
CSApplication，这样会导致整个网站变的臃肿，因为为了一个新的简单的分类就要去新建一个CSApplication，现在想想感觉非常不
好，尽管实现起来也比较简单的。呵呵，说实话，当初感觉还是满好的，只不过用多了，感觉就麻烦了，所以现在期望能够改进一下。</p>
<p>经过我这段时间的观察和思考，一般一个典型的网上书店对书本都会有以下一些分组：</p>
<p>1)正统归类，比如计算机图书、.Net图书、Java图书、C#类图书等，这些类别可以嵌套；<br />
2)按出版社归类，即查询某个出版社出版的所有图书；<br />
3)按作者归类，即查询某个作者的所有图书；<br />
4)图书系列，每个图书系列中都有一些相关的图书，比如.Net黑皮书系列，等；</p>
<p>.....，还有很对你可以想到的其它分组方式。</p>
<p>从上面的一些实际的需求中我们可以看出，我们对一本书从不同的角度去观察它，那它就属于不同的分组。比如说，ASP.NET高级编程这本书，既属
于.Net，又属于Wrox红皮书系列，可能还属于清华大学出版社等，当我们要.Net图书时，应该可以找到它，找Wrox红皮书系列图书时，也可以找到
它，同理找清华大学出版社的所有图书时也同样可以找到它。上面的这种现象从数据库原理的角度来理解就是一个对象可以属于多个类别，一个类别下也可以包括多
个对象，即我们通常所说的多对多的关系。这个功能在目前的CS系统中已经完全实现，这点我就不多说了，如果还不清楚的，可以去查看一下数据库。</p>
<p>下面我说一下，在我看来应该如何合理的在目前CS的设计基础之上实现上面的需求。</p>
<p>前面说过，CS中某个section下所有的分类都是不能进一步分组的，就是说如果某个seciton下有5个分类，我们希望前面两个类别是对文章
进行分类的，后面三个类别是对照片进行分类的，当我们需要找出所有的文章分类，或者所有的照片分类时，目前的CS就无能为力了。我现在想想对这些分类进行
分组是多么有意义。所以，我就扩展目前的cs_PostCategories表，添加一个字段，比如Group,该字段的作用就是对某个section下
的类别进行分组。我们可以将前面所有的文章分类放在一个分组中，照片分类放在另外一个分组中，这个字段我们在上层的代码中可以设定为枚举，为各个枚举值设
置一个不重复的整数值即可，在数据库中Group字段保存的就是该整数值。好下面我谈一下添加这个字段我们可以解决什么问题。</p>
<p>前面网上书店对书本进行不同分组的这个需求现在就可以轻松解决了。</p>
<p>我们可以先预先定义很多对书本分类的分组的枚举，比如：</p>
<p>BookCategory:该分组下的任何一个类别表示一个一般的图书类别，比如.Net图书；<br />
Publisher:该分组下的任何一个类别表示一个出版社，比如清华大学出版社；<br />
Author：该分组下的任何一个类别表示一个作者，比如章立民；<br />
BookSeries：该分组下的任何一个类别表示一个图书系列，比如Wrox系列；</p>
<p>好，现在我们就可以为各个类别分组添加很多类别了，这些类别还可以递归嵌套，并且我们可以很轻松的知道哪些类别是属于哪个分组，只要根据Group这个字段进行查询即可。</p>
<p>关于图书和类别之间的关系还是可以按照正常的方式进行关联，目前CS已经实现，对应的关系表是cs_Posts_InCategories(不知道有没有记错)。</p>
<p>不知道各位看官有没有清楚这样做会给我们带来什么好处？我想好处是显而易见的，就是只要添加Group这么一个字段，我们就可以实现对图书(也就是
一个Post)的任意任意归类，并对类别进行任意分组。你所需要思考的仅仅是抽象，即要从思想上意识到，并不是.Net类图书才是对书本进行分类，某个出
版社或某个作者就不是对书本进行分类了，您必须理解这些其实也是对书本进行归类，比如&#8220;推荐图书&#8221;、&#8220;特价图书&#8221;这些也是对书本进行归类，对吗？
：）关键是你要理解这个概念。也许这也算是一种抽象吧，呵呵。</p>
<p>下面再以我的个人网站为例，说明一下这种归类和分组的好处：</p>
<p>我的个人网站中有通知、个人介绍、日志、文章、照片、作品、留言这些实体；其中，目前的需求是，文章和照片是需要分类的，类别不需要递归，只要一层即可。好，基于添加了Group字段的CS架构，我们可以按照下面的方式有效的管理所有这些实体。</p>
<p>1.<br />
建立一个Section，并给管理员分配对该Section完全控制的权限，给匿名用户分配查看和添加评论的权限；</p>
<p>2.<br />
为上面的每个实体定义一个枚举，比如PostType；</p>
<p>3.<br />
为文章分类分组、照片分类分组分别定义一个枚举，比如PostCategoryType；</p>
<p>4.<br />
添加所有的文章分类和照片分类，添加时每个分类都指定其所属的分组；</p>
<p>5.<br />
接下来就可以在这个section下添加所有的实体了，一方面实体之间可以通过PostType枚举区分，另一方面，如果要查这个section下的所有
的文章类别，则只要获取某个PostCategoryType枚举下的所有分类即可。如果要查询某个类别下的所有的实体的时候，只要将该类别的ID传入数
据库进行过滤即可。这里有一个特殊的问题是，如果类别是嵌套的，比如.Net类别、ASP.NET类别、C#类别，其中ASP.NET类别、C#类别是.
Net类别的子类别，现在我要查询.Net类别下的所有图书，怎么做呢？因为数据库里面没有一本书是直接和.Net类别关联的，都是和其子类别关联的。那
么是不是就只能把其下面的所有子类别的图书都找出来然后合并起来，最后返回呢？这样做也许可以，但是你一定觉得太复杂了吧，没错，肯定有好的高效率的方
法，关于如何解决这个问题，我先不说了，还是留待各位自己去慢慢琢磨吧，呵呵。不过我可以提一下，就是在cs_PostCategories表中还有一个
字段叫Path的，各位看官可以考虑利用该字段来解决我上面说的这个问题。</p>
<p>好了，上面我说了大致我的个人网站实现的思路，如果对具体实现感兴趣的朋友可以下载我的网站源代码，我也是支持开源的哦，因为本身自己也是从别人的开源项目中学东西呀，呵呵。</p>
<p>啊，没想到已经写了一个小时了，该停了，希望下次再有一些好的想法和大家交流。大家看了我的文章之后如果有意见或体会的别忘了给我留言哦！</p>
</div>
<img src ="http://www.cnblogs.com/netfocus/aggbug/1035642.html?type=2" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43773/" target="_blank">[新闻]Silverlight开源版本Moonlight 1.0 beta发布</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>CommunityServer中关于权限控制体系的一些修改</title><link>http://www.cnblogs.com/netfocus/articles/1035644.html</link><dc:creator>netfocus</dc:creator><author>netfocus</author><pubDate>Fri, 11 Jan 2008 10:32:00 GMT</pubDate><guid>http://www.cnblogs.com/netfocus/articles/1035644.html</guid><wfw:comment>http://www.cnblogs.com/netfocus/comments/1035644.html</wfw:comment><comments>http://www.cnblogs.com/netfocus/articles/1035644.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/netfocus/comments/commentRss/1035644.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/netfocus/services/trackbacks/1035644.html</trackback:ping><description><![CDATA[<div class="body">
<div class="body">
<p>由于这个阶段的目标是要做一个比较通用的基于CS的权限管理系统&nbsp;这几个晚上我又仔细研究了CS中权限的实现，发现确实有一些设计局限的地方。所以决定对其进行修改。</p>
<p>先说一下目前CS中和权限及用户相关的权限控制体系。</p>
<p>主要有这么几个东西：</p>
<p>User、Role、Permission(一个枚举)、PermissionBase、Section。</p>
<p>当某个User要访问某个Section中的内容时，CS会先获取该User的所有的Roles，然后在找到这些Roles在当前Section下
的所有的PermissionBase，并把这些PermissionBase合并，通过二进制或的运算即可。最后将得到的那个总的
PermissionBase和一些Permission枚举值进行比较，比如和Permission.Post进行比较，根据比较的结果就可以知道该用
户是否对当前Section有权限了。</p>
<p>这个流程本身是没有问题的，我觉得唯一的问题是由于CS在Permission枚举类型中定义写死了一些权限点，并且要求所有的未来的
CSApplication的相关权限控制点都依赖于该枚举，那就有点局限了，你说呢。因为很可能我要定义一些权限点不是一些基本的Add、
Delete、Reply等权限点，而是和业务逻辑相关的权限点。</p>
<p>我的做法：</p>
<p>将Permission枚举删除，转而用long类型的参数替换，以保证不会影响现在的PermissionBase中的代码。然后在各个
CSApplication中定义自己的权限点，权限点可以用枚举值表示，就想Permission枚举一样，只不过这些枚举值你可以自己任意定义。然
后，在传入PermissionBase类的接口中时，把枚举值的类型强制转换为long之后再传入即可。我发现通过这样的方法确实是可行的，而且可扩展
性也比较好。</p>
<p>上面是我对CS权限控制的一些优点和缺点的思考及我的一些解决方法，希望对大家有所帮助。</p>
</div>
</div>
<img src ="http://www.cnblogs.com/netfocus/aggbug/1035644.html?type=2" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43773/" target="_blank">[新闻]Silverlight开源版本Moonlight 1.0 beta发布</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>根据CS中的类的命名研究其设计思想</title><link>http://www.cnblogs.com/netfocus/articles/1035640.html</link><dc:creator>netfocus</dc:creator><author>netfocus</author><pubDate>Fri, 11 Jan 2008 10:30:00 GMT</pubDate><guid>http://www.cnblogs.com/netfocus/articles/1035640.html</guid><wfw:comment>http://www.cnblogs.com/netfocus/comments/1035640.html</wfw:comment><comments>http://www.cnblogs.com/netfocus/articles/1035640.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/netfocus/comments/commentRss/1035640.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/netfocus/services/trackbacks/1035640.html</trackback:ping><description><![CDATA[<div class="body">
<p>今天这篇文章打算在一个小时之内完成。一直以来，我写的关于CS的文章都融入了我的自己的想法，这篇也不例外。今天写一下关于CS中对于各个类的命名方式，以及我们要如何根据它那些类的命名方式来推断这个类的含义，最后还写到了一些相关的面向对象的设计思想。</p>
<p>在CS中，如果是对某个实体类进行命名，则一般都是这样的：Group、Section、Post、User、Role、Message，等等；如
果是对某个实体的集合类命名，则为：ApplicationSet、PostSet、ThreadSet、UserSet，等等；如果是对某个管理实体的
管理类进行命名，则一般为：DataProviders、Groups、Sections、PostCategories、Roles、
Permissions，等等；如果是一些查询条件类，则为这样：ThreadQuery、UserQuery，等等。如果是一些利用Provider模
式的数据操作访问类，则一般都是以Provider结尾，比如CommonDataProvider、GalleryDataProvider，等等。</p>
<p>好，从上面的命名方式可以看出，CS中对类的命名方式我认为相对还是比较科学的，当我们看到一个类，如果它的名称可以代表一个实体，则它就是一个实
体类，这个类里的结构一定相对比较简单，只有一些属性和简单的方法；如果这个类的名称后缀带有&#8220;s&#8221;，那它可能就是一个管理类，它里面一定都是一些方法，
而且可能是一些静态方法；如果类的名称是以&#8220;Set&#8221;结尾，那它一般就是一个集合类，这个类一般结构最简单，它的作用就是用来存放一些查询结果。比如
ThreadSet这个类就是用来存放一些Thread实体的。而对于ThreadQuery这样的类，往往就是一些查询条件的容器类，
ThreadQuery就是存放了一些查询Thread的条件信息的容器。对于以Provider结尾的类，则里面包含了一些抽象的函数或虚函数，这些函
数可以或必须被重写。这些函数的作用就是提供一系列操作实体的接口，供一些管理类调用。</p>
<p>上面分析了CS中一些类的命名特点以及他们通常的用途，下面我再说一下我更进一步的想法。</p>
<p>所谓的面向对象编程，应该是指这样一种意思：一些对象操纵者通过某种手段操纵或者直接操纵对象，如果操纵的结果比较复杂，则会把结果放到另外一个对
象中，这样我们就又可以用面向对象的方式来操纵这个&#8220;操纵结果&#8221;。也就是说，为了完成某件事情，需要有一个操作者和一个被操作者，另外还有一些操作手段和
操作结果，其实我们也可以把操作手段和操作结果也看成是一个被操作者，因为他们也是被操作者利用的一个棋子，最终也是要被操作者操纵才有意义的。所以，对
于我们来说，用面向对象的思想编程，最重要的就是要知道一个应用中有哪些操作者，哪些被操作者，哪些是辅助的被操作者，它们分别具有的职责是什么。突然记
起《UML与模式设计》一书中提到的一句话，OOA/D（面向对象分析和设计）中最重要的就是为对象分配职责。当我们要确定某个函数（职责）应该属于哪个
类时，我们要遵循的一个原则是：&#8220;将职责分配给执行该职责所必须信息的类&#8221;。我觉得这个是很有道理的，这样的原则保证了每个类中的每个函数的实现都是很自
然的，不需要额外的，牵强的去依赖于某个其他类里的某些东西。这也会加强类的封装性、内聚性。当然有时我们考虑问题时也不能这么简单，在设计时往往还要和
所要求的&#8220;高内聚、低耦合&#8221;等原则结合，最终选择一个折中的方案。</p>
<p>最后，我把整个CS系统中的一些最关键的类列出来，并做简单讲解，希望对各位分析CS提供侧重点。</p>
<p>CSHttpModule：一个自定义HttpModule，用来在一次请求的早期添加一些预处理，比如用户身份验证、权限设置，等；</p>
<p>CSConfiguration、SiteSettings：存放整个站点的全局配置信息；</p>
<p>RoleConfiguration、Role、Permission：和权限相关的一些类；</p>
<p>CSContext：封装一个页面一次请求过程中的所有信息；</p>
<p>CSCache：提供所有和缓存相关的操作；</p>
<p>CSApplication：封装了某个CS应用程序，如Blog、Forum，等；</p>
<p>CSException：代表了一个自定义异常；</p>
<p>Group、Section、Post、Thread、PostAttachment、PostCategory：存放所有主要的实体信息；</p>
<p>User：封装了当前请求过程中的所有用户信息；</p>
<p>SiteUrls：通过面向对象的方式为为这个站点提供所有需要用到的Url信息；</p>
<p>CSEvents：定义了整个站点中可能触发的事件；</p>
<p>IJob：定义了以后需要在网站后台定时处理的一个工作任务；</p>
<p>Provider：提供了一系列相关的抽象操作，每个操作完成一个特定的数据库操作任务；</p>
</div>
<img src ="http://www.cnblogs.com/netfocus/aggbug/1035640.html?type=2" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43773/" target="_blank">[新闻]Silverlight开源版本Moonlight 1.0 beta发布</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>谈如何利用CS架构实现一个网上书店中的类别管理</title><link>http://www.cnblogs.com/netfocus/articles/1035637.html</link><dc:creator>netfocus</dc:creator><author>netfocus</author><pubDate>Fri, 11 Jan 2008 10:29:00 GMT</pubDate><guid>http://www.cnblogs.com/netfocus/articles/1035637.html</guid><wfw:comment>http://www.cnblogs.com/netfocus/comments/1035637.html</wfw:comment><comments>http://www.cnblogs.com/netfocus/articles/1035637.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/netfocus/comments/commentRss/1035637.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/netfocus/services/trackbacks/1035637.html</trackback:ping><description><![CDATA[<div class="body">
<p>好多天没写文章了，今天正好有点时间，所以就再花半个小时写一篇我最近一直在思考的一个问题。今天这篇文章的主题是，如何利用目前CommunityServer中的设计，实现一个网上书店中任意层次的类别管理功能。</p>
<p>先看一下一个一般的网上书店中书本的类别是如何组织的。其实很简单，就是一颗类别树，一个类别节点下面有任意多个类别子节点。那么我在考虑的问题
时，如果我们把某个类别删除了，比如删除了.Net图书这个类别，那是不是.Net图书类别下的所有子类别也要删除呢？按照以往的方式，应该是要删除的。
但是我觉得是不是不应该删除子节点，而是重新组织子节点更加合理呢？比如你可以将.net类别下的所有子类别等级上升为第一层节点。不过，不管怎样讨论这
个没有意义，因为不同的情况下有不同的需要，我们只要根据具体情况来设计就可以了。</p>
<p>在CS2.1中，PostCategory这个类的作用是对某个Section下的所有Post进行归类，而且从表
cs_PostCategories可以看出，归类是支持递归的，也就是说是允许类别嵌套的。虽然数据库表是设计为支持递归定义的，但是似乎没有一个模块
利用了这个功能，因为在CS2.1中所有对Post归类的地方一般都只有一层，比如随笔分类、相册中的影集，等等。所以，要真正实现对Post的递归分类
管理功能，需要我们自己写代码实现。研究过CS的朋友肯定知道Section是递归的，而且CS团队已经将Section进行了递归处理。通过对代码的研
究发现，在每一个Section中都定义了一个属性，Sections，这个属性表示当前Section下的所有子Section。而在
PostCategory这个类中却没有定义一个类似Categories的属性。所以，如果我们也要实现对PostCategory的递归处理，也可以
和Section一样，在PostCategory类中添加一个Categories的属性，表示当前PostCategory下的所有子
PostCategory。好了，只要添加这个属性即可，另外要做的事情仅仅是在获取某个或某些PostCategory时，需要为Categories
属性赋值，关于如何赋值可以参考Section是如何为其Sections属性赋值的。然后，按照目前CS提供的对PostCategory的CRUD操
作，我们就可以很轻松地对PostCategory进行递归处理了。昨天网上我基本完成了这个功能，再经过测试之后就可以整合到目前我的个人网站框架中。</p>
<p>我们知道，通常要递归的管理一些实体，最好的方式就是采用树状结构。像CS在管理Section时就是采用树的。所以，我们可以参考Section的树状管理代码，自己写一个用户控件，以及一个后台CS文件。这样就可以轻松对PostCategory实现递归处理。</p>
<p>Section和PostCategory不同的地方是，Section是对某个Post进行正统的归类，即只要有一个Post，则理论上必须使之
对应一个Section。而PostCategory则不同，因为它和Post是多对多的关系，所以，某个Post不一定必须和某个CategoryID
关联，同样如果你删除了某个PostCategory，它下面的Post是不会删除的。其实在CS中，PostCategory的功能是被设计为实现
Tag功能的。</p>
<p>好，到目前位置，讨论了网上书店中图书分类的功能，以及目前CS的一些设计基础。那么我们具体应该怎么来做呢？</p>
<p>从一个大的前提出发，因为CS架构中，任何子模块，比如论坛、博客、相册登都是以注册用户为中心的，它强调的是我发表过的帖子、我的博客、我的相册
这种概念。而一个典型的网上书店，是以书本为中心，强调的是图书展示、图书购买、订单支付这么一个流程。所以似乎和CS目前的实际不是很符合。现在想想也
是可以的。下面是我的想法：</p>
<p>我们可以将网上书店整个站点理解为是CS中的一个模块，相当于是一个论坛或博客或相册，只不过这个网上书店模块只能由系统管理员才可以管理。所以，
我们可以类似于某个人管理他的博客那样来管理整个网上书店。首先，我们需要为这个网上书店创建一个&#8220;网上书店分组&#8221;，相当于一个&#8220;博客分组&#8221;，然后再创建
一个&#8220;网上书店&#8221;，相当于一个&#8220;博客&#8221;。这样就创建了一个Group，一个Section了。然后通过CS现有的对Section的权限管理功能，分配系
统管理员拥有管理该Section的权限，分配一般用户查看该Section下所有Post（书本）的权限。这样就完成了系统管理员和一般注册用户的区
分。然后考虑如何实现网上书店中的所有书本类别的管理，这个刚才在上面已经说了很多了。在创建所有的图书类别时只要和网上书店对应的Section关联即
可。呵呵，是不是很简单呢，其他的应该都比较容易实现的，一个本书以及它的所有评论都可以用Post来实现，出版社、购物车、订单等可以通过自己扩展表或
者也存放在Post中，只要你开动脑子，都可以实现的。</p>
<p>好了，就写到这里吧，不知道各位看官有没有看懂，如果没有理解的欢迎和我交流。快吃饭去了，88</p>
</div>
<img src ="http://www.cnblogs.com/netfocus/aggbug/1035637.html?type=2" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43773/" target="_blank">[新闻]Silverlight开源版本Moonlight 1.0 beta发布</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>如何彻底的做到代码和界面分离</title><link>http://www.cnblogs.com/netfocus/articles/1035635.html</link><dc:creator>netfocus</dc:creator><author>netfocus</author><pubDate>Fri, 11 Jan 2008 10:28:00 GMT</pubDate><guid>http://www.cnblogs.com/netfocus/articles/1035635.html</guid><wfw:comment>http://www.cnblogs.com/netfocus/comments/1035635.html</wfw:comment><comments>http://www.cnblogs.com/netfocus/articles/1035635.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnblogs.com/netfocus/comments/commentRss/1035635.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/netfocus/services/trackbacks/1035635.html</trackback:ping><description><![CDATA[<div class="body">
<p>离三点钟还有半个小时，趁机把自己编程的一个小的技巧写下来吧！废话不多说了。</p>
<p>我们都知道在ASP里面，VBScript是嵌套在网页里面被解释执行的，也就是说代码和界面混杂在一起，所以用起来和维护起来非常的麻烦。在
ASP.NET里面情况有了本质上的变化，界面已经和代码基本没有大的关系了，一个ASPX页面对应一个CS或VB文件，可以说基本做到了代码和界面的分
离。其实微软是伟大的，它做的ASP.NET其实是一个框架，在该框架中提供了几个关键的方法，使得我们可以做到代码和界面的进一步分离，比如
CommunityServer中就很好的利用了这点。在CommunityServer中已经将ASPX文件的后台CS全部分离，转而通过用户控件或服
务器控件实现，而用户控件的后台代码都放在另外一个项目中，这样就形成了界面层中几乎只包括ASPX、ASCX等文件，而它们的后台CS文件都移到了其他
项目中，所以这就做到了进一步的分离，你说对吧？</p>
<p>我上面说的分离只要研究过CS的人因该都是知道的，但是下面这个技巧可能你就不一定知道了。</p>
<p>如果你现在要显示一个实体的详细信息，比如一篇新闻、一篇文章、一个产品，等等。你一般会怎么做呢？我想大部分人都是调用一个类似
GetObject(int
objectID)的方法，然后把该Object取出来，然后你会怎么办呢？通常你会在页面上放一些Label，Literal，或者其他服务器控件之类
的，每个控件都有一个你自己命名的ID，然后你会在页面的Load事件处理函数中通过FindControl函数找到这些界面上的服务器控件，然后为其一
个个赋值。这样就达到了显示详细信息的目的。但是你有没有想过，这样做已经讲界面和后台CS代码绑定在一起了，如果你删除了某个服务器控件或者修改了它的
ID，那你的代码如果没有Try起来或者做空值判断，那肯定会出问题了。所以，为了能够既可以显示详细信息，又可以将代码和界面的耦合减到最少，我想到了
一种方法，如下：</p>
<p>我们可以在界面上放一个Repeater控件，在这个控件的ItemTemplate模版中将当前的Container.DataItem对象取出
来，然后，你可以通过DataBinder.Eval函数取出该对象中的任何一个字段，然后在和某个客户端标记绑定，或者直接显示出来。在后台CS文件
中，你唯一要做的只是把页面上的Repeater控件得到，然后把你通过GetObject函数得到的那个数据对象放到一个集合中，并把这个集合和这个
Repeater控件绑定即可。通过这样的方式说白了就是把显示一个实体当作和显示一个列表一样来处理。这样做有点奇怪，所以我想很多人确实不会那样去想
或做。关于前台如何显示数据，下面是一段示例HTML代码：</p>
<p>&lt;%@ Register TagPrefix="CS" Namespace="NetFocus.Web.Controls" Assembly="NetFocus.Web.Controls" %&gt;<br />
&lt;%@ Register TagPrefix="CS"
Namespace="NetFocus.WebApplications.Article.Controls"
Assembly="NetFocus.WebApplications.Article" %&gt;<br />
&lt;%@ Import Namespace="NetFocus.WebApplications.Article.Components" %&gt;<br />
&lt;%@ Import Namespace="NetFocus.Web.Components" %&gt;<br />
&lt;%@ Control Language="C#" %&gt;</p>
<p>&lt;div class="designpattern-detail1"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;asp:Repeater EnableViewState="false" runat="server" id="list"&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;ItemTemplate&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;div class="title"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;%# DataBinder.Eval(Container.DataItem, "Subject") %&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/div&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;div class="subtitle"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;CS:ResourceLiteral runat="server" ResourceName="PostDate" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;%# DataBinder.Eval(Container.DataItem, "PostDate") %&gt;&amp;nbsp;&amp;nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;CS:ResourceLiteral runat="server" ResourceName="Source" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;%# DataBinder.Eval(Container.DataItem, "Source") %&gt;&amp;nbsp;&amp;nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;CS:ResourceLiteral runat="server" ResourceName="Replies" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;%# DataBinder.Eval(Container.DataItem, "Replies") %&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/div&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;div class="body"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;%# DataBinder.Eval(Container.DataItem, "Body") %&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/div&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;/ItemTemplate&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/asp:Repeater&gt;<br />
&lt;/div&gt;</p>
<p>以上这段代码是我的NetFocus个人站点中显示文章详细信息时前台用户控件中所使用的代码。各位看这段代码的时候可以和你正在浏览的网页的布局结合起来看，就很容易懂了。</p>
<p>好了，不知道这样我有没有说清楚，时间正好是半个小时，呵呵。</p>
</div>
<img src ="http://www.cnblogs.com/netfocus/aggbug/1035635.html?type=2" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43773/" target="_blank">[新闻]Silverlight开源版本Moonlight 1.0 beta发布</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>由CommunityServer中的权限控制设计想到的一种思想</title><link>http://www.cnblogs.com/netfocus/articles/1031456.html</link><dc:creator>netfocus</dc:creator><author>netfocus</author><pubDate>Wed, 09 Jan 2008 02:32:00 GMT</pubDate><guid>http://www.cnblogs.com/netfocus/articles/1031456.html</guid><wfw:comment>http://www.cnblogs.com/netfocus/comments/1031456.html</wfw:comment><comments>http://www.cnblogs.com/netfocus/articles/1031456.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnblogs.com/netfocus/comments/commentRss/1031456.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/netfocus/services/trackbacks/1031456.html</trackback:ping><description><![CDATA[<p>今天终于有空了，整理完所有的东西，开始履行我刚开始的承诺，写一些心得体会出来。今天我要说的内容是CommunityServer（以下简称CS）中的权限策略以及由此想到的一些自身的体会。先说明一下，看我的文章需要一定的耐心，因为我说的东西可能会有一定的抽象，我从来不喜欢写一些别人都写过的东西。当然，如果你觉得没什么意思，可以不看的，呵呵。</p>
<p>在CS2.1中，权限是通过一个叫Section的抽象类来分配的。举例说明：博客模块中，整个网站中有一些博客分组，每个博客分组对应一个Group，由于Group没有对权限进行处理，所以每个博客分组也就无法验证权限了。其实在现实生活中也没有多大必要去控制一个博客分组的权限。在每个博客分组的下面有很多的博客，一个博客就对应一个Section，而Section是和权限相关的，所以，我们就可以控制某个博客是否允许被某个用户访问或做其它操作。那么到底一个Section是怎么和用户关联来确定该用户是否有访问该博客的权限的呢？这个关联过程比较复杂，需要用一段文字才能描述清楚。在一般情况下，某个Section的默认权限是这样和一个用户关联的：</p>
<p>我们知道一个用户有一些角色，这个是MemberShip就已经实现了的，不需要我多说。另外，在CS的数据库中还有一张表叫ProductPermissions，正是该表把一个Section的默认权限和一个用户的角色关联起来。该表的表结构各位看官要自己去看，我就不多说了。可以这样来理解：博客应用程序中的任何一个Section都表示一个博客，那么如果我要给一个Section设置一个默认的权限，则只要给该博客应用程序指定一些默认的权限即可。对应到ProductPermissions表就是，一个ApplicationType对应多个RoleID。ApplicationType就表示一种一用程序如博客，RoleID表示一个用户的某个角色，它来自Roles表。说到这里只是说明了一个应用程序可以和一些角色关联；还有另外一个关键点是：一个用户同时也可以属于多个角色；好，那就是说一个用户和多个角色关联，而一个Section也和多个角色关联，那只要联合这两个关联是不是就可以确定该用户是否有对某个Section操作的权限了呢，答案当然肯定的。但是，这里只是讲了大致的关联，一个很重要的细节还没有说清楚。就是说，到底怎么确定一个用户有哪些权限呢？你一定看到了在ProductPermissions表中还有另外两个字段就是AllowMask和DenyMask，是的，这两个字段就是存放具体的权限信息的。下面举一个完整的例子说明：</p>
<p>若一个博客应用程序中规定了这么几种具体的权限：浏览、添加、删除、修改、回复、属性设置、上传附件；另外假设当前站点中有这么几种权限：系统管理员、博客拥有者、博客编辑员、博客附件管理员、一般注册用户、所有用户；假设其中系统管理员角色、博客拥有者角色拥有所有的权限，博客编辑员拥有浏览、添加、删除、修改的权限，一般用户拥有浏览、回复的权限，所有用户只拥有浏览的权限；好，现在如果一个用户A拥有系统管理员角色，用户B拥有博客拥有者角色，用户C拥有一般用户角色，用户D拥有所有用户角色，用户E拥有博客编辑员和博客附件管理员的角色；那么就可以严格的得出以下结论：</p>
<p>用户A、B拥有所有的权限；</p>
<p>用户C拥有浏览和回复的权限；</p>
<p>用户D只拥有浏览的权限；</p>
<p>用户E拥有浏览、添加、删除、修改、上传附件的权限；</p>
<p>到这里，你是不是已经理解了为什么每个用户有这样的权限呢？如果是是，那恭喜你，下面一段你就不用看了，如果是否，那还必须看下面一段。</p>
<p>为了便于说明这种思想，我用离散数学的原理来说明。</p>
<p>假设有如下前提：</p>
<p>AA集合中包含了A1、A2、A3、A4、A5这5个元素；R1集合中包含了A1到A5这5个元素；R2集合中包含了A1、A2这2个元素；R3集合中包含了A3、A4这2个元素；R4集合中包含了A5这个元素；另外，如果还存在下面这些关系：</p>
<p>{AA，R1}，{AA，R2}，{AA，R3}，{AA,R4}；</p>
<p>{用户1，R1}，{用户2，R2}，{用户3，R3}，{用户3，R4}；</p>
<p>那么就可以推断出以下结论：</p>
<p>用户1可以访问元素：A1，A2，A3，A4，A5</p>
<p>用户2可以访问元素：A1，A2</p>
<p>用户3可以访问元素：A3，A4，A5</p>
<p>上面的离散数学模型其实就是CS里面的权限理论模型，A1到A5就对应一个应用程序中的5中权限；R1到R4就对应四种角色；用户1到用户3就对应三个用户；不知道我这样解释你是否可以明白，如果还不能明白，那我可能就没什么办法了，需要你在多去学学离散数学了，呵呵。</p>
<p>所以，在CS系统中为什么有些用户他只有一个博客，而有些用户比如系统管理员、博客管理员他拥有所有博客的管理权限。原因就是通过上面的权限控制原理来进行判断当前用户到底拥有哪几个博客，或者一个博客都没有。另外，相册模块也是一个道理。</p>
<p>好了，到这里为止，我都是在说明CS中是如何为某个Section应用权限的，虽然一些具体的实现代码我没有说明，但我已经说明了一个原理，一个模型，我觉得这样说明已经够了，动不动就贴代码不是我写文章的作风，具体实现代码需要你自己去看的哦！我只是希望可以帮你引导，帮你引入主动思考某个问题的轨道。</p>
<p>那么，从这种设计本身出发，我们可以想到什么呢？我脑子里想到的更加抽象的模型是这样的：</p>
<p>有一个对象，我们为了对他进行更加精确和细粒度的控制，对其划分了若干个相互独立的操作。然后将这些操作按照有一定现实意义的方式进行组合，使得组合后的那个聚合体更加有实用意义，更加能够象征某个操作者的身份。另外，对于需要操作该对象的操作者而言，为了能够有效的控制该操作者能够对该对象进行哪些操作，人们采用了这样的方法，就是将对象和某些聚合体关联，将操作者也和某些聚合体关联，这样利用集合本身的叠加作用，我们就可以灵活的控制一个操作者可以对一个对象进行哪些操作。为什么说用这样的方式控制操作权限非常灵活，因为1）对对象的细粒度操作的划分可以任意多，只要不重复即可；2）对这些细粒度操作的组合也可以任何组合；3）无论是对象还是操作者都可以以任意方式和这些聚合体进行组合；也就是说所有的关系都可以变化，只要有这个变化的需要。</p>
<p>上面这段话看起来似乎比较抽象，感觉自己越来越像整理设计模式的那四人帮里的那几个人了，哈哈，开玩笑的。所以，我们通过CS的这种权限控制机制可以看出当初他们的设计者的脑子里一定已经有上面我说的那种模型了，不然我想他们肯定是不会那样去控制权限的，你说呢！</p>
<p>好了，从他们的这个设计中，我们以后做设计应该注意些什么呢？我觉得有很多是还需要我们加强和提高的。当我们要解决一个问题的时候，我认为如果时间允许，则一定要多考虑考虑灵活性、可扩展性，不能为了光解决这个问题而去思考，我们应该想的更远，思考的更加周到。我看到一些人在设计权限的时候往往都是设置一个标志位，如0代表一般用户、1代表管理员、2代表系统管理员，然后实现权限判断的逻辑通常是这样的，如果当前用户是0，则怎么怎么样，如果是1，则怎么怎么样，如果是2，则怎么怎么样，这些判断逻辑往往都是在代码里面写死的。这样做虽然可以解决当时的问题，但是如果我现在要求有一个人不是系统管理员，但是又同时可以做0、1两个人的事，那该怎么办呢，我想按照这样的设计是实现不了了。除非你去修改代码。</p>
<p>最后，我希望我们中国所有的开发和设计人员，在工作和学习的过程中，能够经常去想想别人优秀设计的背后是什么，一旦你都知道了这些背后的东西，那我相信有一天你也一定可以做出老外非常感叹的设计了，难道这个不是你也想的吗？呵呵！</p>
<p>好了，写了差不多一个小时，该结束了，明天双休日，好好玩玩，晚安。</p>
<img src ="http://www.cnblogs.com/netfocus/aggbug/1031456.html?type=2" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43772/" target="_blank">[新闻]Digg创始人：不再考虑出售公司 将适机并购</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>CommunityServer中分类的实现的新的理解</title><link>http://www.cnblogs.com/netfocus/articles/1031443.html</link><dc:creator>netfocus</dc:creator><author>netfocus</author><pubDate>Wed, 09 Jan 2008 02:27:00 GMT</pubDate><guid>http://www.cnblogs.com/netfocus/articles/1031443.html</guid><wfw:comment>http://www.cnblogs.com/netfocus/comments/1031443.html</wfw:comment><comments>http://www.cnblogs.com/netfocus/articles/1031443.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/netfocus/comments/commentRss/1031443.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/netfocus/services/trackbacks/1031443.html</trackback:ping><description><![CDATA[<div class="body">
<p>半夜2点，和朋友打完牌回来，洗好衣服，打开电脑，习惯性的打开我的个人网站的Solution。由于觉得以前关于一些类别的实现有些不太好，所以思考如何更好的实现类别管理。</p>
<p>以我的个人网站为例，文章和相册这两个模块都有类别管理，以前是通过Section表来存放类别的，即一个类别对应一个Section。后来发现，虽然这样做可以实现目前的功能，但是不太好，或者说没有真正利用CS里面的类别管理功能，比如如果我删除了一个Section，那么这个Section下的所有的Post也会删除，但实际上我们可能并不希望这样，就像博客种的日志分类，当我删除了某个日志分类之后，该日志分类下的所有日志还是在的，只不过被自动转移到了&#8220;所有分类&#8221;中。</p>
<p>在CS里，在同一个Section下，可以进行类别的管理，通过cs_Post_Categories表实现。比如某个人的相册中可以添加和修改影集，每个影集就是一个类别，这些类别都是在同一个Section下的；再比如，某个人的博客里，会有很多日志，日志有日志分类，一个日志分类就是一个类别，这些类别也都是再同一个Section下；经过我观察，发现现在所有的门户网站的博客中，需要管理的内容中只有一样东西是需要区分类别的，那就是日志，其他的比如照片、收藏、好友、音乐、留言、关键字等都是不需要类别；如果是这样功能的博客，那目前的CS系统也可以实现了。我们可以这样来设计，一个人的博客对应一个Section，日志、照片、音乐、留言等都只是这个Section下的不同类型的Post而已，而因为只有日志需要区分类别，所以可以在这个Section下添加一个类别，这些类别用于对日志进行分类。这样就可以实现目前大部分门户网站中的博客功能了。但是，如果有一个博客，它里面有不止一样东西需要通过类别来管理，比如日志分类、照片分类、收藏分类，那该怎么办呢？如果还是按照前面的方式来设计，由于所有这些分类都是存放在同一个Section下面，那应该怎么来区分这个类别是日志分类还是照片分类还是收藏分类呢？针对这个问题，我看了一下CS的表结构，发现同一个Section下的所有分类是不能分组的，即不可能知道这个分类是哪种分类，所以我觉得如果不增加字段是不可能实现我刚才说的那种功能了。</p>
<p>后来我继续研究了一下CS的功能，发现它的博客中，就只有随笔是需要分的，而对于另外一个需要分类的相册，又作为一个单独的CS应用程序设计，命名为&#8220;相册&#8221;，对单个人而言，就是我的博客，我的相册。通过这样的方式，的确可以实现随笔分类和照片分类的分开管理，因为他们属于不同的应用程序，也就属于不同的Section。</p>
<p>&nbsp;现在开始想回来，我现在的这个个人网站，有个人介绍、站内通知、随笔、文章、相册、作品、留言这些实体。其实在极端情况下，这每个实体都是可以分类的，只要有这个需要，但实际上可能只需要文章、相册这两个实体需要分类，最多加个作品分类。因为这个是个人网站，相当于是一个博客，所以如果按照CS的架构来设计，应该把上面提到的所有实体都和同一个Section进行关联，但是就像前面提到的，对于有两个或以上的实体都需要分类的时候就不能实现了。那该怎么办呢？难道真的也要像CS那样做，就是：文章作为一个应用程序、相册作为一个应用程序、作品作为一个应用程序，并且因为不能确保其他实体以后就一定不会分类，所以也要把所有其他的实体也都作为一个应用程序管理，这样的话，我的个人网站不是成了有多少个实体，就需要建立多少种应用程序了。这样做确实是可以实现每个实体都需要分类的情况，但是不是有这个必要呢？这样做有什么好处和坏处呢？</p>
<p>我想至少有两个好处：</p>
<p>1）如果对于每个实体都通过一个应用程序来管理，那么对于这个实体来说，它可以发挥的余地大多了，该应用程序可以围绕该实体设计任意功能。比如最小的实体的应用程序就是GuestBook（留言本），对应的实体就是留言；相对复杂点的实体的应用程序就是产品网上销售系统，对应的实体就是产品；中等复杂点的实体的应用程序就是博客，对应的实体就是日志（随笔）；</p>
<p>2）一旦围绕某个实体的应用程序设计并实现了，那这个应用程序相当于是一个独立的模块，以后不需要做大的修改就可以直接拿过来用。比如这次我做了一个文章发布系统CS应用程序，那下次如果我在某个站点种也需要包括一个文章发布系统的，那只要直接把这个应用程序的整个工程文件拿过去编译即可。这样就可以达到极大的代码重用；虽然我们在第一次为了实现某个应用时花了较多的时间，但和后期的重用比起来还是值得的我想。</p>
<p>我可以想到的缺点如下：</p>
<p>1）当一个站点中有10种完全不相关的实体时，就必须建立10中不同类型的CS应用程序，除非你确定这10种不相关的实体种有几种实体是肯定不需要分类的而且可以和其他类别进行合并，那么你可以少建立几个CS应用程序。这样做肯定会给开发带来更多的成本；</p>
<p>2）是否真的有必要这样做，是不是可以考虑修改目前CS的表的结构，让它同一个Section下支持分类的分组；这个问题我现在暂时先不去研究，时间有限，而且如果表一个，对应的很多存储过程也要修改，这样可能会影响上层的很多功能。等到时间充裕的时候，我相信我们完全可以设计出比目前CS更优秀更抽象的数据库。</p>
</div>
<img src ="http://www.cnblogs.com/netfocus/aggbug/1031443.html?type=2" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43772/" target="_blank">[新闻]Digg创始人：不再考虑出售公司 将适机并购</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>CommunityServer2.1中四张抽象表的理解</title><link>http://www.cnblogs.com/netfocus/articles/1031376.html</link><dc:creator>netfocus</dc:creator><author>netfocus</author><pubDate>Wed, 09 Jan 2008 02:02:00 GMT</pubDate><guid>http://www.cnblogs.com/netfocus/articles/1031376.html</guid><wfw:comment>http://www.cnblogs.com/netfocus/comments/1031376.html</wfw:comment><comments>http://www.cnblogs.com/netfocus/articles/1031376.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/netfocus/comments/commentRss/1031376.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/netfocus/services/trackbacks/1031376.html</trackback:ping><description><![CDATA[<div class="body">
<p>终于有机会可以坐下来写写设计思想类的文章了，最近一直在研究CommunityServer（以下简称CS），对某一样东西接触多了总会有一些感受，所以想写下来和大家分享：）。另外，补充一句，由于这篇文章偏重的是设计想象，所以希望各位看官能耐心点，尤其是后面部分，如果看了之后感觉在浪费时间，那看都看了，下次就不要再来看了，呵呵。</p>
<p>&nbsp;自从CS出来以后，外界已经有很多人都在对CS进行学习和研究。我看到有很多网站直接拿CS作为自己的社区管理系统，但是我发现真正从核心级别研究CS的人不多，很多都只停留在表面，所以不能充分利用它的设计思想及源代码。下面我说一下我在学习CS过程中的一些感受和体会：</p>
<p>1． 一个好的系统需要有一个抽象的可扩展的核心；</p>
<p>假设D依赖于C，C依赖于B，B又依赖于A。好，在这种情况下，如果A、B、C、D</p>
<p>是一个软件中的必要组成部分，那么，我认为应该让A设计的最好、最抽象，其次是B、C、D。因为如果你把A设计的抽象而又有扩展性，那就可以在她基础上生出一个很优秀的B，因为B可以不受约束的表现出任意形态，同理C、D也是一个道理。对于CS系统，A对应的是数据库中的几张抽象的表（Groups、Sections、Posts、Threads），B对应的是Components项目中的几个抽象的类（Group、Post、Thread、Section），C对应的是整个系统中某个子系统（如论坛、相册等）。关于这四张表设计的如何抽象如何优秀，网上已经有很多这方面的资料了，比较有名的有宝玉的一些文章。我在这里也冒昧谈一下我的理解。</p>
<p>Group：代表了现实生活中的一些实体所属的大类。</p>
<p>Section：代表了现实生活中一些实体所属的从第二层类开始的所有小类（可以嵌套）。</p>
<p>Post：代表了现实生活中一些实体，可以嵌套。</p>
<p>Thread：不代表现实生活中的任何实体，是一个纯粹抽象的概念，是对相关Post的统计。</p>
<p>它们之间的关系如下：</p>
<p>通过一个可以唯一标识Group的东西，比如GroupID可以获取所有的Section，类似的通过一个SectionID可以获得所有的Post，通过一个ThreadID可以获得所有相关的Post，通过一个PostID可以获得所有的子Post。</p>
<p>好，将上面提到的几个概念进行组合，我们可以很方便的构建出一些日常生活中经常接触的系统。先说一下通过这四个概念可以做什么事情：</p>
<p>我们有时候经常需要对现实生活中的实体进行归类，而且复杂的时候往往类别都是嵌套的。另外我们有时候往往会对某个问题进行讨论或共享或公布，如在CSDN上发起一个帖子，后面的人对这个帖子进行讨论；或者网易的新闻发布员在网站上发布了一条新闻，很多人过来阅读并进行评论；或者亚马逊网站的网站维护相关人员上架了某个商品，很多人购买并发表评论；或者阿里巴巴系统中的某个会员（即公司）新上架了某个最新产品，其他会员查看其特点并可能会寻盘以了解该产品的详细信息。再或者你给某个留言板管理员留了言之后他对你的留言进行回复；等等。</p>
<p>所有上面提到的例子其实都可以用上面所说的这四个概念或其中某几个概念来实现。</p>
<p>以下举例说明：</p>
<p>1） 论坛系统</p>
<p>论坛主要由版块组、版块（一个版块可能还有子版块）、帖子、帖子的回复这四种概念组成；所以，很明显，我们可以用Group表示版块组、Section表示版块、Post表示一个帖子或回复、Thread存放了某些相关子帖子的所有统计信息。</p>
<p>2） 博客系统</p>
<p>一个典型的博克系统由博客分组、某个人的博客、某个人博客中的一篇随笔或日志、随笔或日志的评论或引用；所以，我们也可以像论坛那样用Group表示博客分组、Section表示某个人的博客、Post表示一篇随笔或日志或其评论、Thread存放了一篇随笔及其所有评论的统计信息。</p>
<p>3） BToB系统</p>
<p>一个BToB系统其实是一个企业交流的平台，它往往有很多会员（公司）、每个会员可以发布自己的介绍信息、产品、供应信息、求购信息、新闻通告、招聘信息等。产品，供应信息，求购信息，新闻等内容一般都属于某个具体的类别，而且该类别往往还属于一个更大的类别。我们可以用Group存放一些最大的类别，Section存放除最大类之外的所有子类别，Post存放产品、供应信息、求购信息、新闻等，Thread存放一些统计信息。另外，一个公司的产品不仅属于某个产品类别，还可能属于某个公司自己管理的产品系列，这中情况其实是很常见的，比如有一本书《.Net 框架程序设计C＃版》，它最"正统"的类别是C＃类图书，但是呢，它又同时是黑皮书系列。所以，用抽象的思维来理解就是，一个实体从不同的角度去理解，它就是不同的东西，也就是说属于不同的类别。好，那么我们该把产品的系列如何看待如何存放呢？看了CS，我发现它还有一张cs_Post_Categories表，还有一张cs_Posts_InCategories表，我到目前为止还没有去细看它的用处，但是从这两张表的结构来看，应该可以满足刚才我说的情况。我们可以把产品的系列放在cs_Post_Categories表中，然后用cs_Posts_InCategories这张表来建立产品和产品系列的关系。那么，我们是否可以把产品系列也放在Post表中呢？我觉得是可以的，因为产品系列在这种情况下也可以理解为一个实体，并且这个实体和多个产品实体相关。所以，我们可以把产品系列也放在Post表中，然后像管理产品那样对其进行管理。那么，我们该如何为产品和产品系列建立关系呢？有一个办法可以做到，就是利用目前CS系统中的扩展属性ExtendedAttribute，我们为某个产品实体添加一个扩展属性，比如叫SerialID，该属性和SectionID属性的作用一致。但是问题是SectionID在数据库中有一个明确的字段，所以可以直接作为条件进行SQL查询，而SerialID在数据库中并不存在一个与之对应的字段，那我们就不能直接通过SQL语句查询出某个产品系列的产品了。这的确是一个问题，从更抽象的角度来看，只要是通过ExtendedAttribute的方式新增的字段都不能作为SQL查询条件进行查询。我们如果要得到期望的结果，只能先将没有过滤过的产品都查询出来，然后在内存中人工对其进行过滤以返回正确的结果。所以，结论就是，通过像CS新建表的方式，可以实现这种情况，而且查询起来也比较方便，效率高，但是，目前表中的字段似乎设计的还有点问题，因为CategoryID是和某个SectionID关联的，而不是和一个更抽象的字段关联，CS的设计人员可能仅仅考虑到了某个实体一定属于某个Section的情况，而没有考虑到一个产品不属于任何一个Section的情况；通过扩展属性的方式，虽然可扩展性比较好，但是由于数据库中没有可以直接利用的字段，所以查询起来比较困难。这两种方法，都可以尝试一下。</p>
<p>4） 电子商务系统</p>
<p>一个电子商务系统的前台部分主要由商品类别、商品、商品的评论、购物车、订单系统组成。对于商品类别、商品、商品的评论直接可以套用上面的四个概念，对于购物车，因为一般购物车中的内容都是临时的，所以不宜存放在Post表中，可以按照一般实现购物车的方式来实现，比如通过为每个用户创建一个Session、Cookie、一张临时表中的某几条商品记录，等。对于订单，一旦用户下了某个订单，就应该把这个订单及其明细信息存放到某个物理位置，如数据库，XML文档。所以，我们也可以考虑将订单及其明细信息存放在Post表，把明细信息看作是订单主记录的一些回复或评论。也许你可能会想订单又没有类别，那以后该如何去访问某个人的某张订单的信息及其明细信息呢？我觉得可以这样理解：如果一张订单有4件商品，那么在数据库Post表中存5条记录，第一条记录存放订单记录本身，另外4条存放明细信息，这5条记录的ApplicationPostType（这个字段表示某个子系统中某种类型的实体）应该设置为相同，然后将后面4条记录的ParentID设置为第一条记录的PostID，通过这样的方式，我们就可以存储一张订单了，并且也已经建立了订单信息及其明细信息的关系；这样，如果我们现在要找某个人的所有订单，则可以将ApplicationType、UserID、ApplicationPostType作为参数进行查询，即可获得所有订单信息及它们的明细信息，获得原始数据之后上层可以用面向对象的类来进一步组织这些信息，比如你可以设计两个Order、OrderDetail类来存放订单和订单明细信息，以方便上层访问。如果我们仅仅只要获得某个人的订单列表，不需要获取订单的明细，则只要将 ApplicationType、UserID、ApplicationPostType、ParentID为空这四个条件作为参数查询，返回的所有Post就是所有的订单了，不包括订单明细。最后，如果要获取某个人某个订单的信息，则只要将PostID作为参数，再用一些SQL技巧就可以获取这个订单的所有相关记录了。</p>
<p>5） 信息发布系统</p>
<p>信息发布系统就相对简单了，一般的信息发布系统都只有一层类别，则给予这样的情况，我们就没有必要使用Group，因为Group只有在至少有两层类别的情况下才用的着。我们可以将一个信息类别看作是一个Section，一个信息看做是一个Post。当我们要查找信息发布系统中的所有的Section时，直接将ApplicationType作为参数进行查询即可。另外，如果要获取某个信息类别下的所有的信息，则只要将某个SectionID传入即可。最后，关于信息的评论就不多说了，和上面的系统类似。信息发布系统这样应该就可以存放所有主要内容了。</p>
<p>6） 留言系统</p>
<p>这个是最简单的例子了，因为一般一个留言板中的留言没有大类，也没有小类，只有留言和回复（可能一条留言有多个回复）两种信息。那么这种情况该如何处理呢？其实很简单：从现实的角度出发，我们肯定不需要用到Group、Section这两个概念，应该只需要用到Post这一个概念即可。即我们可以把所有的留言及其它们的回复都放在Post表中，当我要查询所有的留言时，只要将ApplicationType、ApplicationPostType，PostID为空这三个参数就可以获取了，要查询某条具体留言及其回复则只要传入PostID即可。</p>
<p>2． 让我们来想想为什么人家会想到那样去设计；【注：上面的可以不看，但下面的一定要看哦！】</p>
<p>有很多人可能很少像我这样提这个问题，其实，这个问题非常重要，我到现在为止还不知道这个问题的答案，如果我知道，那我的水平就和CS的核心架构师的水准差不多了，你说呢？呵呵：）但是，我认为，我们从他们的设计结果里面可以体会出一些他们当初设计这四个概念时的思维场景。下面是我可以想象到的思维模拟过程：</p>
<p>我现在要做什么？</p>
<p>一个社区系统。</p>
<p>我想做到什么样的程度？</p>
<p>最好是可扩展性很好的那种，很帅的那种，以后维护很方便的那种。</p>
<p>我要不要对每一个实体都建一张表？</p>
<p>肯定不想这样，不然以后工作量不是很大。</p>
<p>那如果不建表该怎么表示所有可能出现的不同的信息呢？</p>
<p>我需要再思考，但是我坚信一定会有结果的。</p>
<p>和女朋友吃完饭回来后，开始思考的过程（请各位看管不要闲罗唆，呵呵）：</p>
<p>我现在要想一种解决方案，通过这个解决方案我可以轻松的扩展我的Web系统。根据我以往的经验，要知道两样东西的关系必须要先知道这两样是什么东西，要知道这两样是什么东西必须先明确这两样东西的数据结构，要知道这两样东西的数据结构需要深度分析这两样东西在现实生活中体现出来的特征。但问题是我现在面对的东西似乎太多，比如有书本，有留言，有回复，有电影，有新闻，等等等等。那该怎么办呢？什么怎么办，都想到这里了当然还要想下去的了！对了，老师好像曾经教过我，白熊和黑熊都是熊，也就是说它们都属于熊类，但是老师好像没有教过我所有上面这些东西都是什么。嗯，那我该怎么办呢，我想这个一定是老师可能也不知道的，或者没去思考过的，或者他认为这些根本就是完全不相干的东西。那如果我想出来了不是比老师更厉害？呵呵，是的！我一定要多想想，反正还有时间，技术总监给我很多的时间去思考设计的，没坏处！再回忆一下，我的目标是什么？是用某种抽象的东西来尽可能表示现实生活中多的东西，如上面想到的那些。因为只有这样我才可以在以后用一样的代码，一样的逻辑去处理所有这些现实生活中的东西以及它们的关系，哇，好像难度很大，估计老师们肯定不会这样去思考的，因为他们只会把一些看上去最正统的理论的教给学生，最离谱的最难以理解的可能就作为星号章节留作学生自学或作为思考题了。唉，对了，以前好像某个人对我说起过，任何事情如果你可以想出解决方案，就说明它的某种特征或规律被你发现了，然后你找到了一种方案可以符合这件事情的特征和发展规律，并且可以按照它的发展方向控制它，拥有它。我学过数学，记得小学时常有这样的题目，有100、120、160、200四个数字，要求它们最大的公约数，我很容易就可以答出来，看看就知道，就是20嘛！那么我那个时候究竟是怎么答出来的呢？好像有些记不大得了，可能是猜的，也可能是用超快的正统的逻辑推理计算出来的，也可能是条件反射没经过大脑得那种，也可能是老天告诉我的，呵呵。不管怎么答出来的，在我现在看来，通过逻辑推理就可以找出答案。即找出每个数的所有可以被整除的数，然后取这些数中最大的公有的那个即可。嗯，我是否可以从这个例子里面得到些有意义有价值的参考信息呢？让我再想想，唉，好像有了，如果那是我是用逻辑推理得出答案得，那么我那个时候的思维肯定分为两个过程：1）理解了最大公约数的含义；2）找到了一个可以求最大公约数的方法。这个思维过程从更抽象的角度出发，是不是可以理解为：要解决一个问题，需要先知道这个问题的特征及规律是什么，然后在符合它特征和规律的基础上施加各种外在的因素去合理的利用它，然后把利用后的好处作为我们自己的财富。那我现在也用这种理论去研究一下刚才我遇到的问题试试吧！要将一个Web站点中常出现的所有主要的实体抽象为一样或几样典型的东西，通过刚才想那个最大公约数的问题，再回过头来想这个问题好像不是那么没有立足点了，似乎也是和求最大公约数差不多耶！首先，如果是一个论坛的帖子，那么有标题、内容、回复集合，发帖时间，发帖人，是否置顶等；如果是相册中的一张照片，那么有标题，描述，评论集合，照片地址，点击查看次数等；如果是一样商品，那么有名称、详细信息、规格、价格、评论集合、上架时间、厂家信息、库存数量等；把所有这些东西都列出来，在用人类独特的观察事物总结抽象能力，就可以找出很多共同的特征。我暂时就把这个特征命名为Post吧，这个名称是什么不重要，因为它只代表了一个概念的载体。总结后，发现这个Post应该有名称、描述、诞生时间、被关心次数、可以归为的正统的一个类别、它的创造者、它的本质类别、由它而引发出来的所有相关信息、其他任意多的额外特性。嗯，暂时好像只能考虑到这些了。哇，真开心，一下子找出这么多的"公约数"，估计以后一定发了，呵呵。不过，现在离革命成功还早，我要继续思考。不过今天不早了，我要先休息，补充点脑细胞，明天再想，待续。。。。。。</p>
<p>3． 我们怎样做才能接近这个目标；</p>
<p>待续。。。。。。</p>
</div>
<img src ="http://www.cnblogs.com/netfocus/aggbug/1031376.html?type=2" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43772/" target="_blank">[新闻]Digg创始人：不再考虑出售公司 将适机并购</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>数据结构动画演示系统－用户界面（GUI）子系统分析</title><link>http://www.cnblogs.com/netfocus/articles/344411.html</link><dc:creator>netfocus</dc:creator><author>netfocus</author><pubDate>Tue, 07 Mar 2006 01:11:00 GMT</pubDate><guid>http://www.cnblogs.com/netfocus/articles/344411.html</guid><wfw:comment>http://www.cnblogs.com/netfocus/comments/344411.html</wfw:comment><comments>http://www.cnblogs.com/netfocus/articles/344411.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/netfocus/comments/commentRss/344411.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/netfocus/services/trackbacks/344411.html</trackback:ping><description><![CDATA[<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">本文介绍我的系统中用户界面是如何生成和管理的。</SPAN><SPAN lang=EN-US>DataStructure</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">使用</SPAN><SPAN lang=EN-US>MVC</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">（</SPAN><SPAN lang=EN-US>model-view-controller</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">，模型</SPAN><SPAN lang=EN-US>-</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">视图</SPAN><SPAN lang=EN-US>-</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">控制器）设计模式。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>1</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">．下面介绍一下</SPAN><SPAN lang=EN-US>MVC</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">模式中的各个组成部分。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">视图：</SPAN><SPAN lang=EN-US><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">视图是用户看到并与之交互的界面。对老式的</SPAN><SPAN lang=EN-US>Web</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">应用程序来说，视图就是由</SPAN><SPAN lang=EN-US>HTML</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">元素组成的界面，在新式的</SPAN><SPAN lang=EN-US>Web</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">应用程序中，</SPAN><SPAN lang=EN-US>HTML</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">依旧在视图中扮演着重要的角色，但一些新的技术已层出不穷，它们包括</SPAN><SPAN lang=EN-US>Macromedia</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">　</SPAN><SPAN lang=EN-US>Flash</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">和象</SPAN><SPAN lang=EN-US><A href="http://www.zdnet.com.cn/developer/tech/story/0,2000081602,20036353,00.htm" target=_blank><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体"><FONT color=#000000>XHTML</FONT></SPAN></A></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">，</SPAN><SPAN lang=EN-US><A href="http://www.zdnet.com.cn/developer/tech/story/0,2000081602,39030849,00.htm" target=_blank><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体"><FONT color=#000000>XML/XSL</FONT></SPAN></A></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">，</SPAN><SPAN lang=EN-US><A href="http://www.zdnet.com.cn/developer/tech/story/0,2000081602,39048901,00.htm" target=_blank><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体"><FONT color=#000000>WML</FONT></SPAN></A></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">等一些标识语言和</SPAN><SPAN lang=EN-US>Web</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">　</SPAN><SPAN lang=EN-US>services</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">。如何处理应用程序的界面变得越来越有挑战性。</SPAN><SPAN lang=EN-US>MVC</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">一个大的好处是它能为你的应用程序处理很多不同的视图。在视图中其实没有真正的处理发生，不管这些数据是联机存储的还是一个雇员列表，作为视图来讲，它只是作为一种输出数据并允许用户操纵的方式。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">模型：</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">模型表示企业数据和业务规则。在</SPAN><SPAN lang=EN-US>MVC</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">的三个部件中，模型拥有最多的处理任务。例如它可能用象</SPAN><SPAN lang=EN-US>EJBs</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US>ColdFusion</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">　</SPAN><SPAN lang=EN-US>Components</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">这样的构件对象来处理数据库。被模型返回的数据是中立的，就是说模型与数据格式无关，这样一个模型能为多个视图提供数据。由于应用于模型的代码只需写一次就可以被多个视图重用，所以减少了代码的重复性。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">控制器：</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">控制器从视图接受用户的输入并调用模型去完成用户的需求。所以当单击</SPAN><SPAN lang=EN-US>Web</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">页面中的超链接和发送</SPAN><SPAN lang=EN-US>HTML</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">表单时，控制器本身不输出任何东西和做任何处理。它只是接收请求并决定调用哪个模型构件去处理请求，然后用确定用哪个视图来显示模型处理返回的数据。现在我总结Ｍ</SPAN><SPAN lang=EN-US>VC</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">的处理过程，首先控制器接收用户的请求，并决定应该调用哪个模型来进行处理，然后模型用业务逻辑来处理用户的请求并返回数据，最后控制器用相应的视图格式化模型返回的数据，并通过表示层呈现给用户。</SPAN></P>
<P><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-language: ZH-CN; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-bidi-language: AR-SA">2</SPAN><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">．上面大致介绍了比较通用的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-language: ZH-CN; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-bidi-language: AR-SA">MVC</SPAN><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">模式中各个模块的功能和联系，下面我介绍一下</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-language: ZH-CN; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-bidi-language: AR-SA">MVC</SPAN><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">模式是如何应用在</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-language: ZH-CN; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-bidi-language: AR-SA">DataStructure</SPAN><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'">中的。首先来看一个比较抽象总体交互图。</SPAN></P>
<P align=center><SPAN style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-fareast-language: ZH-CN; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-bidi-language: AR-SA; mso-bidi-font-family: 'Times New Roman'"></SPAN><IMG src="http://www.netfocus.cn/images/projectImages/GUI-MVCModel.bmp"></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">说明：</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">上图中视图和面板等</SPAN><SPAN lang=EN-US>GUI</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">就是</SPAN><SPAN lang=EN-US>MVC</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">模式中的视图，工作台代表控制器，布局管理器代表模型。不过视图和面板已经被抽象化，也就是说它们并不是直接以某种可视控件的形式供其它对象使用，而是以接口的形式来向外界提供可视化元素。工作台表示控制器，工作台并不知道如何在屏幕上显示视图或面板。工作台并不关心视图或面板的显示方式，真正显示视图或面板的逻辑驻留于布局管理器中。正如</SPAN><SPAN lang=EN-US>MVC</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">模式中所定义的那样，控制器从某个视图接受用户的输入并调用某个模型去完成用户的需求。布局管理器处理</SPAN><SPAN lang=EN-US>GUI</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">逻辑，负责处理</SPAN><SPAN lang=EN-US>GUI</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">元素的显示方式。在当前的</SPAN><SPAN lang=EN-US>DataStructure</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">中，工作台和布局管理器都只有一种，即单文档界面（以选项卡的形式显示文档）。在</SPAN><SPAN lang=EN-US>DataStructure</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">中典型的</SPAN><SPAN lang=EN-US>GUI</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">元素（即</SPAN><SPAN lang=EN-US>MVC</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">中的视图）有面板、视图、菜单、工具条、状态栏，下面我详细介绍一下其中几种元素。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">视图（</SPAN><SPAN lang=EN-US>ViewContent</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">）：</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">在</SPAN><SPAN lang=EN-US>DataStructure</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">中，所有视图都实现了一个接口（</SPAN><SPAN lang=EN-US>IViewContent</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">），该接口定义了所有具体视图必须要实现的操作。当前有两种类型的具体视图：文本编辑器视图和网页浏览器视图。因为所有的具体视图都实现了接口所规定的操作，所以当外界要调用某个视图所提供的功能时，只要引用</SPAN><SPAN lang=EN-US>IViewContent</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">接口即可，而无需指定具体的视图的类型。视图在一个应用中能够被打开多个。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">面板（</SPAN><SPAN lang=EN-US>PadContent</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">）：</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">和视图一样，系统中所有的面板都实现了一个接口：</SPAN><SPAN lang=EN-US>IPadContent</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">，该接口的主要作用是抽象一种能提供某种特定功能的控件。面板是一种工具窗口，与视图最大的区别是一种面板在一个应用中只能被打开一个，并且不能被关闭，只能隐藏。面板一般用于显示一些辅助信息。在</SPAN><SPAN lang=EN-US>DataStructure</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">中当前有文件浏览面板、动画面板、属性面板、帮助文件浏览面板。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><B style="mso-bidi-font-weight: normal"><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">菜单和工具栏：</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></B></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">这两种</SP