如何应用策略设计模式分离JDBC数据库连接中的外部环境信息
wxin55 2024-11-20 22:43 99 浏览 0 评论
软件项目实训及课程设计指导——如何应用策略设计模式分离JDBC数据库连接中的外部环境信息
1、什么是策略(Strategy)设计模式
策略设计模式把"算法"(也就是软件应用系统中的业务规则或者待实现的功能等)和"环境"(封装软件应用系统在实际应用时的场景)相互分离,其中的"环境"程序类主要是负责维护和查询"算法"程序类,而各种"算法"则由具体的策略程序类加以封装和实现,并且策略程序类可以通过面向对象设计方法中的继承机制来产生出层次性的策略程序类,可以根据应用的需要进行替换。
策略设计模式在GOF设计模式的分类中属于GOF设计模式中的行为型类型的设计模式。如下示图为体现策略设计模式中的各个类之间关系的UML类图,依据此UML类图,可以了解到策略设计模式提供了一种替代面向对象设计方法中的继承的方法,将继承改变为组合,而且既保持了继承的优点(实现代码重用)但又比继承更具有灵活性("算法"独立,可以任意地扩展)。
2、为什么要在软件应用系统编程实现中应用策略设计模式
(1)策略设计模式能够把"算法"和"环境"分离开
在软件应用系统的程序功能代码编程实现中,开发人员经常会应用策略设计模式,以达到把实现"算法"的程序代码本身与使用算法的"客户"端程序之间的耦合关系相互分离。也就是策略设计模式能够让"算法"独立于使用它的客户程序而独立地变化、并且"算法"自身的变化(比如"算法"的增减、修改等)不会影响到使用"算法"的客户端程序。
因此,应用策略设计模式后,在软件应用系统设计方面所能够达到的设计目标:
1)保证软件应用系统具有良好的可扩展性和可维护性;
2)使用策略设计模式可以在系统的需求发生变化时,对程序代码的修改量较少,并且能够快速地适应变化(通过添加新的功能实现类)。
(2)策略设计模式的应用场景示例一
比如,在构建软件应用系统持久层数据库连接Connection接口的对象实例时不希望出现下面的状况:
将实现各种不同物理数据库系统的"连接"的功能代码(在这里代表策略模式中的"算法")直接出现在使用数据库连接对象实例的"程序"中(也就是策略模式中的"客户"——如软件应用系统持久层中的各种数据库访问操作的DAO组件)。
这样的设计方案将使得"客户"相关的程序代码和具体的"算法"功能实现的程序代码完全绑定,而且由于"算法"相关的程序也会经常发生变化。应用这样的设计方案的后果将会导致程序代码的可维护性比较差——因为一旦"算法"相关的程序代码发生了改变,将会影响到相关的各个客户程序也都需要被动地修改和完善。
(3)策略设计模式的应用场景示例二
作者再应用生活中的示例为读者说明策略设计模式中的"算法"和"环境"相互分离的作用效果—— "汉堡包"为什么在全世界的口味是一样的呢?
因为"汉堡包" 制作的工艺("算法")是独立"环境"的(不同的国家或者地区);而"汉堡包"的客户(不同国家的人)在不同的环境中都能够获得一致"口味"的汉堡包。
3、"J2EE项目实训——UML及设计模式"一书详细介绍了策略设计模式的具体实现
作者考虑到本文的篇幅关系,无法详细地为读者介绍GOF设计模式中的策略设计模式更深入的知识及具体实现程序代码示例等内容。因此,有关策略设计模式的具体编程实现及程序代码示例,请读者参考清华大学出版社出版的作者的"J2EE项目实训——UML及设计模式"一书(如下示图为该书的封面)中的第10章"典型GOF设计模式及应用"中的有关内容。
作者将为读者介绍如何将策略模式设计应用于创建软件应用系统持久层数据库连接Connection接口对象实例的功能实现程序代码中。
4、为什么要应用策略模式创建数据库连接Connection接口类型的对象实例
在JDBC数据库应用编程技术中,一般是利用下面程序代码示例中所示的常规的数据库连接类的功能实现代码完成对数据库连接Connection对象的实例化——常规的数据库连接Connection对象的实例化的功能实现代码示例
public class ConnectDBBean implements ConnectDBInterface {
String JDBC_DBDriver_ClassName=" com.mysql.jdbc.Driver ";
String JDBC_DSN_URL=" jdbc:mysql://localhost:3306/webbank ";
String JDBC_dbUserName="root";
String JDBC_dbUserPassWord="root";
private java.sql.Connection oneConnectionObject = null;
public ConnectDBBean() throws WebBankException {
try{
Class.forName(JDBC_DBDriver_ClassName);
}
catch (java.lang.ClassNotFoundException e){ //在此先不考虑异常处理
}
try{
oneConnectionObject =DriverManager.getConnection(JDBC_DSN_URL,
JDBC_dbUserName, JDBC_dbUserPassWord);
}
catch (java.sql.SQLException e){
}
catch (NullPointerException e){
}
}
}
作者为了节省篇幅,在上面的程序代码示例中,省略了一些无关的程序代码语句如包的引入和异常的捕获等。并请读者注意其中的黑体标识部分的语句代码,本程序代码示例是连接MySQL数据库系统中的名称为webbank数据库文件,并且访问数据库系统的账户及密码都设置为root。
在常规的数据库连接类的功能实现代码中,所存在的主要问题在于将数据库连接类中所需要的外部环境参数(上面示例代码中黑体部分的参数值)直接写在功能实现的程序代码中,而这些数据库连接相关的信息和参数是经常会发生变化的——比如访问数据库系统的账户所对应的密码、数据源的目标服务器主机的位置(可能为本机、也可能为网络中的远程主机)等。
软件应用系统的程序开发实现人员不应该在比如密码等这样的工作参数发生变化时,也要相应地去修改软件应用系统中的数据库连接实现的功能程序代码。否则,所开发实现的程序太缺少灵活性!
5、应用策略设计模式重构数据库连接Connection对象实例的创建代码
在GOF设计模式中的策略设计模式的基本思想,主要是要求软件应用系统的编程开发实现人员将某功能实现中所需要的各种可变化的环境参数分离出来,并用一个上下文环境程序类进行封装。
在示例项目银行账户信息管理系统中,作者首先是采用Java属性配置文件提供整个系统的配置信息,然后再利用一个名称为ClassNameConfig的程序类封装对Java属性配置文件中的各个属性项目的解析,从而动态地根据应用的需要获得对应的数据库连接相关的工作参数。
名称为ClassNameConfig的程序类也就是本示例中的上下文环境程序类,作者在下文中为读者介绍如何实现ClassNameConfig的程序类。
6、构建策略设计模式中的上下文环境ClassNameConfig类的功能实现代码
(1)在项目中添加一个属性配置文件 classNameConfig.properties
根据Java系统平台中对属性文件(*.properties)解析的基本要求,该属性配置文件应该要存放在软件应用系统的classpath所在的路径中。该路径对于Web方式的应用程序则是在WEB–INFO/classes目录下。
但读者一定要注意属性配置文件(*.properties)的相对路径,否则对属性配置文件进行解析的程序将会由于找不到此属性配置文件而抛出找不到文件的异常错误信息。
因此,读者只需要在MyEclipse开发工具中右击项目的src文件夹,并在弹出的【新建文件】的对话框中输入属性配置文件名 classNameConfig.properties。最后的操作结果的图示请见下图示例图所示。
(2)设计属性配置文件 classNameConfig.properties中的配置项目
由于Java属性配置文件(*.properties)的项目内容是"键/值"对的形式存储,因此根据项目的数据库连接的需要分别提供五个不同的属性项目。
每个项目的内容请见下图所示的内容——它们分别代表MySQL数据库的JDBC驱动程序类、MySQL数据库文件webbank和在该数据库中的账号root和密码root等信息。
(3)设计一个获得属性配置文件中的各个属性项目的ClassNameConfig程序类
在java.lang.Class类中的getResourceAsStream方法将直接返回一个InputStream类型的流对象实例,而getResourceAsStream功能方法是查找具有给定名称的资源并返回 InputStream对象。
但要注意的是:getResourceAsStream功能方法在查找和定位属性配置文件时是相对于"/"根路径下的位置——这样的路径是指定绝对路径;如果在标识属性配置文件时不以"/"字符开头,则查找和定位的路径是相对于这个程序类(也就是ClassNameConfig程序类)文件所在包的路径。比如,下面的程序代码示例:
InputStream oneInputStreamObject =
ClassNameConfig.class.getResourceAsStream("/classNameConfig.properties");
而java.lang.ClassLoader类中的getResource()功能方法则是从系统的classpath的根路径开始查找带有给定名称的资源路径和文件名并返回一个URL类型的对象示例。当然,当指定的程序类名字不能在当前的classpath目录路径中找到时,getResource()功能方法将返回null。
java.lang.Thread类中的contextClassLoader属性则代表线程的上下文 ClassLoader,因为每个运行中的线程都有一个成员contextClassLoader属性对象,用来在运行时动态地载入其它的程序类。并且可以采用下面形式的程序代码获得当前线程的contextClassLoader对象实例。
ClassLoader currentClassLoader= Thread.currentThread().getContextClassLoader();
因此,如果在某个线程中需要应用并加载某个外部的功能类,可以首先利用Thread.currentThread().getContextClassLoader()功能方法获得该线程的对象实例的contextClassLoader;然后再利用所获得的contextClassLoader对象实例请求它的父ClassLoader对象实例来完成外部程序类的载入请求。
完整的ClassNameConfig程序类的功能实现代码请见下面的程序代码示例所示——ClassNameConfig类的功能实现代码示例
package com.px1987.webbank.config;
import java.util.Properties;
import java.io.*;
public class ClassNameConfig {
public ClassNameConfig() {
}
private static Properties onePropertiesObject =null;
static {
onePropertiesObject = new Properties();
try{
InputStream oneInputStreamObject =
Thread.currentThread().getContextClassLoader().
getResource("classNameConfig.properties").openStream();
onePropertiesObject.load(input);
}catch(Exception e){
e.printStackTrace();
}
}
public static String getProperty(String propName){
return onePropertiesObject.getProperty(propName);
}
public static void setProperty(String propName, String prop Value){
onePropertiesObject.setProperty(propName, propValue);
}
}
请读者注意其中的黑体标识的语句,由于static静态成员属性对象能够达到全局缓存的应用效果,并且static语句块是在该程序类被加载时就执行的、而且也只执行一次。因此,static语句块也能够产生一种"单例"(单一对象实例,也就是单例设计模式)的应用效果,避免重复地对属性配置文件(*.properties)进行加载。另外,下面的语句代码片段:
InputStream oneInputStreamObject =Thread.currentThread().getContextClassLoader().
getResource("classNameConfig.properties").openStream();
其实等同于下面的程序代码:
ClassLoader currentClassLoader=Thread.currentThread().getContextClassLoader();
URL oneURL = currentClassLoader.getResource("classNameConfig.properties");
InputStream oneInputStreamObject = oneURL.openStream();
如何正确地创建和销毁软件应用系统中JDBC数据库连接对象实例
在程序中如何正确地创建和销毁软件应用系统中文件IO流对象实例
相关推荐
- Shiro学习系列教程三:集成web(web集成环境)
-
相关推荐:《Shiro学习系列教程一:Shiro之helloworld》《Shiro学习系列教程三:集成web》《Shiro学习系列教程四:集成web(二)》《Shiro学习系列教程五:自定义Real...
- 写了这么多年代码,这样的登录方式还是头一回见
-
SpringSecurity系列还没搞完,最近还在研究。有的时候我不禁想,如果从SpringSecurity诞生的第一天开始,我们就一直在追踪它,那么今天再去看它的源码一定很简单,因为我们了...
- Shiro框架:认证和授权原理(shiro框架授权的四种方式)
-
优质文章,及时送达前言Shiro作为解决权限问题的常用框架,常用于解决认证、授权、加密、会话管理等场景。本文将对Shiro的认证和授权原理进行介绍:Shiro可以做什么?、Shiro是由什么组成的?举...
- Spring Boot 整合 Shiro-登录认证和权限管理
-
这篇文章我们来学习如何使用SpringBoot集成ApacheShiro。安全应该是互联网公司的一道生命线,几乎任何的公司都会涉及到这方面的需求。在Java领域一般有SpringS...
- Apache Shiro权限管理解析二Apache Shiro核心组件
-
ApacheShiro核心组件Subject(用户主体)Subject是Shiro中的核心概念之一,表示当前用户(可以是登录的用户或匿名用户)。它是与用户交互的主要接口,提供了对用户身份验证...
- 详细介绍一下Apache Shiro的实现原理?
-
ApacheShiro是一个强大、灵活的Java安全框架,设计目标是简化复杂的安全需求,提供灵活的API,使开发者能方便地将安全功能集成到任何应用中。主要作用是用于管理身份验证、授权、会话管理和加...
- 什么是Apache Shiro?SpringBoot中如何整合Apache Shiro?
-
ApacheShiro是一个功能强大且易于使用的Java安全框架,主要用于构建安全的企业应用程序,例如在应用中处理身份验证(Authentication)、授权(Authorization)、加密(...
- Apache Shiro权限管理解析三Apache Shiro应用
-
Shiro的优势与适用场景优势简单易用:API设计直观,适合中小型项目快速实现权限管理。灵活性高:支持多种数据源(数据库、LDAP等),并允许开发者自定义Realm。跨平台支持:不仅限于We...
- 那些通用清除软件不曾注意的秘密(清理不需要的应用)
-
系统清理就像卫生检查前的大扫除,即使你使出吃奶的劲儿把一切可能的地方都打扫过,还会留下边边角角的遗漏。随着大家电脑安全意识的提高,越来越多的朋友开始关注自己的电脑安全,也知道安装360系列软件来"武装...
- JWT在跨域认证中的奇妙应用(jq解决跨域)
-
JWT在跨域认证中的奇妙应用什么是JWT?让我们先来聊聊JWT(JSONWebToken)。它是一种轻量级的认证机制,就像一张电子车票,能让用户在不同的站点间通行无阻。JWT由三部分组成:头部(H...
- 开启无痕浏览模式真能保护个人隐私吗?
-
在访问网站页面时,你是否有过这样的疑虑,自己访问的会不会是山寨网站?用公用电脑上网,个人信息会被别人看到吗?这时,有人会说,使用浏览器的“无痕浏览”模式不就行了,可以在操作中不留下“蛛丝马迹”,但,真...
- 辅助上网为啥会被抛弃 曲奇(Cookie)虽甜但有毒
-
近期有个小新闻,大概很多小伙伴都没有注意到,那就是谷歌Chrome浏览器要弃用Cookie了!说到Cookie功能,很多小伙伴大概觉得不怎么熟悉,有可能还不如前一段时间被弃用的Flash“出名”,但它...
- cookie、session和token(cookie,session和token的区别)
-
Cookie的概念最早是在1994年由NetscapeCommunications的程序员LouMontulli发明的,目的是为了解决当时早期互联网的一个关键问题:HTTP无状态协...
- 小白都能看懂的session与cookie的区别理解
-
cookie/session都是跟踪识别浏览器用户身份的一个东西。cookie的理解:我们要知道,服务器和客户端之间进行数据传输,需要使用到一个超文本传输协议(http协议),而http协议本身是个...
- 面试:网易一面:支撑10万QPS的电商购物车系统如何架构设计呢?
-
1.需求分析:10万QPS的购物车系统需要满足哪些需求?回答:10万QPS的购物车系统需要满足以下核心需求和挑战:核心功能:添加、删除、修改购物车商品实时查看购物车列表支持高并发读写(10万QPS)...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- Shiro学习系列教程三:集成web(web集成环境)
- 写了这么多年代码,这样的登录方式还是头一回见
- Shiro框架:认证和授权原理(shiro框架授权的四种方式)
- Spring Boot 整合 Shiro-登录认证和权限管理
- Apache Shiro权限管理解析二Apache Shiro核心组件
- 详细介绍一下Apache Shiro的实现原理?
- 什么是Apache Shiro?SpringBoot中如何整合Apache Shiro?
- Apache Shiro权限管理解析三Apache Shiro应用
- 那些通用清除软件不曾注意的秘密(清理不需要的应用)
- JWT在跨域认证中的奇妙应用(jq解决跨域)
- 标签列表
-
- hive行转列函数 (63)
- sourcemap文件是什么 (54)
- display none 隐藏后怎么显示 (56)
- 共享锁和排他锁的区别 (51)
- httpservletrequest 获取参数 (64)
- jstl包 (64)
- qsharedmemory (50)
- watch computed (53)
- java中switch (68)
- date.now (55)
- git-bash (56)
- 盒子垂直居中 (68)
- npm是什么命令 (62)
- python中+=代表什么 (70)
- fsimage (51)
- nginx break (61)
- mysql分区表的优缺点 (53)
- centos7切换到图形界面 (55)
- 前端深拷贝 (62)
- kmp模式匹配算法 (57)
- jsjson字符串转json对象 (53)
- jdbc connection (61)
- javascript字符串转换为数字 (54)
- mybatis 使用 (73)
- 安装mysql数据库 (55)