在刚学习web时,我的service层的代码往往这样写
public class OrderService {
OrderDao od=new OrderDao();
public Order findOrderItemsByOrderId(String orderid) {
try {
return od.findOrderItemsByOrderId(orderid);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
但是在慢慢接触设计模式和面向对象设计时。传统的service层包含dao的弊端:
1.service含有OrderDao属性,与OrderDao有耦合,一旦我们的DAO层从mysql数据库改成oracle,那么service层的代码需要修改,这是不符合面向对象设计的OP原则的。
2.开发中往往service、dao并行完成,但是service层又需要调用dao层的CRUD方法,这意味着dao必须先于service完成。这在开发中会极大降低效率的。
所以我们有两种改进方法(都是通过工厂设计模式解耦)
一丶写一个bean.properties配置文件
创建工厂类:
public class BeanFactory {
private static ResourceBundle bundle ;
private static BeanFactory factory = new BeanFactory();
private BeanFactory(){
}
static{
bundle = ResourceBundle.getBundle("com.itheima.properties.bean");
}
public static BeanFactory newInstance(){
return factory;
}
//生产DAO,拿到对象
public Object getDao(String className) {
try {
Object obj = null;
String classPath = bundle.getString(className);
obj = Class.forName(classPath).newInstance();
return obj;
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
}
serivice层
public class UserServiceImpl implements IUserService {
private IUserDao dao = (IUserDao)BeanFactory.newInstance().getDao("USERDAO");
}
对UserDao的实现有多种如:UserDaoJdbcImpl、UserDaoHibernateImpl
我们只需要改配置文件
二丶通过注解(Annotatoin)我们可以轻松实现两个层次的解耦
首先写一个注解类
@Retention(RetentionPolicy.RUNTIME)
public @interface getClassAnnotation{
public String className();
}
在dao层写一个工厂
public class UserDaoFactory {
private String userDaoClassName;
private static UserDaoFactory instance = new UserDaoFactory();
private UserDaoFactory(){
ClassNameAnnotaton annotation = UserDao.class.getAnnotation(ClassNameAnnotaton.class);
this.userDaoClassName = annotation.className();
}
public static UserDaoFactory newInstance(){
return instance;
}
public UserDao getUserDao(){
try {
return (UserDao)Class.forName(userDaoClassName).newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
//在UserDao接口中注解对应的className
@ClassNameAnnotaton(className="cn.itcast.dao.UserDaoHibernateImpl")
public interface UserDao {
public User getUser(String id);
public boolean save(User user);
public boolean delete(String id);
public User update(User user);
}
对UserDao的实现有多种如:UserDaoJdbcImpl、UserDaoHibernateImpl
只需要在接口上标明是哪一个实现类
这样一来在Service层就可以直接通过工厂获得dao实现类
UserDao dao = UserDaoFactory.newInstance().getUserDao();