java提供服務者框架

 服務提供者框架是指:多個服務提供者實現一個服務,系統爲客戶端提供多個實現,並把他們從多個實現中解耦出來。服務提供者的改變對它們的客戶端是透明的,這樣提供了更好的可擴展性。例如,JDBC,JMS等就是用了服務提供者框架java

      他們之間的關係以下圖:mysql

  


 
 

   1.服務具體實現類和服務提供者實現類是服務提供者本身去實現。以JDBC爲例,這2個模塊由具體的數據庫提供商來實現。sql

   2.其餘三個模塊是java對數據庫提供商怎麼實現上面2個模塊的一個約束。好比:提供服務者實現類必須實現服務提供者接口。才能成功註冊到服務提供者注 冊類。以JDBC爲例,全部的數據庫提供商只須要按照接口裏面定義的規則來操做,都能成功地使java連上他們的數據庫。數據庫

 

    下面以mysql數據庫爲例簡單說明一下mysql數據庫提供商是如何實現這些接口的。編程

    1.咱們在java中獲取mysql鏈接對象源代碼以下:框架

 

   

Java代碼  收藏代碼ide

  1. Class.forName("com.mysql.jdbc.Driver");   測試

  2. DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","123");  url

 

 

 

       從這個地方能夠看出:咱們只須要更換數據庫的驅動名稱與創建鏈接的URL,用戶名等信息,就能夠徹底切換到另一個數據庫。數據庫底部怎麼操做的咱們不清 楚,也不必清楚。咱們獲取的鏈接對象是Connection,查看java.sql.Connection這個類,會發現它只是一個接口。咱們獲得的只 是一個接口,怎麼可能可以操做數據庫呢?其實這裏獲得的不是Connection接口,而是它的一個實現類,只是對於客戶端不可見而已。這可能就是所謂的 面向接口編程,客戶端只須要知道它該知道的信息,服務端告訴客戶端,你能夠調用哪些方法。至於具體方法怎麼實現是服務端的事情,客服端就不須要管,也不需 要知道了。spa

     下面咱們看看簡單的這2個語句分別作了什麼事情:

      語句一: Class.forName("...")。這樣一個語句會實例化一個com.mysql.jdbc.Driver類(提供服務者實現類),並將這個類的實例註冊到DriverManager(服務提供者註冊類)。

       語句二: 經過創建鏈接的URL,用戶名,密碼來獲取創建到mysql數據庫的鏈接。是這樣的,DriverManager經過你傳進來的url信息判斷出你是要獲 取那個服務提供者提供的服務。也就是語句一已經將提供服務者實現類註冊到DriverManager了,DriverManager獲取到這個服務提供者 實現類對象以後,經過調用它的getService(mysql裏面是connect方法)方法獲取到服務具體實現類對象,返回的倒是 java.sql.Connection接口對象(由於服務具體實現類實現了Connection接口),這樣把服務具體實現類對象隱藏了。提供了很好的 擴展性。

      最後,咱們本身來測試一個。

      以北京地鐵進出控制爲例:如今北京地鐵進出都是刷卡,有二種卡:1.一卡通(好比一次性衝值50元,進地鐵刷一次,出地鐵刷一次,扣2元)。2.一次性卡 (進地鐵刷一次,出地鐵插入回收。)這2種卡均可以實現進出地鐵功能,但實現的具體方法是有區別的:一卡通:須要獲取這卡餘額是多少,而後扣掉2元。若是 餘額不足2元怎麼處理等。一次性卡則不必了。

     服務接口源碼:

 

   

Java代碼  收藏代碼

  1. /** 

  2.  * 進出地鐵服務接口 

  3.  * @author Administrator 

  4.  * 

  5.  */  

  6. public interface SubWayInterface {  

  7.       

  8.     //進入地鐵  

  9.     public boolean in();  

  10.       

  11.     //出地鐵  

  12.     public boolean out();  

  13.   

  14. }  

 

 

   

   服務實現源碼:

 

 

Java代碼  收藏代碼

  1. /** 

  2.  * 一卡通地鐵進出服務實現 

  3.  * @author Administrator 

  4.  * 

  5.  */  

  6. public class SubWayImpl implements SubWayInterface {  

  7.   

  8.     public boolean in() {  

  9.         System.out.println("經過一卡通進入地鐵");  

  10.         /** 

  11.          * 進行一些處理,而後返回是否放行 

  12.          */  

  13.         return false;  

  14.     }  

  15.   

  16.     public boolean out() {  

  17.         System.out.println("經過一卡通出地鐵");  

  18.         /** 

  19.          * 進行一些處理,而後返回是否放行 

  20.          */  

  21.         return false;  

  22.     }  

  23.   

  24. }  

 

 

    

   服務提供者接口源碼:

 

 

  

Java代碼  收藏代碼

  1. /** 

  2.  * 地鐵進出服務提供者接口 

  3.  * @author Administrator 

  4.  * 

  5.  */  

  6. public interface SubwayProviderInterface {  

  7.       

  8.     public SubWayInterface getService();  

  9.   

  10. }  

 

 

    服務提供者接口實現源碼:

 

 

   

Java代碼  收藏代碼

  1. /** 

  2.  * 服務提供者實現類 

  3.  * @author Administrator 

  4.  * 

  5.  */  

  6. public class SubwayProviderImpl implements SubwayProviderInterface {  

  7.   

  8.     static {  

  9.         ServiceManager.registerProvider("一卡通"new SubwayProviderImpl());  

  10.     }  

  11.   

  12.     public SubWayInterface getService() {  

  13.         return new SubWayImpl();  

  14.     }  

  15.   

  16. }  

  

 

   服務提供者註冊類實現源碼:

 

 

  

Java代碼  收藏代碼

  1. /** 

  2.  * 服務提供者註冊類 

  3.  *  

  4.  * @author Administrator 

  5.  *  

  6.  */  

  7. public class ServiceManager {  

  8.   

  9.     private ServiceManager() {  

  10.   

  11.     }  

  12.   

  13.     private static final Map<String, SubwayProviderInterface> providers = new ConcurrentHashMap<String, SubwayProviderInterface>();  

  14.   

  15.     public static void registerProvider(String name, SubwayProviderInterface p) {  

  16.         providers.put(name, p);  

  17.     }  

  18.   

  19.     public static SubWayInterface getService(String name) {  

  20.   

  21.         SubwayProviderInterface p = providers.get(name);  

  22.   

  23.         if (p == null) {  

  24.             throw new IllegalArgumentException(  

  25.                     "No provider registered with name:" + name);  

  26.         }  

  27.   

  28.         return p.getService();  

  29.   

  30.     }  

  31.   

  32. }  

  

 

     客戶端測試類:

 

    

Java代碼  

  1. /** 

  2.  * 客戶端測試類 

  3.  * @author Administrator 

  4.  * 

  5.  */  

  6. public class Test {  

  7.   

  8.     /** 

  9.      * @param args 

  10.      * @throws ClassNotFoundException  

  11.      */  

  12.     public static void main(String[] args) throws ClassNotFoundException {  

  13.           

  14.         Class.forName("cn.netjava.cgl.subway.SubwayProviderImpl");  

  15.         SubWayInterface swi = ServiceManager.getService("一卡通");  

  16.         swi.in();  

  17.         swi.out();  

  18.     }  

  19. }  

 

   測試類Class.forName("")裏面的參數你可能跟個人不一樣,看你服務提供者實現類放在哪一個包下面了。個人是在:cn.netjava.cgl.subway包下面。

相關文章
相關標籤/搜索