java设计模式----综合案例(一) weir 2015-06-09 09:04:52.0 java,设计模式 1825 我们想分析一下我们要吧这个通用的代码生成工具做成什么样子的c/s 还是 b/s,如果要我决策我会选择b/s形式,这算是一个问题。 还有我们设计的实体是连接数据库还是不连接数据库,也就是说是先有数据库还是现有程序,这两种情况都有可能,有的项目可能是二次开发,那数据库当然就已经存在了,如果已经有数据库了那实体就不需要什么模板然后再需要生成了,我们用框架直接可以生成实体的。这一步就算解决了。所以我们的代码生成器不需要去连接数据库,有人就说了,我们可以一站式的把数据库表也生成了,我觉得没这个必要,之前我们也分析过有些框架已经实现了正向和反向的操作数据库,那么我们生成完实体就可以了,没必要再去可数据库打交道,把这个活交给框架做好了,不要抢别人的活干。所以我们这个代码生成工具就可以独立起来使用了,不受任何结束。 下面的重点就是我们该如何设计这个模板了,我们需要生成不同层次的模板该如何组织这些模板呢?每个模板肯定都是一个文件来的,最简单的就是文本文档了,统一组织管理这些文件的东西我们可以做成xml格式的文件和可以用数据库来管理,对不对这两种形式都是可取的,都可以把各种文件保存下来不至于丢失。 当我们读取这些模板文件的时候肯定会不停的使用他们,这样我们就有必要把这些文件缓存下来,知道我们整个模板都生成完了才释放这样也可以加快程序运行速度。 分析到这里我们的重点就转到了模板和数据库怎么设计这块了。相对来说我觉得放在数据库里面对我们来时会更容易管理,而放在xml文件里面对我们来说会相对操作起来灵活一点。 为了让使用者用起来简单把这些模板做成网页或可视化的操作方式不失为很好的选择。市面上也有此类的工具jeecg就是其中的一个,用起来还算方便,很有借鉴意义,但是我大致浏览了一下成生器源码(当然是反编译了),也不是很复杂加上本身既定的框架结构,不知道灵活性有多大,没有仔细研究,而我们今天要做的是既要学习设计模式又要做出来一个相对通用的东西。可能有些朋友知道私塾在线的课程就会知道,他那里有这样的课程我也有学习里面的课程,还是很有技术含量的,我们现在在分享的这个东西也是他们课程的改造升级版本,做到更加容易操作。 我们继续深入分析模板问题 实体: package com.weirblog.entity; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; @Entity @Table(name = "users") public class Users { private Integer id; private String userName; private String userPwd; private String email; private Date createDate=new Date(); private String idStr; private String profileImageUrl; public Users() { super(); } public Users(String userName, String idStr, String profileImageUrl) { super(); this.userName = userName; this.idStr = idStr; this.profileImageUrl = profileImageUrl; } public Users(Integer id, String userName, String idStr, String profileImageUrl) { super(); this.id = id; this.userName = userName; this.idStr = idStr; this.profileImageUrl = profileImageUrl; } @Id @GeneratedValue public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } @Column(unique=true,nullable=false,length=20) public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } @Column(nullable=false,length=64) public String getUserPwd() { return userPwd; } public void setUserPwd(String userPwd) { this.userPwd = userPwd; } @Column(unique=true,nullable=false,length=50) public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Temporal(TemporalType.TIMESTAMP) @Column(nullable=false,length=30) public Date getCreateDate() { return createDate; } public void setCreateDate(Date createDate) { this.createDate = createDate; } @Column(length=100) public String getIdStr() { return idStr; } public void setIdStr(String idStr) { this.idStr = idStr; } @Column(length=200) public String getProfileImageUrl() { return profileImageUrl; } public void setProfileImageUrl(String profileImageUrl) { this.profileImageUrl = profileImageUrl; } } 这样一个实体类我们可以把它分解成不同的部分,我们从头到尾的分解一下: 首先是最上面的包结构:package com.weirblog.entity; 分析package 应该是固定的也是Java的语法结构,对于其他语言也一样,这里就是固定值。 com.weirblog.entity; 这个就是你们的项目的包结构构成,这个就有自己确定了 com是什么含义?weiblog是什么含义?entity是什么含义?这个都是需要你们公司去规范起来的,不要忘了后面还有一个分号 ; 英文的,这些都需要我们去分析说明的。 接下来是 import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; 你们说这些我们怎么自动生成,这个你可以直接写在这里固定起来,也可以生成好java代码之后自己在引入,看起来直接先固定写下来会好一点。 下面是: @Entity @Table(name = "users") public class Users { @Entity 固定 @Table(name = "users") users 不固定 public class Users { Users 也是变量 下面: private Integer id; private String userName; private String userPwd; private String email; private Date createDate=new Date(); private String idStr; private String profileImageUrl; 这些都是需要我们添加的了,其中包括类型 名称 下面: public Users() { super(); } public Users(String userName, String idStr, String profileImageUrl) { super(); this.userName = userName; this.idStr = idStr; this.profileImageUrl = profileImageUrl; } public Users(Integer id, String userName, String idStr, String profileImageUrl) { super(); this.id = id; this.userName = userName; this.idStr = idStr; this.profileImageUrl = profileImageUrl; } 这些可有可无的 最后: @Id @GeneratedValue public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } @Column(unique=true,nullable=false,length=20) public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } 基于注解的getter 和 setter 方法,也是我们需要生成的重头戏。 是不是主键?需不需要自动生成?属性类型是什么?多大长度?是否为空?是否唯一?等等吧都是变化的需要我们自己设置的,这些都需要在配置文件或数据库里面体现出来。 不过说句实话,你能把这些写出来不就等于是数据库设计好了么,那么把这些直接对接到数据库也是可行的,在这个时候连同数据库也设计出来了。需要说明的是对于基于框架的一对多 多对多等等这些标语表之间的关系,归于小型应用来说确实很方便,但是对于大型系统来说切记慎重使用,这里虽然可以做但是我们先忽略这样的关系。 对于上面的分析我们可不可以这样设计模板: package ${packge}.vo; @Entity @Table(name = "${tableName}") public class ${ClassName} implements java.io.Serializable{ $[com.weirblog.pro.property] $[ com.weirblog.gs.getterSetter] } 你如果还想附加什么可以在上面加就是了。 DAO和servivce层 简不简单就拿我经常用的,dao封装与数据库打交道的所有CRUD然后交给service调用即可: package com.weirblog.hservice; import com.weirblog.dao.BaseDAO; import com.weirblog.entity.Comments; public interface CommentsService extends BaseDAO<Comments>{ 。。。。。。。。 } package com.weirblog.hservice.impl; import org.springframework.stereotype.Service; import com.weirblog.dao.BaseDAOSupport; import com.weirblog.entity.Comments; import com.weirblog.hservice.CommentsService; @Service("commentsService") public class CommentsServiceImpl extends BaseDAOSupport<Comments> implements CommentsService { } 这就是service层 ,你说这有什么难做的,比实体层容易多了。 其它层我就不多说了,按照这个思路做下去就行了。 上面那些${} , $[] 这些也没什么特别的,就是制定一些规则而已,以后再慢慢了解。 说句实在话,最好的代码生成就是只要有一个实体模板,后面的dao service action 甚至web统统用一套模板生成,之后再做调整,这样效率最高。如果你配置的模板太多你所用在设计模板上面的时间跟你去自己完成所花费的时间其实差不多,所以说模板用好用不好在于你的程序架构是否遵循一定的规律,这一点要十分清楚。