设计模式之工厂模式----抽象工厂实例:解决系统依赖于单一数据库的问题

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)	// 默认是RetentionPolicy.CLASS。注解保留到class文件,jvm加载class后,遗弃注解。RetentionPolicy.RUNTIME直到jvm加载class,注解一致保留。
public @interface FieldName{
	String name();
}
public class Student{
	@FeldName(name = "STU_NAME");	// 加注解,对应数据库字段
	private String name;
	@FieldName(name = "STU_ID");
	private String id;
}
public interface StudentDao{
	int addStudent(Strudent student);
}
// 数据库操作
public class StudentDoaImpl() implements StudentDao{
	private Conntction connection;
	public StudentDaoImpl(Connection connetcion){
		this.connection = connection;
	}
	@Override
	public int addStudent(Student student){
		// 首先获取student各个属性值。以及属性名。
		StringBuilder sql = new StringBulider("INSRT INTO student_t(")	// 根据student的属性注解决定给哪个字段赋值。字段写死sql语句会依赖于student的字段,不方便修改,插入字段动态获取,把sql语句与student的字段进行解耦,插入字段修改,sql不必改变。
		StringBuilder fieldName = new StringBuilder();
		StringBuilder fieldValue = new StringBuilder();
		DeclaredField[] declaredFileds = student.getClass.getDeclaredFields();
		try{
			for(Field field: declaredFileds){
				field.setAccessible(true);
				FieldName annotation = field.getAnnotation(FieldName.class);
				String name = annotation.name(); // 获取注解值
				fieldName.append(name + ",");
				fieldValue.append("?,");	// 对插入值的处理交给JDBC。
			}
		}catch(Exception e){
			e.peintStackTrace();
			return 0;
		}
		// 删除最后一个‘,’
		fieldName.delete(fieldName.lastIndexOf(","), fieldName.length());
		fieldValue.delete(fieldName.lastIndexOF("'"), fieldValue.length());
		sql.append(fieldName)
			.append(")"
			.append("VALUES(")
			.append(fieldValue)
			.append(")");
		// sql准备完毕,进行预编译,然后给占位符赋值
		try{
			PreparedStatement prepareStatement = connection.preparedStatement(sql.toString());
			int i = 1;
			// declaredFiled数组顺序与准备sql是的declaredFileds的数组顺序一致
			// 赋值时可直接通过索引进行赋值
			for(Field field: declaredFileds){
				field.setAccessible(true);
				Object value = "";
                value = field.get(student);
                preparedStatement.setObject(i,value);
                i++;
			}
            return preparedStatement.executeUpdate();
		}catch(Excetion e){
			e.printStackTrace();
			return 0;
		}
	}
}

// 以下是抽象工厂模式的实例
// 抽象工厂
public abstract DaoFactory{
	// 通过抽象工厂获取具体工厂
	public static final int MYSQL = 1;
	public static final int SQLSERVER = 2; 
	public static getDaoFactory(int flag){
		switch(flag){
			case: MYSQL
				return new MySQLFactory;
			case: SQLSERVER
				return new SqlServerFactory;
	}
	public abstract StudentDao getStudentDao();
}
// 具体工厂MySQLFactory 
public class MySQLFactory extends DaoFactory{
	private final String driverName="";
	private final String url = "";
	private final String user = "";
	private final String password = ";
	@Override
	public StuedntDao getStudentDao(){
		try{
			Class.forName(driverName);
			Connection connection = DriverManger.getConnection(url, user, password);
			return new StudentDaoImpl(connection)
		}catch(Exception e){
			e.printStackTrace();
			return null;
		}
	}
}
// 具体工厂SqlServerFactory
public class SqlServerFactory extends DaoFactory{
	private final String driverName="";
	private final String url = "";
	private final String user = "";
	private final String password = ";
	@Override
	public StuedntDao getStudentDao(){
		try{
			Class.forName(driverName);
			Connection connection = DriverManger.getConnection(url, user, password);
			return new StudentDaoImpl(connection)
		}catch(Exception e){
			e.printStackTrace();
			return null;
		] 
	}
}
// 优化,把getStudentDao()的逻辑写在DaoFactory中,MySQLFactory/SqlServerFactory只对四个属性进行赋值。
// 使用
public class Client{
	psvm(){
		Student student = new Student(1, "test");
		DaoFactory factory = DaoFactory.getDaoFactory(DaoFactory.MySQL);	// 获取具体工厂
		StudentDao studentDao = factory.getStudentDao(); // 具体工厂返回”产品“对象
		int x = studentDao.addStudent(student);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值