博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
抽象工厂模式
阅读量:2434 次
发布时间:2019-05-10

本文共 6124 字,大约阅读时间需要 20 分钟。

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

  抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提
       供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。

 与工厂方法模式的区别:
  抽象工厂模式:
       1.多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
       2.一个抽象工厂类,可以派生出多个具体的工厂类。
       3.每个具体工厂类可以创建多个具体产品类的实例。  
  工厂方法模式:

       1.一个抽象产品类,可以派生出多个具体产品类。

       2.一个抽象工厂类,可以派生出多个具体工厂类。 
       3.每个具体工厂类只能创建一个具体产品类的实例。
  
  抽象工厂就像工厂,而工厂方法则像是工厂的一种产品生产线

 

 

抽象工厂模式实例:

 

 

/** * 用户类 */public class User {	private String id;	private String name;	public String getId() {		return id;	}	public void setId(String id) {		this.id = id;	}	public String getName() {		return name;	}	public void setName(String name) {		this.name = name;	}	}

 

/** * 用户接口 */public interface IUser {			public void insertUser(User user);		public User getUser(String id);}

 

/** * 用于访问Access的User。 */public class UserAccess implements IUser {	public User getUser(String id) {		System.out.println("在Access中根据ID得到User表一条记录。");				return null;	}	public void insertUser(User user) {		System.out.println("在Access中给User表添加一条记录。");	}}

 

/** * 用于访问SqlServer的User。 */public class UserSqlServer implements IUser {	public User getUser(String id) {		System.out.println("在SqlServer中根据ID得到User表一条记录。");				return null;	}	public void insertUser(User user) {		System.out.println("在SqlServer中给User表添加一条记录。");	}}

 

/** * 部门类 */public class Department {	private String id;	private String name;	public String getId() {		return id;	}	public void setId(String id) {		this.id = id;	}	public String getName() {		return name;	}	public void setName(String name) {		this.name = name;	}	}

 

/** * 部门接口 */public interface IDepartment {			public void insertDepartment(Department department);		public Department getDepartment(String id);}

 

/** * 用于访问Access的Department。 */public class DepartmentAccess implements IDepartment {	public Department getDepartment(String id) {		System.out.println("在Access中根据ID得到Department表一条记录。");		return null;	}	public void insertDepartment(Department department) {				System.out.println("在Access中给Department表添加一条记录。");	}}

 

/** * 用于访问SqlServer的Department。 */public class DepartmentSqlServer implements IDepartment {	public Department getDepartment(String id) {		System.out.println("在SqlServer中根据ID得到Department表一条记录。");				return null;	}	public void insertDepartment(Department department) {		System.out.println("在SqlServer中给Department表添加一条记录。");	}}

 

