1. 程式人生 > >工廠設計模式解耦dao與service(註解和配置檔案)

工廠設計模式解耦dao與service(註解和配置檔案)

在剛學習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();