关于Facade的应用

关于Facade的应用
Facade用的非常的广了,以前刚接触的时候有个误解,总觉得Facade是简单的,而它后面的支撑服务是复杂的,对于客户来说却是简单的,现在来看,不完全对,或者说只是说对了一半,因为有时候恰恰是Facade是复杂的.

我们举一个例子,比如发送短信,我们一般就定义一个MessageService的服务类,里面只提供一个方法就行了,sendToUser(String phone,String content)
但是到了客户端的时候有了自己的 "方言",比如它不是关心一个抽象的用户,它只知道向教师发送短信,或者向学生发送短信,或者向家长发送短信。

示例如下:

facade.png
由图中可以看到,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);
    }

}


看起来似乎不错,不过仔细想想个人认为还是不是太好,总的感觉就是层次不清晰,因为很多时候Facade和Service之间是被服务与服务的关系,所以理当分开。 同时,这个类有点倾向于"万能类"了,能分还是分开好.这和我们以前提到的dao又背离过来了(以前我们提倡一个业务一个dao,现在觉得只用一个通用的dao更合适),这个并不矛盾,具体问题具体看待.

欢迎各位拍砖.

你可能感兴趣的:(关于Facade的应用)