/** * 定义一个创建访问User表和部门表对象的抽象的工厂接口 */public interface IFactory {		// 创建用户	public IUser createUser();		// 创建部门	public IDepartment createDepartment();}

 

/** * 实现IFactory接口,实例化AccessUser和AccessDepartment。 */public class FactoryAccess implements IFactory{	public IDepartment createDepartment() {		return new DepartmentAccess();	}	public IUser createUser() {		return new UserAccess();	}}

 

/** * 实现IFactory接口,实例化SqlServerUser和SqlServerDepartment。 */public class FactorySqlServer implements IFactory{	public IDepartment createDepartment() {		return new DepartmentSqlServer();	}	public IUser createUser() {		return new UserSqlServer();	}}

 

public class Main {		public static void main(String[] args) {				// 用户		User user = new User();		// 部门		Department department = new Department();				// 访问SqlServer数据库(访问Access只要改为new FactoryAccess()).		IFactory factory = new FactorySqlServer();				// 操作用户表		IUser iu = factory.createUser();		iu.insertUser(user);		iu.getUser("1");				// 操作部门表		IDepartment id = factory.createDepartment();		id.insertDepartment(department);		id.getDepartment("1");	}}

 

 

用简单工厂改进抽象工厂:抛弃了IFactory,FactorySqlServer,FactoryAccess三个工厂类.

不足之处:如果需要增加Oracle数据库,应需要在每个方法的switch中添加case处理。

 

 

/** * 数据库枚举类 */public enum DataBaseEnum {			SqlServer,Access;		}

 

public class DataAccess {		// 数据库名称(可替换成Access)	private static final DataBaseEnum dataBase = DataBaseEnum.SqlServer;			// 根据不同的数据库操作用户表	public static IUser createUser(){		IUser iUser = null;				// 由于DB的事先设置,此处可根据选择实例化出相应的对象		switch(dataBase){			case SqlServer:				iUser = new UserSqlServer();				break;			case Access:				iUser = new UserAccess();				break;					}				return iUser;			}		// 根据不同的数据库操作部门表	public static IDepartment createDepartment(){		IDepartment iDepartment = null;				// 由于DB的事先设置,此处可根据选择实例化出相应的对象		switch(dataBase){			case SqlServer:				iDepartment = new DepartmentSqlServer();				break;			case Access:				iDepartment = new DepartmentAccess();				break;					}				return iDepartment;	}}

 简单工厂类的改进:采用反射机制解决简单工厂中switch分支添加case处理的修改变动。

                           也可采用配置文件和反射技术进行改进。 

public class DataAccessReflect {		// 此处可改为AccessUser(访问Access数据库)或OracleUser(访问oracle数据库)	private static final String userClassName = "com.design." +						"factory.abstractFactory.UserSqlServer";	private static final String departClassName = "com.design." +						"factory.abstractFactory.DepartmentSqlServer";			// 根据不同的数据库操作用户表	public static IUser createUser(){		IUser iUser = null;		try {						// 利用反射实例化指定的对象			iUser = (IUser)Class.forName(userClassName).newInstance();		} catch (InstantiationException e) {			e.printStackTrace();		} catch (IllegalAccessException e) {			e.printStackTrace();		} catch (ClassNotFoundException e) {			e.printStackTrace();		}		return iUser;			}		// 根据不同的数据库操作部门表	public static IDepartment createDepartment(){		IDepartment iDepartment = null;				try {						// 利用反射实例化指定的对象			iDepartment = (IDepartment)Class						  .forName(departClassName).newInstance();		} catch (InstantiationException e) {			e.printStackTrace();		} catch (IllegalAccessException e) {			e.printStackTrace();		} catch (ClassNotFoundException e) {			e.printStackTrace();		}		return iDepartment;	}}

 

public class Main {	public static void main(String[] args) {		// 用户		User user = new User();		// 部门		Department department = new Department();					// 操作用户表(直接得到实际的数据库访问实例,而不存在任何依赖)		IUser iu = DataAccess.createUser();		iu.insertUser(user);		iu.getUser("1");				// 操作部门表(直接得到实际的数据库访问实例,而不存在任何依赖)		IDepartment id = DataAccess.createDepartment();		id.insertDepartment(department);		id.getDepartment("1");				//**************改进后的反射机制调用*********************		IUser iuReflect = DataAccessReflect.createUser();		iuReflect.insertUser(user);		iuReflect.getUser("1");				// 操作部门表(直接得到实际的数据库访问实例,而不存在任何依赖)		IDepartment idReflect = DataAccessReflect.createDepartment();		idReflect.insertDepartment(department);		idReflect.getDepartment("1");	}}

 

 

转载地址:http://nyxmb.baihongyu.com/

你可能感兴趣的文章
纵览全局——SSH
查看>>
纵览全局——Mybatis
查看>>
PC端-中文转拼音后续问题
查看>>
第七章-面向对象技术
查看>>
Mybatis-略识之无
查看>>
ionic 前端 - 汉字转拼音
查看>>
Ionic-与时间有关的故事-localecompare()
查看>>
Logback-spring.xml日志配置
查看>>
[Vue warn]: Property or method "name" is not defined on the instance but referenced during render
查看>>
ts:json串转换成数组
查看>>
String、StringBuffer和StringBuilder的区别
查看>>
java——职责链模式
查看>>
java_选择类排序——简单选择排序
查看>>
java_中介者模式
查看>>
java_备忘录模式
查看>>
多线程——背景了解
查看>>
power designer使Comment与Name相同.txt
查看>>
学习Spring 开发指南------基础语义
查看>>
IE下的图片空隙间距BUG和解决办法
查看>>
[pb]从excel导入数据到datawindow
查看>>