作用:提供一个创建一系列相关或者相互依赖对象的接口,而无序指定他们具体的类。直白点就是一个工厂能生产更多类型的组件,比如电脑,有鼠标,主机,键盘等等,这个工厂就生产这一些列的东西,然后具体实现就是不同的厂商,比如联想,戴尔等等对应于具体的工厂。
1、抽象工厂模式
1、用户类
//用户类
public class User {
//用户ID
private int _id;
public int getId(){
return this._id;
}
public void setId(int value){
this._id=value;
}
//用户姓名
private String _name;
public String getName(){
return this._name;
}
public void setName(String value){
this._name=value;
}
}
2、部门类
public class Department {
//部门ID
private int _id;
public int getId(){
return this._id;
}
public void setId(int value){
this._id=value;
}
//部门名称
private String _name;
public String getName(){
return this._name;
}
public void setName(String value){
this._name=value;
}
}
3、用户类接口
类似产品A
public interface IUser {
public void insert(User user);
public User getUser(int id);
}
4、用户类实现
public class SqlserverUser implements IUser {
//新增一个用户
public void insert(User user){
System.out.println("在SQL Server中给User表增加一条记录");
}
//获取一个用户信息
public User getUser(int id){
System.out.println("在SQL Server中根据用户ID得到User表一条记录");
return null;
}
}
public class AccessUser implements IUser {
//新增一个用户
public void insert(User user){
System.out.println("在Access中给User表增加一条记录");
}
//获取一个用户信息
public User getUser(int id){
System.out.println("在Access中根据用户ID得到User表一条记录");
return null;
}
}
5、部门类接口
类似产品2
public interface IDepartment {
public void insert(Department department);
public Department getDepartment(int id);
}
6、部门类实现
public class SqlserverDepartment implements IDepartment {
//新增一个部门
public void insert(Department department){
System.out.println("在SQL Server中给Department表增加一条记录");
}
//获取一个部门信息
public Department getDepartment(int id){
System.out.println("在SQL Server中根据部门ID得到Department表一条记录");
return null;
}
}
public class AccessDepartment implements IDepartment {
//新增一个部门
public void insert(Department department){
System.out.println("在Access中给Department表增加一条记录");
}
//获取一个部门信息
public Department getDepartment(int id){
System.out.println("在Access中根据部门ID得到Department表一条记录");
return null;
}
}
7、工厂接口
public interface IFactory {
public IUser createUser();
public IDepartment createDepartment();
}
8、工厂实例化
public class SqlserverFactory implements IFactory {
public IUser createUser(){
return new SqlserverUser();
}
public IDepartment createDepartment(){
return new SqlserverDepartment();
}
}
public class AccessFactory implements IFactory {
public IUser createUser(){
return new AccessUser();
}
public IDepartment createDepartment(){
return new AccessDepartment();
}
}
9、测试和结果
public class Test {
public static void main(String[] args){
System.out.println("**********************************************");
System.out.println("《大话设计模式》代码样例");
System.out.println();
User user = new User();
Department department = new Department();
IFactory factory = new SqlserverFactory();
//IFactory factory = new AccessFactory();
IUser iu = factory.createUser();
iu.insert(user); //新增一个用户
iu.getUser(1); //得到用户ID为1的用户信息
IDepartment idept = factory.createDepartment();
idept.insert(department); //新增一个部门
idept.getDepartment(2); //得到部门ID为2的用户信息
System.out.println();
System.out.println("**********************************************");
}
}
结果
2、用简单工厂改进抽象工厂
1、添加简单工厂
public class DataAccess {
private static String db = "Sqlserver";//数据库名称,可替换成Access
//private static String db ="Access";
//创建用户对象工厂
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;
}
}
2、测试和结果
public class Test {
public static void main(String[] args){
System.out.println("**********************************************");
System.out.println("《大话设计模式》代码样例");
System.out.println();
User user = new User();
Department department = new Department();
//直接得到实际的数据库访问实例,而不存在任何依赖
IUser iu = DataAccess.createUser();
iu.insert(user); //新增一个用户
iu.getUser(1); //得到用户ID为1的用户信息
//直接得到实际的数据库访问实例,而不存在任何依赖
IDepartment idept = DataAccess.createDepartment();
idept.insert(department); //新增一个部门
idept.getDepartment(2); //得到部门ID为2的用户信息
System.out.println();
System.out.println("**********************************************");
}
}
结果
3、反射+抽象工厂
1、添加反射
public class DataAccess {
private static String assemblyName = "cn.bugstack.mybatis.learn.";
private static String db ="Sqlserver";//数据库名称,可替换成Access
//创建用户对象工厂
public static IUser createUser() {
return (IUser)getInstance(assemblyName + db + "User");
}
//创建部门对象工厂
public static IDepartment createDepartment(){
return (IDepartment)getInstance(assemblyName + db + "Department");
}
private static Object getInstance(String className){
Object result = null;
try{
result = Class.forName(className).getDeclaredConstructor().newInstance();
}
catch (InvocationTargetException e) {
e.printStackTrace();
}
catch (NoSuchMethodException e) {
e.printStackTrace();
}
catch (InstantiationException e) {
e.printStackTrace();
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
return result;
}
}
2、测试和结果
public class Test {
public static void main(String[] args){
System.out.println("**********************************************");
System.out.println("《大话设计模式》代码样例");
System.out.println();
User user = new User();
Department department = new Department();
//直接得到实际的数据库访问实例,而不存在任何依赖
IUser iu = DataAccess.createUser();
iu.insert(user); //新增一个用户
iu.getUser(1); //得到用户ID为1的用户信息
//直接得到实际的数据库访问实例,而不存在任何依赖
IDepartment idept = DataAccess.createDepartment();
idept.insert(department); //新增一个部门
idept.getDepartment(2); //得到部门ID为2的用户信息
System.out.println();
System.out.println("**********************************************");
}
}
结果
4、反射+配置文件+抽象工厂
1、添加反射和配置文件
public class DataAccess {
private static String assemblyName = "cn.bugstack.mybatis.learn.";
public static String getDb() {
String result="";
try{
Properties properties = new Properties();
//编译后,请将db.properties文件复制到要编译的class目录中,并确保下面path路径与
//实际db.properties文件路径一致。否则会报No such file or directory错误
String path=System.getProperty("user.dir")+"/cn/bugstack/mybatis/learn/db.properties";
System.out.println("path:"+path);
BufferedReader bufferedReader = new BufferedReader(new FileReader(path));
properties.load(bufferedReader);
result = properties.getProperty("db");
}
catch(IOException e){
e.printStackTrace();
}
return result;
}
//创建用户对象工厂
public static IUser createUser() {
String db=getDb();
return (IUser)getInstance(assemblyName + db + "User");
}
//创建部门对象工厂
public static IDepartment createDepartment(){
String db=getDb();
return (IDepartment)getInstance(assemblyName + db + "Department");
}
private static Object getInstance(String className){
Object result = null;
try{
result = Class.forName(className).getDeclaredConstructor().newInstance();
}
catch (InvocationTargetException e) {
e.printStackTrace();
}
catch (NoSuchMethodException e) {
e.printStackTrace();
}
catch (InstantiationException e) {
e.printStackTrace();
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
return result;
}
}
配置文件db.properties
db=Sqlserver
2、测试和结果
public class Test {
public static void main(String[] args){
System.out.println("**********************************************");
System.out.println("《大话设计模式》代码样例");
System.out.println();
User user = new User();
Department department = new Department();
//直接得到实际的数据库访问实例,而不存在任何依赖
IUser iu = DataAccess.createUser();
iu.insert(user); //新增一个用户
iu.getUser(1); //得到用户ID为1的用户信息
//直接得到实际的数据库访问实例,而不存在任何依赖
IDepartment idept = DataAccess.createDepartment();
idept.insert(department); //新增一个部门
idept.getDepartment(2); //得到部门ID为2的用户信息
System.out.println();
System.out.println("**********************************************");
}
}
结果