PMD是一款静态代码分析工具,它能够自动检测各种潜在缺陷以及不安全或未优化的代码。Checkstyle之类的其它工具可以检查代码是否遵循了约定和标准。而PMD功能则更多地是集中在预先检测缺陷上,它提供了高度可配置的丰富规则集,用户可以方便配置对待特定项目使用那些规则。
在Eclipse中安装和使用PMD步骤
Elipse中安装PMD插件
打开Help->Install new Software,点击Add,添加Repository。Name:PMD,Location:http://pmd.sf.net/eclipse。
点击OK。选择相应的版本插件,继续随后的安装。
激活PMD插件。Ecplise的菜单Project->Properties->PMD,在这个窗口选择要应用的规则,并指定相对重要性,为特定项目详细配置PMD,目前只需要选中Enable PMD复选框,保留默认规则集。
运行PMD,单击项目资源,右键->PMD->Check code with PMD。在Violation OverView视图中按问题严重程度列出PMD问题。在Violations outLinew右键show Details可以查看更详细的规则描述以及说明规则的示例代码。
一旦理解了PMD提出的问题,可以
一套开源的 Jspx.net Framework (简实构架)是一套开源的java一体化构架,丢掉了jsp编译的烦恼和使用tag的麻烦, 完整的架构体系,包括了ui、ioc、cache、连接池、验证、模板、数据库查询更新,工作流等丰富功能,最少的赖第三方包。b/s,c/s 构架都可以使用.为了提高易用性,学习和使用上没有使用特殊技术,语言上只使用了标准的 java 和javascript,模板语言呈现页面,支持读写分离等。特点:体积小巧,使用模板呈现页面。标准的(html+css+javascript) UI方式。其中融入了很多作者开发软件碰到的问题解决方法。
名称说明- 请大家不要以为是jspx,jspx是一个来自于埃及的java web快速开发框架。本构架和它没一点关系,而且本构架在它之前就已经开发了。
- 后边有个.net也和C\#没一点关系,本构架开发之初.net才开始发布。
- 名称里边的x表示:jsp的扩展性,并且劲量遵循xml标准。
- 名称里边的.net表示:以web开发为主的一套构架。
- 本构架不是一个傻瓜式的构架,在本构架的开发过程中一直在寻求,简化和效率的结合点,故而考虑得比较灵活。
- 快速:体积小,加载速度快
- 开源:开放源代码,高水平,高品质
- 底层:使用jdk1.6原生库,最少的依赖第三方库,就可以完成开发工作。
- 扩展:基于插件的设计,所有功能都是插件,可根据需求增减功能
- 风格:修改编辑器风格非常容易,只需修改一个 CSS 文件
- 兼容:支持大部分主流浏览器,比如 IE、Firefox、Safari、Chrome、Opera
- 系统: 支持window,linux, unix等多种平台,支持32位,64位系统
本构架不适合一无所知的未入门者,如果你还未步入编程的门槛,那么可以先学习一下,jsp,php的基本开发,并且了解一下java的构架概念后在来学习。 本平台也不是那种通过点击就可以生成软件的开发工具。
本平台主要针对以下开发者下载
http://code.google.com/p/jspxnet/downloads/list
帮助
http://www.jspx.net/help/
抽象的意思是,抽取不同事物的共性而成的一种新事物。为什么用事物一词?因为抽象未必抽的是物,也可能是事。
抽象是编程的重要思想之一,其主要目的是为了减少代码重复,使其更易维护。
抽象就是让变化的事物得到一致的处理方式。
抽象是如何应用的?我们怎么去抽象?
当我们面临有共同特性的事物时,需要对它们统一处理,那么就需要抽象。而这种共性的事物在实际项目中会经常碰到。而且在我们使用的各种框架中应用广泛。比如说,用户打开不同的网页,都需要去展现页面,那么所有的网页都有一个共性就是展现,而不同的网页又具有不同的行为;所以在处理网页展现时,只需要处理网页们的抽象的东西——展现。这个“处理网页展现”的代码一般在框架内部实现。他对所有的网页处理都是调用抽象网页的展现代码,所以他的代码是一致不变的。再比如说我们点击某一些按钮,会触发各种事件,点击按钮的行为都是一致的,而事件的内容缺各不相同。那么在点击的这个行为上的处理也是一致的,就是触发事件的内容,至于事件内容的本身,那就是具体的实现问题,跟处理点击没有关系。我们把统一处理抽象事物的代码叫上层代码。抽象就是为了上层代码的一致性,不需要因为具体事物的改变而改变。
抽象与模式
也许大家都知道设计模式,这是经典的实际应用中碰到的各种常见问题而归纳出来的编程技巧,其中大多数都离不开抽象这一概念。掌握的抽象的思想,再去理解他们更容易些。
工厂模式
工厂模式是最易理解的模式之一,他是通过一个工厂类,创建抽象对象(其实是具体的实际对象),因为是抽象对象,所以其他代码在使用这些抽象对象的共性时只需要通过工厂类获取对象即可,而不需要具体new每个实际对象。
代码示例:
public interface IUserRepository { IEnumerable<Users> GetUsers(); } namespace DataRepository.MySql { public class UserRepository : IUserRepository { private MySql _db; public UserRepository() { _db = new MySql(ConnectionStringManager.Get("MySql")); } public IEnumerable<Users> GetUsers() { return _db.ExecuteSql("sql").ToList<Users>(); } } } namespace DataRepository.SqlServer { public class UserRepository : IUserRepository { public IEnumerable<Users> GetUsers() { return GetDataContext(ConnectionStringManager.Get("SqlServer")).Users.AsEnumerable(); } } } public class RepositoryFactory { public IUserRepository GetUserRepository() { return CreateInsnace(AppSettings.Get("CurrentDatabase"),"UserRepository"); } } public class UserManager() { public IEnumerable<Users> GetUsers() { return RepositoryFactory.GetUserRepository().GetUsers(); } }
上面的代码看起来比较简单,继承自接口,反射实例化具体子类便可。但抽象意味着是具体实现,而不是继承,继承只是实现的一种。所以在继承上要慎用。而大多数的模式也都是采用各种组合。其不外乎就是抽象出共同的接口,组合接口的实现。
策略模式
策略模式的应用场景我们几乎都碰到过,比如现在都比较流行SinaWeibo登录和QQ登录,再加上自己的Email登录,每种登录方式都有不同的实现,因为Sina和QQ这种OAuth的登录都需要回调网页(其实就是用来验证用户有效性的),而我们的Email登录也需要验证,总不能写3个登录验证页面吧?当然,写三个也不是不可以,但是如果我们还是Wap站,那就是6个,如果再有其他的站点,那就不知道要写多少个了。至少页面数量会很多。如果用MVC框架的话,倒是可以用公共的Controller来省去,那至少也要三个Action,而这三个页面其实也有共性,必然存在代码重复。我们需要消除这种重复,万一哪天再来个开心、人人等登录实现,又会增加很多页面;所以要把因为变化牵扯出来的变化保持不变。
可以看下面的实现代码,实现了3种登录方式的登录、验证和退出。
//登录地址策略接口 public interface ILogin { public string GetLoginUrl(/blog_article/HttpContextBase context/index.html); } //第三方用户的验证策略接口 public interface IAuthenticate { public TrdUser Authenticate(HttpContextBase context); } //退出地址策略接口 public interface ILogout { public string GetLogoutUrl(/blog_article/HttpContextBase context/index.html); } //新浪Auth的策略实现 public class SinaAuth : ILogin,IAuthenticate,ILogout { public string GetLoginUrl(/blog_article/HttpContextBase context/index.html) { return "http://weibo.com/oauth/login"; } public TrdUser Authenticate(HttpContextBase context) { return new TrdUser { Name = "我来自新浪" }; } public string GetLogoutUrl(/blog_article/HttpContextBase context/index.html) { return "http://weibo.com/oauth/logout"; } } //QQAuth的策略实现 public class QQAuth : ILogin,IAuthenticate { public string GetLoginUrl(/blog_article/HttpContextBase context/index.html) { return "http://qq.com/oauth/login"; } public TrdUser Authenticate(HttpContextBase context) { return new TrdUser { Name = "我来自QQ" }; } } //本网站默认策略的实现 public class DefaultAuth :ILogin, IAuthenticate,ILogout { public string GetLoginUrl(/blog_article/HttpContextBase context/index.html) { return "http://mysite.com/oauth/login"; } public TrdUser Authenticate(HttpContextBase context) { return new TrdUser { Name = "我来自Email" }; } public string GetLogoutUrl(/blog_article/HttpContextBase context/index.html) { return "http://mysite.com/oauth/logout"; } } //策略组装类 public class Login { private HttpContextBase _context; public Login(HttpContextBase context) { _context = context; } //获取登录地址 public string GetLoginUrl(/blog_article/ILogin login/index.html) { return login.GetLoginUrl(/blog_article/_context/index.html); } //获取退出地址 public string GetLogoutUrl(/blog_article/ILogout logout/index.html) { return logout.GetLogoutUrl(/blog_article/_context/index.html); } //获取本站用户信息 public User Authenticate(IAuthenticate auth) { var trdUser = auth.Authenticate(_context); return xx.GetUser(trdUser); } } //策略工厂,根据不同的type创建不同的策略 public class AuthFactory { private string _authType; public AuthFactory(string authType) { _authType = authType; } public ILogin GetLogin() { return (ILogin)CreateInstance(typeof(ILogin)); } public IAuthenticate GetAuth() { return (IAuthenticate)CreateInstance(typeof(IAuthenticate)); } public ILogout GetLogoutUrl() { return (ILogout)CreateInstance(typeof(ILogout)); } private object CreateInstance(Type type) { //通过反射获取具体的类型 var instance = ....; //若是没有实现,就使用默认的。 if(instance == null) return new DefaultAuth(); } } //本站的页面具体代码 public AccountController : Controller { private Login GetLogin() { return new Login(HttpContext); } //登录地址 public ActionResult Login(string authType) { var factory = new AuthFactory(authType); return Redirect(GetLogin().GetLoginUrl(factory.GetLogin())); } //验证地址,不管是Email还是第三方登录回调,均使用该地址。 public ActionResult Authenticate(string authType) { var factory = new AuthFactory(authType); var user = GetLogin().Authenticate(factory.GetAuth()); //.... } //退出地址 public ActionResult Logout(string authType) { var factory = new AuthFactory(authType); return Redirect(GetLogin().GetLogoutUrl(factory.GetLogin())); } }
因为我们在获取具体策略的时候依然要判断该使用哪种策略,所以用工厂模式来创建具体的策略。但是仍然能