抽象工厂模式
抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提
供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。
与工厂方法模式的区别:
抽象工厂模式:
1.多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
2.一个抽象工厂类,可以派生出多个具体的工厂类。
3.每个具体工厂类可以创建多个具体产品类的实例。
工厂方法模式:
1.一个抽象产品类,可以派生出多个具体产品类。
2.一个抽象工厂类,可以派生出多个具体工厂类。
3.每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂就像工厂,而工厂方法则像是工厂的一种产品生产线
http://dl.iteye.com/upload/attachment/497913/97fa5346-fe75-3e0b-a41e-236166ac5856.gif
抽象工厂模式实例:
http://dl.iteye.com/upload/attachment/497917/2024aeb8-045d-3b9a-a2c0-cabaeeb06a25.gif
/** * 用户类 */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处理。
http://dl.iteye.com/upload/attachment/497936/0dc1cd6c-39b0-347d-b962-4d155381bd43.gif
/** * 数据库枚举类 */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");}}
页:
[1]