关于Facade的应用
Facade用的非常的广了,以前刚接触的时候有个误解,总觉得Facade是简单的,而它后面的支撑服务是复杂的,对于客户来说却是简单的,现在来看,不完全对,或者说只是说对了一半,因为有时候恰恰是Facade是复杂的.
我们举一个例子,比如发送短信,我们一般就定义一个MessageService的服务类,里面只提供一个方法就行了,sendToUser(String phone,String content)
但是到了客户端的时候有了自己的 "方言",比如它不是关心一个抽象的用户,它只知道向教师发送短信,或者向学生发送短信,或者向家长发送短信。
示例如下:
由图中可以看到,Facade的内容非常丰富,而支撑它的服务类却很简单,在开发过程中我们一般先实现通用的ServiceA,然后根据进一步的需求做一个面向具体复杂的Facade.
在Spring提供的sample里发现一个小技巧,就是Facade和ServiceA都是接口,然后提供一个实现二者的支撑类:
看起来似乎不错,不过仔细想想个人认为还是不是太好,总的感觉就是层次不清晰,因为很多时候Facade和Service之间是被服务与服务的关系,所以理当分开。 同时,这个类有点倾向于"万能类"了,能分还是分开好.这和我们以前提到的dao又背离过来了(以前我们提倡一个业务一个dao,现在觉得只用一个通用的dao更合适),这个并不矛盾,具体问题具体看待.
欢迎各位拍砖.
我们举一个例子,比如发送短信,我们一般就定义一个MessageService的服务类,里面只提供一个方法就行了,sendToUser(String phone,String content)
但是到了客户端的时候有了自己的 "方言",比如它不是关心一个抽象的用户,它只知道向教师发送短信,或者向学生发送短信,或者向家长发送短信。
示例如下:
由图中可以看到,Facade的内容非常丰富,而支撑它的服务类却很简单,在开发过程中我们一般先实现通用的ServiceA,然后根据进一步的需求做一个面向具体复杂的Facade.
在Spring提供的sample里发现一个小技巧,就是Facade和ServiceA都是接口,然后提供一个实现二者的支撑类:
public
class
PetStoreAnnotationImpl
implements
PetStoreFacade, OrderService {
private AccountDao accountDao;
private CategoryDao categoryDao;
private ProductDao productDao;
private ItemDao itemDao;
private OrderDao orderDao;
// -------------------------------------------------------------------------
// Setter methods for dependency injection
// -------------------------------------------------------------------------
public void setAccountDao(AccountDao accountDao) {
this .accountDao = accountDao;
}
public void setCategoryDao(CategoryDao categoryDao) {
this .categoryDao = categoryDao;
}
public void setProductDao(ProductDao productDao) {
this .productDao = productDao;
}
public void setItemDao(ItemDao itemDao) {
this .itemDao = itemDao;
}
public void setOrderDao(OrderDao orderDao) {
this .orderDao = orderDao;
}
// -------------------------------------------------------------------------
// Operation methods, implementing the PetStoreFacade interface
// -------------------------------------------------------------------------
public Account getAccount(String username) {
return this .accountDao.getAccount(username);
}
public Account getAccount(String username, String password) {
return this .accountDao.getAccount(username, password);
}
public void insertAccount(Account account) {
this .accountDao.insertAccount(account);
}
public void updateAccount(Account account) {
this .accountDao.updateAccount(account);
}
public List getUsernameList() {
return this .accountDao.getUsernameList();
}
public List getCategoryList() {
return this .categoryDao.getCategoryList();
}
public Category getCategory(String categoryId) {
return this .categoryDao.getCategory(categoryId);
}
public List getProductListByCategory(String categoryId) {
return this .productDao.getProductListByCategory(categoryId);
}
public List searchProductList(String keywords) {
return this .productDao.searchProductList(keywords);
}
public Product getProduct(String productId) {
return this .productDao.getProduct(productId);
}
public List getItemListByProduct(String productId) {
return this .itemDao.getItemListByProduct(productId);
}
public Item getItem(String itemId) {
return this .itemDao.getItem(itemId);
}
public boolean isItemInStock(String itemId) {
return this .itemDao.isItemInStock(itemId);
}
public void insertOrder(Order order) {
this .orderDao.insertOrder(order);
this .itemDao.updateQuantity(order);
}
public Order getOrder( int orderId) {
return this .orderDao.getOrder(orderId);
}
public List getOrdersByUsername(String username) {
return this .orderDao.getOrdersByUsername(username);
}
}
private AccountDao accountDao;
private CategoryDao categoryDao;
private ProductDao productDao;
private ItemDao itemDao;
private OrderDao orderDao;
// -------------------------------------------------------------------------
// Setter methods for dependency injection
// -------------------------------------------------------------------------
public void setAccountDao(AccountDao accountDao) {
this .accountDao = accountDao;
}
public void setCategoryDao(CategoryDao categoryDao) {
this .categoryDao = categoryDao;
}
public void setProductDao(ProductDao productDao) {
this .productDao = productDao;
}
public void setItemDao(ItemDao itemDao) {
this .itemDao = itemDao;
}
public void setOrderDao(OrderDao orderDao) {
this .orderDao = orderDao;
}
// -------------------------------------------------------------------------
// Operation methods, implementing the PetStoreFacade interface
// -------------------------------------------------------------------------
public Account getAccount(String username) {
return this .accountDao.getAccount(username);
}
public Account getAccount(String username, String password) {
return this .accountDao.getAccount(username, password);
}
public void insertAccount(Account account) {
this .accountDao.insertAccount(account);
}
public void updateAccount(Account account) {
this .accountDao.updateAccount(account);
}
public List getUsernameList() {
return this .accountDao.getUsernameList();
}
public List getCategoryList() {
return this .categoryDao.getCategoryList();
}
public Category getCategory(String categoryId) {
return this .categoryDao.getCategory(categoryId);
}
public List getProductListByCategory(String categoryId) {
return this .productDao.getProductListByCategory(categoryId);
}
public List searchProductList(String keywords) {
return this .productDao.searchProductList(keywords);
}
public Product getProduct(String productId) {
return this .productDao.getProduct(productId);
}
public List getItemListByProduct(String productId) {
return this .itemDao.getItemListByProduct(productId);
}
public Item getItem(String itemId) {
return this .itemDao.getItem(itemId);
}
public boolean isItemInStock(String itemId) {
return this .itemDao.isItemInStock(itemId);
}
public void insertOrder(Order order) {
this .orderDao.insertOrder(order);
this .itemDao.updateQuantity(order);
}
public Order getOrder( int orderId) {
return this .orderDao.getOrder(orderId);
}
public List getOrdersByUsername(String username) {
return this .orderDao.getOrdersByUsername(username);
}
}
看起来似乎不错,不过仔细想想个人认为还是不是太好,总的感觉就是层次不清晰,因为很多时候Facade和Service之间是被服务与服务的关系,所以理当分开。 同时,这个类有点倾向于"万能类"了,能分还是分开好.这和我们以前提到的dao又背离过来了(以前我们提倡一个业务一个dao,现在觉得只用一个通用的dao更合适),这个并不矛盾,具体问题具体看待.
欢迎各位拍砖.