《大话设计》——抽象工厂模式——最终用(反射+配置文件)实现数据访问程序

接着上篇博客,继续… … …

一、抽象工厂模式

工厂模式是设计模式中比较简单的一个设计模式,但很多地方都用到了工厂模式,(如解析xml中,jdbc连接数据库等)利用好工厂模式对程序的设计很有用处。

工厂模式在一些设计模式的书中分为简单工厂模式工厂方法模式抽象工厂模式 三类。也有把工厂方法模式划分到抽象工厂模式的,认为工厂方法是抽象工厂模式的特例的一种,就是只有一个要实现的产品接口。


1、产品族和产品等级

在这里插入图片描述

  • 产品族:产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品。它们有着共同的接口;举例:一个数据库不同的数据表的集合。
  • 产品等级:产品等级结构即产品的继承结构,例如抽象电视机是父类,而具体品牌的电视机是其子类

2、定义

抽象工厂模式,提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。


3、数据访问程序UML

抽象工厂模式 的数据访问程序UML。(一切尽在这张UML图里)

在这里插入图片描述

抽象工厂模式 支持产品族 的扩展,这里指的是表的扩展,不支持 产品等级,这里指的是数据库访问方式的扩展,即UML图中工厂的扩展。


4、优缺点

   1、为新产品族的添加提供了方便,而不为等级结构的增加提供方便。

   2、增加产品族,满足开放封闭原则

   3、增加产品等级结构(即创建一个新的表),需要修改很多很多(也是,上篇博客最后的遗留问题


二、用简单工厂改进抽象工厂

去除,三个工厂IFactory,SqlserverFactory,AccessFactory, 取而代之的是DataAccess,用一个简单工厂模式来实现。
在这里插入图片描述

1、DataAccess类

package 抽象工厂模式;

public class DataAccess {
	private static String db="Sqlserver";
	
	public static IUser CreateUser() {
		IUser result =null;
		switch(db){
		case"Sqlserver":
			result=new SqlserverUser();
			break;
		case"Access":
			result=new AccessUser();
			break;
		}
		return result;
	}
	public static IDepartment CreateDepartment() {
		IDepartment result =null;
		switch(db){
		case"Sqlserver":
			result=new SqlserverDepartment();
			break;
		case"Access":
			result=new AccessDepartment();
			break;
		}
		return result;
	}
}

在客户端没有出现任何一个SQLserver 或 Access 的字样,达到解耦的目的。但如果想要增加Oracle数据库访问,本来抽象工厂只增级一个OracleFactory工厂类就可以了,现在却要在DataAccess类中每个方法的Switch中增加case了。


三、用反射+抽象工厂实现数据访问程序

在DataAccess1类,用反射技术,取代IFactory、SQLserverFactory和AccessFactory。

“用简单工厂改进抽象工厂” 方法唯一的不同是:DataAccess1类!

UML类图:在这里插入图片描述


整体代码结构:
在这里插入图片描述


1、DataAccess1类:

package 抽象工厂模式;
//不在再使用switch-case语句
public class DataAccess1 {
	private static String AssemblyName="抽象工厂模式";
	private static String db="Sqlserver";
	
	public static IUser CreateUser() throws InstantiationException, IllegalAccessException, ClassNotFoundException{
		String className=AssemblyName+"."+db+"User";
		return (IUser)Class.forName(className).newInstance();
	}
	public static IDepartment CreateDepartment() throws InstantiationException, IllegalAccessException, ClassNotFoundException{
		String className=AssemblyName+"."+db+"Department";
		return (IDepartment)Class.forName(className).newInstance();
	}
}

2、IDepartment接口

package 抽象工厂模式;

public interface IDepartment {
	public void Insert(Department department);
	public Department GetDepartment(int id);
}

3、AccessIDepartment、SqlserverDepartment 实现 IDepartment 接口

package 抽象工厂模式;

public class AccessDepartment implements IDepartment {

	@Override
	public void Insert(Department department) {
		System.out.println("在 Access 中给Department表增加一条记录。");
	}
	@Override
	public Department GetDepartment(int id) {
		System.out.println("在Access 中根据ID得到Department表一条记录");
		return null;
	}
}
package 抽象工厂模式;

public class SqlserverDepartment implements IDepartment {

	@Override
	public void Insert(Department department) {
		System.out.println("在 SQL Server中给Department表增加一条记录。");	
	}
	@Override
	public Department GetDepartment(int id) {
		System.out.println("在SQL Server中根据ID得到Department表一条记录");
		return null;
	}
}

4、IUser接口

IUser接口

package 抽象工厂模式;

public interface IUser {
	public void Insert(User user);
	public User GetUser(int id);
}

附加User普通类

package 抽象工厂模式;

public class User {
	private int id;
	private String name;
	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;
	}
	
}

