可复用面向对象软件基础——设计模式(四)之单例模式

单例对象(Singleton)是一种常用的设计模式。在 Java 应用中,单例对象能保证在一个 JVM 中,该对象只有一个实例存在。 单例模式优势 某些类创建繁琐,对于一些大型对象,系统开销大 省去 new 操作符,降低系统内存使用频率,减轻 GC 压力 保证某些核心类独立控制系统整个流程(控制其不可实例多个) 简版单例类 public class Singleton { // 持有私有静态实例,防止被引用,此处赋值为null,目的为实现延迟加载 private static Singleton instance = null; // 私有构造方法,防止被实例化 private Singleton() { } // 静态工厂方法 public static Singleton getInstance() { if(instance == null) { instance = new Singleton(); } return instance; } // 如果该对象被用于序列化,可保证对象在序列化前后保持一致 public Object readResolve() { return instance; } } 这个类可以满足基本要求,但是,像这样毫无线程安全保护的类,如果我们把它放入多线程的环境下,肯定就会出现问题了,如何解决?我们首先会想到对 getInstance 方法加synchronized关键字,如下: // 静态工厂方法 public static synchronized Singleton getInstance() { if(instance == null) { instance = new Singleton(); } return instance; } 但是,synchronized 关键字锁住的是这个对象,这样的用法,在性能上会有所下降,因为每次调用 getInstance(),都要对对象上锁。...

2016-12-15 19:57:13 · 2 分钟 · 295 字

可复用面向对象软件基础——设计模式(三)之抽象工厂模式

一、工厂方法模式缺陷 工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须修改工厂类,这违背了设计模式六大原则第一条闭包原则。 所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象工厂模式,创建多个工厂类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。 二、抽象工厂模式实现 /** * 1、邮寄接口,有一个抽象邮寄方法待实现 * @author barnett * */ public interface Sender { public void send(); } /** * 2、实现类,邮件邮寄类实现邮寄接口,实现其邮寄的方法 * @author barnett * */ public class MailSender implements Sender { @Override public void send() { System.out.println("I am MailSender!"); } } /** * 短信邮寄类实现邮寄接口,实现其邮寄方法 * @author barnett * */ public class SmsSender implements Sender { @Override public void send() { System.out.println("I am SmsSender!"); } } /** * 3、提供器接口,返回邮寄对象,其生产方法待实现 * 工厂依靠实现该接口,生产产品(Sender) * @author barnett * */ public interface Provider { public Sender produce(); } /** * 4、工厂,邮件邮寄工厂,负责专门生产邮件邮寄实例 * @author barnett * */ public class SendMailFactory implements Provider { @Override public Sender produce() { return new MailSender(); } } /** * 短信邮寄工厂,专门生产短信邮寄实例 * @author barnett * */ public class SendSmsFactory implements Provider { @Override public Sender produce() { return new SmsSender(); } } /** * 5、测试类 * @author barnett * */ public class Test { public static void main(String[] args) { // 实例一个邮件工厂(因其实现了提供器接口,可返回一个具有专门生产某种产品生产方法的实例) Provider provider = new SendMailFactory(); // 通过该实例生产产品 Sender sender = provider....

2016-12-15 16:59:43 · 1 分钟 · 188 字

可复用面向对象软件基础——设计模式(二)之工厂方法模式

一、工厂方法模式分类(3 种) 普通工厂模式 多个工厂方法模式 静态工厂方法模式 二、工厂方法模式详解 (1)普通工厂模式 普通工厂模式就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建。 // 1、创建不同产品的共同接口 public interface Sender { /** * 邮寄接口中有一个邮寄方法待实现 */ public void Send(); } /** * 2、(实现类)邮件邮寄类实现了邮寄接口,实现其邮寄的抽象方法 * @author barnett */ public class MailSender implements Sender { @Override public void Send() { System.out.println("I am MailSender!"); } } /** * 短信邮寄类实现了邮寄接口,实现其邮寄的抽象方法 * @author barnett * */ public class SmsSender implements Sender { @Override public void Send() { System.out.println("I am SmsSender!"); } } /** * 3、工厂类,负责多次制造产品(new出复用的类) * @author barnett */ public class SendFactory { /** * 工厂类中的生产方法 * @param type 输入要生产的产品类型 * @return 返回一个产品 */ public Sender produce(String type) { if("mail"....

2016-12-15 12:57:58 · 2 分钟 · 319 字

可复用面向对象软件基础——设计模式(一)之总览

一、设计模式特点 反复使用 分类编目 经验总结 二、设计模式宗旨 代码重用 使代码易于理解 保证代码可靠性 三、设计模式分类(23+2) 创建型(5 种) 结构型(7 种) 行为型(11 种) 其他(2 种) (1)创建型模式 工厂方法模式 抽象工厂模式 单例模式 建造者模式 原型模式 (2)结构型模式 适配器模式 装饰器模式 代理模式 外观模式 桥接模式 组合模式 享元模式 (3)行为型模式 策略模式 模板方法模式 观察者模式 迭代子模式 责任链模式 命令模式 备忘录模式 状态模式 访问者模式 中介者模式 解释器模式 (4)其他 并发型模式 线程池模式 四、设计模式原则(6 项) 开闭原则(Open Close Principle) 里氏代换原则(Liskov Substitution Principle) 依赖倒转原则(Dependence Inversion Principle) 接口隔离原则(Interface Segregation Principle) 迪米特法则(最少知道原则)(Demeter Principle) 合成复用原则(Composite Reuse Principle) 五、原则详解 (1)开闭原则 开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。目的在于使程序的扩展性好,易于维护和升级。所以需要使用到接口和抽象类 (2)里氏代换原则 里氏代换原则(LSP)是面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。...

2016-12-15 10:43:05 · 1 分钟 · 82 字

基于SSH三大框架的员工管理系统

摘要 本系统为本人学习 SSH 三大框架时所做的整合实例,系统角色包括普通用户和管理员两种,首页有管理员登录入口链接。系统功能主要包括管理员对用户的基本增、删、改、查和分页显示用户信息等。 系统环境 本系统使用 eclipse+mysql+jdk1.8+tomcat8 进行开发 框架使用 struts2+hibernate3+spring3 页面展示 首页一开始没考虑屏幕分辨率和比例问题以及浏览器的兼容问题,后该用 bootstrap 简单模板,达到兼容旧版 IE 浏览器效果,并且为响应式布局,屏幕可任意缩放。 注册页面采用 angularJS 前端框架实现客户端表单验证 日期使用jedate.js控件 注册成功提示(后台为新注册用户分配三个随机邀请码用于邀请其他用户注册本系统) 个人主页使用 easyui 框架 管理员首页(可分页显示用户) 添加用户 核心代码解析 1、随机邀请码生成 使用 UUID 并将其切片,取前八位作为验证码(本算法尚不成熟,在大量使用后可能出现重复) public static String[] codeMaker() { String[] code = new String[3]; for (int i=0; i<3; i++) { code[i] = UUID.randomUUID().toString().substring(0,8).toUpperCase(); } return code; } 2、登录验证 action 层 public String login() { User existUser = userService.login(user); if (existUser == null) { this....

2016-11-02 15:32:34 · 3 分钟 · 477 字

基于SSH的员工管理系统(四)——项目流程

flowchat st=>start: localhost:8080/项目名 e=>end: 访问结束 fir=>: web.xml op=>operation: 我的操作 cond=>condition: 确认? st->op->cond cond(yes)->e cond(no)->op

2016-11-02 13:55:11 · 1 分钟 · 14 字

基于SSH的员工管理系统(三)——配置文件

1. Web 项目入口——web.xml <!-- spring核心监听器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- ctrl+shift+T:contextLoaderListener监听器全路径 --> <!-- 默认情况会加载WEB-INF中的配置文件 --> <!-- 配置全局初始化参数:设置为加载classes中的配置文件 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <!-- struts核心过滤器(与传统servlet配置类似) --> <filter> <filter-name>struts</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <!-- ctrl+shift+T:strutsPrepareAndExecuteFilter --> <filter-mapping> <filter-name>struts</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <display-name>ssh</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> 2. struts 配置文件——struts.xml <struts> <package name="ssh" extends="struts-default"> <action name="user_*" class="userAction" method="{1}"> <result name="input">/index.jsp</result> <result name="success" type="redirect">/jsp/layout.jsp</result> <result name="info" type="redirect">/jsp/myinfo.jsp</result> <result name="invi">/jsp/invi.jsp</result> <result name="regSuccess">/jsp/regSuccess1.jsp</result> <result name="getCodes">/jsp/mycode.jsp</result> <result name="toHome">/jsp/layout.jsp</result> <result name="linkPersion">/jsp/otherInfo.jsp</result> <result name="update">/jsp/updateUser....

2016-11-02 13:45:29 · 3 分钟 · 528 字

基于SSH的员工管理系统(二)——lib 导入各 jar 包详解

本节将关于本项目所需导入的 jar 包进行逐一解释,基本适用于普通的 Struts2+Hibernate3+Spring3 的项目, 此为相对较老的组合版本,若使用 Hibernate4 或 Mybatis 等其他较新框架,请自行查阅相关资料。 1、struts2 基础必备包(解压 blank.war 可得) 本项目使用 struts2.3.4.1 附加 Jar 解释: struts2-convention-plugin-2.3.4.1.jar——支持 struts2 的注解开发 struts2-spring-plugin-2.3.4.1.jar——用于整合 spring 2、hibernate3 基础必备包 本项目使用 hibernate3.3.1 根路径 hibernate3.jar——核心 jar 包 required 目录所有 jar 包 hibernate 日志记录——slf4j-log4j.jar 数据库驱动包——mysql-connector-java.jar(本项目使用 mysql 数据库) 3、spring 基础必备包 本项目使用 spring3.2.2 spring 基本 jar 包包括 IoC 开发 spring-beans.jar spring-context.jar spring-core.jar spring-expression.jar com.springsource.org.apache.log4j.jar——作日志记录 com.springsource.org.apache.commons.logging.jar——日志整合,不作具体日志记录,用于整合其他日志系统 AOP spring-aop.jar spring-aspect.jar——整合 aspect com.spinrgsource.org.aopalliance.jar——aop 联盟 com.springsource.org.aspectj.weaver.jar 其他 spring-tx.jar——事务管理 spring-jdbc.jar——jdbc 模板 spring-orm.jar——整合 hibernate spring-web....

2016-11-02 12:55:29 · 1 分钟 · 89 字

基于SSH的员工管理系统(一)——包结构

本项目是使用 Struts2+Hibernate3+Spring3,基于 MVC 开发模式的一个简单实例,第一篇先建立项目总体包结构,后续将详细解释项目细节。 1、整体包结构 2、action 包 3、domain 实体包 4、service 层 5、dao 层 6、util 工具包 7、页面层

2016-11-02 11:10:02 · 1 分钟 · 16 字

三大GUI库——AWT、swing、SWT

(一)AWT(abstract window toolkit,抽象窗口工具包) 特点: (1)重量级控件 (2)利用操作系统所提供的图形库 (3)简单、高效 (4)运行速度快 (5)基于系统(调用系统 UI) (6)消耗资源 (7)难以跨平台 功能: (1)Canvas 组件:画布,可实现动画操作 (2)TextArea:文本域 (3)单行文本域中回车会激发 ActionEvent (4)CheckBoxGroup 实现单选框 (5)单元框和复选框都使用 CheckBox 实现 (6)菜单:new MenuBar(),MenuBar 表示菜单条,菜单每一项为 MenuItem(一般级联菜单不应超过 3 级) 应用:嵌入式应用 目标平台的硬件资源非常有限,同时应用程序运行速度是项目中至关重要的因素 (二)swing: 特点: (1)轻量级控件 (2)100%JAVA 代码实现(Swing 为 JAVA 自身组件) (3)与底层系统无关 (4)基于 AWT (5)运行速度慢 应用:基于 PC 或工作站的标准 Java 应用 硬件资源对应用程序所造成的限制往往不是项目中的关键因素,通过牺牲速度来实现应用程序的功能 (三)SWT: 特点: (1)未通过 JAVA 虚拟机操作,直接调用 Windows GDI 和 Shell(通过 JNI 方法调用完成) (2)基于 SWT 实现的 Eclipse 界面速度快、效率高,比 Swing 美观

2015-12-23 20:06:30 · 1 分钟 · 67 字

重写与重载的区别

override(覆盖)=重写 对象:方法 解释:重写一个方法,以实现不同的功能 用于:子类继承父类的方法,重写(重现实现=继承+写新方法)父类的方法 规则: 1、参数列表相同,否则为重载而非重写 2、访问修饰符大于被重写方法(public > protected > default > private) 3、返回值(与被重写方法)相同 4、所抛异常(与被重写方法)相同 5、被重写方法不能为 private,否则在其子类中只是新定义了一个方法,并未对其进行重写 6、静态方法不能被重写为非静态方法(否则编译出错) overload(重载) 解释:在一个类内实现若干重载方法,方法名相同而参数形式不同 参数形式不同包括: 1、参数类型不同 2、参数个数不同 3、参数顺序不同(参数类型不同的同时) 用于:在一个类内实现若干同名方法 规则: 1、使用重载只能 通过相同方法名和不同的参数形式实现 2、不能通过访问权限、返回类型、抛出的异常进行重载 3、方法的异常类型和数目不会对重载造成影响

2015-12-23 13:30:18 · 1 分钟 · 30 字