问题引入
在开发过程中更换数据库的问题
基本的数据访问程序
/**
* 抽象工厂模式
* 定义:抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,无须指定它们具体的类。
* 应用:
* 1、客户端(应用层)不依赖于产品类实例如何被创建、实现等细节
* 2、强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码
* 3、提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现
* 该模式中的类主要分为4类
* 抽象工厂 具体工厂 抽象产品 具体产品
* 优点:
* 具体产品在应用层代码隔离,无须关心创建细节 将一系列的产品族统一到一起创建
* 缺点:
* 规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口 增加了系统的抽象性和理解难度
*
*
*/
/*
* 最基本的数据访问程序
*/
public class data1 {
public static void main(String[] args) {
User user = new User();
MysqlUser mu=new MysqlUser();
mu.Insert(user);
mu.Delete(1);
}
}
class User{
private int id;
private String name;
public User(int id, String name) {
super();
this.id = id;
this.name = name;
}
public User() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class MysqlUser{
public void Insert (User user) {
System.out.println("在User表中插入一条记录");
}
public void Delete(int id) {
System.out.println("用户已删除");
}
}
/*
* 问题
* MysqlUser mu=new MysqlUser()使得mu对象被钉死在MySQL上,不够灵活
* 如果需要更换数据库,对程序改动较大
*/
改进 - - -使用工厂方法模式
/*
* 使用工厂方法模式的数据访问程序
*/
public class data1 {
public static void main(String[] args) {
User user = new User();
IFactory factory = new MysqlFactory();
IUser iu = factory.CreateUser();
iu.Insert(user);
iu.Delete(1);
}
}
class User{
private int id;
private String name;
public User(int id, String name) {
super();
this.id = id;
this.name = name;
}
public User() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//IUser接口,用于访问数据,解除与具体数据库的耦合
interface IUser{
void Insert(User user);
void Delete(int id);
}
class MysqlUser implements IUser{
@Override
public void Insert(User user) {
// TODO Auto-generated method stub
System.out.println("在Mysql中给user表增加一条记录");
}
@Override
public void Delete(int id) {
// TODO Auto-generated method stub
System.out.println("在MySQL中根据id删除user表中的一条数据");
}
}
class SqlserverUser implements IUser{
@Override
public void Insert(User user) {
// TODO Auto-generated method stub
System.out.println("在Sqlserver中给user表增加一条记录");
}
@Override
public void Delete(int id) {
// TODO Auto-generated method stub
System.out.println("在Sqlserver中根据id删除user表中的一条数据");
}
}
//Ifactory接口,定义一个创建访问user对象的抽象工厂接口
interface IFactory{
IUser CreateUser();
}
class MysqlFactory implements IFactory{
@Override
public IUser CreateUser() {
// TODO Auto-generated method stub
return new MysqlUser();
}
}
class SqlserverFactory implements IFactory{
@Override
public IUser CreateUser() {
// TODO Auto-generated method stub
return new SqlserverUser();
}
}
/*
* 好处:现在更换数据库只需要把new MysqlFactory()换成new SqlserverFactory(),
* 由于多态的关系,是的iu事先不知道访问那个数据库,却可以在运行时很好的完成工作。
* 使得业务逻辑与数据访问解耦合。
* 问题:数据库中又多个表的情况,例如还有Department(部门表)
*/
改进----使用抽象工厂模式解决多表问题
/*
* 使用抽象工厂模式的数据访问程序
*/
public class data1 {
public static void main(String[] args) {
User user = new User();
Department dt = new Department();
IFactory factory =new MysqlFactory();
IUser iu=factory.CreateUser();
IDepartment idt =factory.CreateDepartment();
iu.Delete(1);
iu.Insert(user);
idt.Delete(1);
idt.Insert(dt);
}
}
class User{
private int id;
private String name;
public User(int id, String name) {
super();
this.id = id;
this.name = name;
}
public User() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Department{
private int number;
private String name;
public Department(int number, String name) {
super();
this.number = number;
this.name = name;
}
public Department() {
super();
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//IUser接口,用于访问数据,解除与具体数据库的耦合
interface IUser{
void Insert(User user);
void Delete(int id);
}
interface IDepartment{
void Insert(Department user);
void Delete(int number);
}
class MysqlUser implements IUser{
@Override
public void Insert(User user) {
// TODO Auto-generated method stub
System.out.println("在Mysql中给user表增加一条记录");
}
@Override
public void Delete(int id) {
// TODO Auto-generated method stub
System.out.println("在MySQL中根据id删除user表中的一条数据");
}
}
class SqlserverUser implements IUser{
@Override
public void Insert(User user) {
// TODO Auto-generated method stub
System.out.println("在Sqlserver中给user表增加一条记录");
}
@Override
public void Delete(int id) {
// TODO Auto-generated method stub
System.out.println("在Sqlserver中根据id删除user表中的一条数据");
}
}
class MysqlDepartment implements IDepartment{
@Override
public void Insert(Department user) {
// TODO Auto-generated method stub
System.out.println("在Mysql中给Department表增加一条记录");
}
@Override
public void Delete(int number) {
// TODO Auto-generated method stub
System.out.println("在Mysql中根据number删除Department中的一条数据");
}
}
class SqlserverDeoartment implements IDepartment{
@Override
public void Insert(Department user) {
// TODO Auto-generated method stub
System.out.println("在Sqlserver中给Department表增加一条记录");
}
@Override
public void Delete(int number) {
// TODO Auto-generated method stub
System.out.println("在Sqlserver中根据number删除Department中的一条数据");
}
}
//Ifactory接口,定义一个创建访问user对象的抽象工厂接口
interface IFactory{
IUser CreateUser();
IDepartment CreateDepartment();
}
class MysqlFactory implements IFactory{
@Override
public IUser CreateUser() {
// TODO Auto-generated method stub
return new MysqlUser();
}
@Override
public IDepartment CreateDepartment() {
// TODO Auto-generated method stub
return new MysqlDepartment();
}
}
class SqlserverFactory implements IFactory{
@Override
public IUser CreateUser() {
// TODO Auto-generated method stub
return new SqlserverUser();
}
@Override
public IDepartment CreateDepartment() {
// TODO Auto-generated method stub
return new SqlserverDepartment();
}
}
/*
* 缺点:
* 抽象工厂模式可以很方便的切换连个数据库访问的代码,但是如果需求来自增加新功能,
* 需要增加和改动的类有很多,很糟糕。
* 还有一点,客户端程序肯定不止一个,在每个类的开头都需要声明factory。
*/
改进----使用简单工厂来改进抽象工厂
/*
* 使用简单工厂来改进抽象工厂
* 思路:去掉三个factory工厂,使用Data类来代替。
*/
public class data1 {
public static void main(String[] args) {
User user = new User();
Department dt = new Department();
IUser iu =Data.CreateUser();
IDepartment idt=Data.CreateDepartment();
iu.Delete(1);
iu.Insert(user);
idt.Delete(1);
idt.Insert(dt);
}
}
class User{
private int id;
private String name;
public User(int id, String name) {
super();
this.id = id;
this.name = name;
}
public User() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Department{
private int number;
private String name;
public Department(int number, String name) {
super();
this.number = number;
this.name = name;
}
public Department() {
super();
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//IUser接口,用于访问数据,解除与具体数据库的耦合
interface IUser{
void Insert(User user);
void Delete(int id);
}
interface IDepartment{
void Insert(Department user);
void Delete(int number);
}
class MysqlUser implements IUser{
@Override
public void Insert(User user) {
// TODO Auto-generated method stub
System.out.println("在Mysql中给user表增加一条记录");
}
@Override
public void Delete(int id) {
// TODO Auto-generated method stub
System.out.println("在MySQL中根据id删除user表中的一条数据");
}
}
class SqlserverUser implements IUser{
@Override
public void Insert(User user) {
// TODO Auto-generated method stub
System.out.println("在Sqlserver中给user表增加一条记录");
}
@Override
public void Delete(int id) {
// TODO Auto-generated method stub
System.out.println("在Sqlserver中根据id删除user表中的一条数据");
}
}
class MysqlDepartment implements IDepartment{
@Override
public void Insert(Department user) {
// TODO Auto-generated method stub
System.out.println("在Mysql中给Department表增加一条记录");
}
@Override
public void Delete(int number) {
// TODO Auto-generated method stub
System.out.println("在Mysql中根据number删除Department中的一条数据");
}
}
class SqlserverDepartment implements IDepartment{
@Override
public void Insert(Department user) {
// TODO Auto-generated method stub
System.out.println("在Sqlserver中给Department表增加一条记录");
}
@Override
public void Delete(int number) {
// TODO Auto-generated method stub
System.out.println("在Sqlserver中根据number删除Department中的一条数据");
}
}
class Data{
private static String db="Mysql";
//private String db="Sqlserver";
public static IUser CreateUser(){
IUser result=null;
switch(db) {
case "Mysql":result=new MysqlUser();break;
case "Sqlserver":result = new SqlserverUser();break;
}
return result;
}
public static IDepartment CreateDepartment(){
IDepartment result=null;
switch(db) {
case "Mysql":result=new MysqlDepartment();break;
case "Sqlserver":result = new SqlserverDepartment();break;
}
return result;
}
}
/*
* 不足:如果增加别的数据库,需要修应该case,比较麻烦。
*/
使用反射+抽象工厂
/*
* 使用反射+简单工厂+抽象工厂
*/
public class data1 {
public static void main(String[] args) throws Exception {
User user=new User();
Department dt=new Department();
Properties pro = new Properties();
ClassLoader classloader = data1.class.getClassLoader();
InputStream is =classloader.getResourceAsStream("reflect.properties");
pro.load(is);
String dbName=pro.getProperty("dbName");
Data data=new Data();
data.setDb(dbName);
IUser iu = data.CreateUser();
iu.Delete(1);
iu.Insert(user);
IDepartment idt =data.CreateDepartment();
idt.Delete(1);
idt.Insert(dt);
}
}
class User{
private int id;
private String name;
public User(int id, String name) {
super();
this.id = id;
this.name = name;
}
public User() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Department{
private int number;
private String name;
public Department(int number, String name) {
super();
this.number = number;
this.name = name;
}
public Department() {
super();
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//IUser接口,用于访问数据,解除与具体数据库的耦合
interface IUser{
void Insert(User user);
void Delete(int id);
}
interface IDepartment{
void Insert(Department user);
void Delete(int number);
}
class MysqlUser implements IUser{
@Override
public void Insert(User user) {
// TODO Auto-generated method stub
System.out.println("在Mysql中给user表增加一条记录");
}
@Override
public void Delete(int id) {
// TODO Auto-generated method stub
System.out.println("在MySQL中根据id删除user表中的一条数据");
}
}
class SqlserverUser implements IUser{
@Override
public void Insert(User user) {
// TODO Auto-generated method stub
System.out.println("在Sqlserver中给user表增加一条记录");
}
@Override
public void Delete(int id) {
// TODO Auto-generated method stub
System.out.println("在Sqlserver中根据id删除user表中的一条数据");
}
}
class MysqlDepartment implements IDepartment{
@Override
public void Insert(Department user) {
// TODO Auto-generated method stub
System.out.println("在Mysql中给Department表增加一条记录");
}
@Override
public void Delete(int number) {
// TODO Auto-generated method stub
System.out.println("在Mysql中根据number删除Department中的一条数据");
}
}
class SqlserverDepartment implements IDepartment{
@Override
public void Insert(Department user) {
// TODO Auto-generated method stub
System.out.println("在Sqlserver中给Department表增加一条记录");
}
@Override
public void Delete(int number) {
// TODO Auto-generated method stub
System.out.println("在Sqlserver中根据number删除Department中的一条数据");
}
}
class Data{
private String db;
public Data(String db) {
super();
this.db = db;
}
public Data() {
super();
}
public String getDb() {
return db;
}
public void setDb(String db) {
this.db = db;
}
public IUser CreateUser() throws Exception{
if(db!=null&&!db.equals("")) {
String classname="com.javastudy4."+db+"User";
Class cls=Class.forName(classname);
Object obj=cls.newInstance();
return (IUser)obj;
}
return null;
}
public IDepartment CreateDepartment() throws Exception{
if(db!=null&&!db.equals("")) {
String classname="com.javastudy4."+db+"Department";
Class cls=Class.forName(classname);
Object obj=cls.newInstance();
return (IDepartment)obj;
}
return null;
}
}
配置文件
dbName=Mysql