工廠設計模式解耦dao與service(註解和配置檔案)
阿新 • • 發佈:2018-12-11
在剛學習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();