前阵子实验室接到一个门户网站的单子.我有幸参考其中,并负责其中所有有关新闻发布的代码.本来以前自己也作过有关新闻发布的例子(客户也没有对使用的开发框架作限制),由于正在看有关SSH(spring,hibernate,struts),就想拿这个模块来练手.经过几天的捣鼓,程序算是完成了.特分享一下设计经验.
由于客户并没有提供相关更多的材料,完全是自我发挥,所以可以用的空间很大,也产生了要把模块弄得很好的愿望.所以设计方面也是有些考虑.采用spring2.0 hibernate3,和最新的struts2.0作为开发框架.(相关源代码可参考本人发在csdn上的链接download.csdn.net/source/235683 ).
模型设计:
新闻发布系统主要涉及新闻,类别.此外,新闻发布用户也是需要被考虑的问题.在实际中,由于考虑到一个新闻置顶方面的问题,特特殊设计了一个关于新闻置顶的类.因此,整个domain分成四个部分:文章(article),目录(category),文章置顶对象(articleTopType)以及用户对象(user).具体设计如下:
#-------------------------
文章(article):
- public class Article implements Serializable {
-
- private int id;
-
-
- private String title;
-
-
-
-
-
- private String pathMark;
-
-
- private boolean audited;
-
-
- private String titleColor = ProjectConfigureGlobals.ARTICLE_DEFAULT_TITLECOLOR;
-
-
- private String summary;
-
-
- private String source;
-
-
- private Date createDate;
-
-
- private Date modifyDate;
-
-
- private String ip;
-
-
- private int hits = 1;
-
-
- private String content;
-
-
- private int pageCount = 1;
-
-
- private int pageCurrentIndex = 1;
-
-
-
-
-
- private boolean firstDeleted = false;
-
-
-
-
-
- private boolean shiftDeleted = false;
-
-
- private ArticleTopType articleTopType;
-
-
- private User createUser;
-
-
- private User editUser;
-
-
- private Category category;
-
-
- private String categoryChain;
-
-
- private String tags;
这里有几个问题
1,文章是否应从数据库中彻底删除
2,文章删除后是否可以被恢复
3,对于多页文章的处理(如一篇文章分成多个页面显示)
4,对于级联目录下的文章的查找(即如windows资源管理器,在一个目录下搜索此目录及所有子目录下的文章)
对于问题1,2,我设计了一个删除firstDeleted字段和一个彻底删除shiftDeleted字段,当shiftDeleted为true时,表示此文章此被彻底删除,否则当fistDeleted为true时,表示一般删除,(此类删除在管理者页面可被查出,不过有相关标志提示,并且可以管理者页面被恢复).当firstDeleted和shiftDeleted同时为false时,表示此文章是正常文章.
对于问题4,我设计了一个categoryChain的字段,此字段保存此文章的路径信息,此路径信息由文章所在当前目录者提供,第一个目录对应一个惟一的路径信息,并且同时保留了其上下目录的级联信息.此字段的get方法被改成由目录提供,因此如果目录被删除,此文章的路径信息为null,即视为无类别文章.相应get方法如下:
- public String getCategoryChain() {
- return category == null ? null : category.getCategoryChain();
- }
对于问题3,我设计了文章的页码并保存在文章属性中,由pageCount和pageCurrentIndex两个属性来完成.pageCount保存此篇文章的总页数,而pageCurrentIndex保存此篇文章当前显示的页数.并且由这两个属性来进行上一页,下一页的判断.这样,当文章被用于多页显示时,每个文章对象仅保留此页的数据,当读取下一页时,再从数据库中读取文章下一页的数据.
#---------------------------
文章类别(category)
java 代码
- public class Category implements Serializable {
-
- private int id;
-
- private String name;
-
- private String description;
-
- private Date createDate;
-
- @Fly_m
- private User user;
-
- @Fly_m
- private List<category></category> categoryList;
-
- @Fly_m
- private List<article></article> articleList;
-
- @Fly_m
- private Category superCategory;
-
-
-
-
-
- private String categoryChain;
正如代码所示,类别被设计为无限级联的,并且每一级有它的上一级和它的子级目录.且每一级都可有相应级类别的文章.想要找到某一级目录下的所有文章,通常作法是对子目录的递归.不过,我作了一个小小的偷懒,即利用categoryChain文章路径,信息这一属性来登记每个目录的详细路径,再将这一路径导向该目录下文章的categoryChain属性.再由article类,可知,article的categoryChain属性由该文章的目录决定,因此,如何处理目录的categoryChain就很重要了.此处利用了数据库本身的特点like语句.详细代码如下所示:
java 代码
- public String getCategoryChain() {
- return categoryChain == null ? (superCategory == null ? new SimpleDateFormat("MMddHHmmssSSS-", Locale.CHINA)
- .format(new Date()) : (superCategory.getCategoryChain() == null ? "" : superCategory
- .getCategoryChain()) + new SimpleDateFormat("SSS",Locale.CHINA).format(new Date()) + "-") : categoryChain;
- }
每一级目录的categoryChain被设计为父目录链,因为顶级目录root目录被设计为时间相关,再加上子级目录被设计为毫秒相关(相同目录下,在同一毫秒内创建不同目录这一可能性很小吧,这里的毫秒相关可能需要被改写),因此,保证了每一目录有惟一的路径信息.
#-------------------
文章置顶对象(articleTopType)
java 代码
- public class ArticleTopType {
-
-
- private int id;
-
-
- private String description;
-
-
- private Date startDate;
-
-
- private Date endDate;
-
- private Article article;
文章置顶只是简单的作了时间相关(关于文章置顶有许多方面的考虑,如何置顶,在哪儿置顶,或者置顶颜色,置顶级别等).由于模块不要求太复杂,仅作了时间置顶,在时间内置顶,超出时间则置顶消失.
#----------------
文章用户对象(user)
java 代码
- public class User implements Serializable {
-
- private static final long serialVersionUID = -4937427658808092834L;
- private int id;
- private String name;
- private String password;
- @Fly_m
- private List<article></article> articleList;
- @Fly_m
- private List<category></category> categoryList;
这个用户对象,只是保存了用户基本信息( 在后期,此对象可能会被其他模块改写,但不影响此处的结构工作).
#------------------------------------
模型设计中,重点是目录和文章对象的设计,我觉得主要是需求的复杂性决定了对象复杂性的设计.对于小型系统,一个文章对象可能就是简单的内容+标题+类别,而在一些大型的系统,需要考虑的因素就多了.这决定于系统分析师的分析能力,在不断的实践于,自己也对分析方面有了很大的进步.而模型设计,直接关系于系统的数据存储和以后相关层的设计以及以后系统的扩展能力.在这方面要多下功夫啊.
附件中是相关域模型的源代码,及hibernate的源代码注释(我把以前基于xml的配置搬到了源代码里面,使相关配置更加简单明了).
欢迎大家指点,我会改进的
下一篇把dao这层以及service这一层写上来.