设计模式-抽象工厂模式

UML类图

在这里插入图片描述

使用场景

有这样一种应用场景,如一套系统要给两个公式用,但是这两个公司要求的数据库不一样,一个是mysql,另一个是sqlserver,那么如何实现数据库的灵活切换,实现代码的松耦合?抽象工厂模式就是一种不错的选择。抽象工厂模式和工厂模式的区别在于工厂模式只有一种产品,抽象工厂模式有多种类型的产品。

代码实现

public interface UserDao {
	public void save();
}
public class UserMysqlDao implements UserDao{
	public void save(){
		System.out.println("mysql user save");
	}
}
public class UserSqlServerDao implements UserDao{
	public void save(){
		System.out.println("sqlserver user save");
	}
}
public interface DepartmentDao {
	public void save();
}
public class DepartmentMysqlDao implements DepartmentDao{
	public void save(){
		System.out.println("mysql department save");
	}
}
public class DepartmentSqlserverDao implements DepartmentDao{
	public void save(){
		System.out.println("sqlserver department save");
	}
}
public interface DaoFactory {
	public UserDao createUserDao();
	public DepartmentDao createDepartmentDao();
}
public class MysqlFactory implements DaoFactory{
	@Override
	public UserDao createUserDao() {
		return new UserMysqlDao();
	}
	@Override
	public DepartmentDao createDepartmentDao() {
		return new DepartmentMysqlDao();
	}
}
public class SqlserverFactory implements DaoFactory{
	@Override
	public UserDao createUserDao() {
		return new UserSqlServerDao();
	}
	@Override
	public DepartmentDao createDepartmentDao() {
		return new DepartmentSqlserverDao();
	}
}
public class Main {
	public static void main(String[] args) {
		//mysql
		DaoFactory factory = new MysqlFactory();
		UserDao dao = factory.createUserDao();
		dao.save();
		DepartmentDao dao2 = factory.createDepartmentDao();
		dao2.save();
		
		//sqlserver
		DaoFactory factory2 = new SqlserverFactory();
		UserDao _dao = factory2.createUserDao();
		_dao.save();
		DepartmentDao _dao2 = factory2.createDepartmentDao();
		_dao2.save();
	}
}

抽象工厂模式的缺点

抽象工厂模式的缺点是显而易见的,虽然实现了解耦,但是如果要增加一个Dao,需要同时修改很多个类。这里用简单工厂加反射代替实现解耦。

修改工厂类

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Properties;


public class Factory {
	Properties prop = new Properties();
	public Factory(){
		try {
			prop.load(Factory.class.getResourceAsStream("config.properties"));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public UserDao createUserDao(){
		try {
			Class<?> clazz = Class.forName(prop.getProperty("UserDao"));
			Constructor<?> con = clazz.getConstructor(null);
			return (UserDao)con.newInstance(null);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public DepartmentDao createDepartmentDao(){
		try {
			Class<?> clazz = Class.forName(prop.getProperty("DepartmentDao"));
			Constructor<?> con = clazz.getConstructor(null);
			return (DepartmentDao)con.newInstance(null);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return null;		
	}
}

客户端类

public class Main {
	public static void main(String[] args) {
		Factory factory = new Factory();
		UserDao userDao = factory.createUserDao();
		userDao.save();
		
		DepartmentDao departmentDao = factory.createDepartmentDao();
		departmentDao.save();
	}
}

配置文件config.properties

UserDao=UserMysqlDao
DepartmentDao=DepartmentMysqlDao

以上,无需修改源码,只需在config.properties配置文件中修改成的对应的类即可实现数据库的灵活切换。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值