5、AccessUser,SqlserverUser 实现接口IUser

package 抽象工厂模式;

public class AccessUser implements IUser {

	@Override
	public void Insert(User user) {
		System.out.println("在 Access 中给User表增加一条记录。");	
	}
	@Override
	public User GetUser(int id) {
		System.out.println("在Access 中根据ID得到Access表一条记录");
		return null;
	}
}

package 抽象工厂模式;

public class SqlserverUser implements IUser {

	@Override
	public void Insert(User user) {
		System.out.println("在 SQL Server中给User表增加一条记录。");	
	}
	@Override
	public User GetUser(int id) {
		System.out.println("在SQL Server中根据ID得到User表一条记录");
		return null;
	}
}

6、Test客户端

package 抽象工厂模式;

import org.dom4j.DocumentException;

public class Test {
	public static void main(String[] args) throws IllegalAccessException, DocumentException,InstantiationException, ClassNotFoundException {
        User user = new User();
        Department dept = new Department();
        
        IUser iu = DataAccess1.CreateUser();
        iu.Insert(user);
        iu.GetUser(1);
        IDepartment  id = DataAccess1.CreateDepartment() ;
        id.Insert(dept);
        id.GetDepartment(1); 
    }
}

7、运行结果

在这里插入图片描述


四、反射+配置文件实现数据访问程序

代码整体:
在这里插入图片描述

1、XML配置文件

<?xml version="1.0" encoding="UTF-8"?>
<databases>
    <database>
         <name>Access</name>
    </database>
</databases>

2、DataAccess类

package 抽象工厂模式;

import java.io.File;
import java.util.Iterator;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class DataAccess {
	
	public static String getDb() throws DocumentException{
		SAXReader reader = new SAXReader();//创建解析器
		//Object obj=null;
			//获取Document对象
			Document doc=reader.read(new File("src/com5_10.xml"));
			//获取xIterator<Element> it = root.elementIterator();根结点
			Element root=doc.getRootElement();
             //获取根元素所有子元素
            @SuppressWarnings("unchecked")
			Iterator<Element> it =root.elementIterator();
            //取出元素
			Element e=it.next();
			String name=e.element("name").getStringValue();
		return name;
	}
//	public static void show() throws DocumentException{
//		System.out.println(getDb());
//	}
	public static IUser CreateUser() throws ClassNotFoundException, InstantiationException, IllegalAccessException, DocumentException
	{
		String db=getDb();
		return (IUser)Class.forName("抽象工厂模式."+db+"User").newInstance();
	}
	public static IDepartment CreateDepartment() throws ClassNotFoundException, InstantiationException, IllegalAccessException, DocumentException {
        String db=getDb();
        return (IDepartment)Class.forName("抽象工厂模式."+db+"Department").newInstance();
    }
}

3、Test客户端

package 抽象工厂模式;

import org.dom4j.DocumentException;

public class Test {
	public static void main(String[] args) throws IllegalAccessException, DocumentException,InstantiationException, ClassNotFoundException {
        User user = new User();
        Department dept = new Department();
        
        IUser iu = DataAccess.CreateUser();
        iu.Insert(user);
        iu.GetUser(1);
        IDepartment  id = DataAccess.CreateDepartment() ;
        id.Insert(dept);
        id.GetDepartment(1); 
// 	DataAccess.show();
		
    }
}

4、运行结果

在这里插入图片描述


参考博客:
【简单工厂模式&工厂方法模式&抽象工厂模式的区别及优缺点及使用场景】

【23种设计模式——抽象工厂模式】

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值