多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > 互聯網 > Google Guice之牛刀小試

Google Guice之牛刀小試

來源:程序員人生   發布時間:2014-11-26 08:11:02 閱讀次數:3062次
Google Guice由google推出的1開源軟件,是超輕量級的,下1代的,為Java 5及后續版本設計的依賴注入容器,其功能類似于如日中天的Spring。

下面我們就來了解1下Guice,在此之前,先看1個官方例子:在利用程序中,要把所有的東西裝配起來是1件很乏味的事件,這要觸及到連接數據,服務,表現層類等方面,這是1個比薩餅訂購網站的計費代碼例子用于這些方面的對照。

public interface BillingService { /** * Attempts to charge the order to the credit card. Both successful and * failed transactions will be recorded. * * @return a receipt of the transaction. If the charge was successful, the * receipt will be successful. Otherwise, the receipt will contain a * decline note describing why the charge failed. */ Receipt chargeOrder(PizzaOrder order, CreditCard creditCard); }

BillingService的實現類,我們會用單元測試進行測試,剩下的我們需要1個FakeCreditCardProcessor來避免其直接與CreditCard打交道,這是面向對象中封裝的表現。
第1種實現方式:直接調用構造方法:

public class RealBillingService implements BillingService { public Receipt chargeOrder(PizzaOrder order, CreditCard creditCard) { CreditCardProcessor processor = new PaypalCreditCardProcessor();//構造方法創建CreditCardProcessor TransactionLog transactionLog = new DatabaseTransactionLog();//構造方法創建TransactionLog對象 try { ChargeResult result = processor.charge(creditCard, order.getAmount()); transactionLog.logChargeResult(result); return result.wasSuccessful() ? Receipt.forSuccessfulCharge(order.getAmount()) : Receipt.forDeclinedCharge(result.getDeclineMessage()); } catch (UnreachableException e) { transactionLog.logConnectException(e); return Receipt.forSystemFailure(e.getMessage()); } } }

這樣的代碼缺少模塊性與可測試性,由于這在編譯期就直接依賴了CreditCardProcessor實現類,耦合性太強。

第2種實現方式:使用工廠模式:
使用1個工廠類可使客戶端與實現解耦,1個簡單工廠使用1靜態方法來獲得或設置接口實現,下面是1樣版:


public class CreditCardProcessorFactory { private static CreditCardProcessor instance; public static void setInstance(CreditCardProcessor creditCardProcessor) { instance = creditCardProcessor; } public static CreditCardProcessor getInstance() { if (instance == null) { return new SquareCreditCardProcessor(); } return instance; } }

在客戶端代碼中,只需要使用工廠類把new關鍵字替換就好了:


public class RealBillingService implements BillingService { public Receipt chargeOrder(PizzaOrder order, CreditCard creditCard) { CreditCardProcessor processor = CreditCardProcessorFactory.getInstance(); TransactionLog transactionLog = TransactionLogFactory.getInstance(); try { ChargeResult result = processor.charge(creditCard, order.getAmount()); transactionLog.logChargeResult(result); return result.wasSuccessful() ? Receipt.forSuccessfulCharge(order.getAmount()) : Receipt.forDeclinedCharge(result.getDeclineMessage()); } catch (UnreachableException e) { transactionLog.logConnectException(e); return Receipt.forSystemFailure(e.getMessage()); } } }

在使用了工廠模式后的單元測試:

public class RealBillingServiceTest extends TestCase { private final PizzaOrder order = new PizzaOrder(100); private final CreditCard creditCard = new CreditCard("1234", 11, 2010); private final InMemoryTransactionLog transactionLog = new InMemoryTransactionLog(); private final FakeCreditCardProcessor creditCardProcessor = new FakeCreditCardProcessor(); @Override public void setUp() { TransactionLogFactory.setInstance(transactionLog); CreditCardProcessorFactory.setInstance(creditCardProcessor); } @Override public void tearDown() { TransactionLogFactory.setInstance(null); CreditCardProcessorFactory.setInstance(null); } public void testSuccessfulCharge() { RealBillingService billingService = new RealBillingService(); Receipt receipt = billingService.chargeOrder(order, creditCard); assertTrue(receipt.hasSuccessfulCharge()); assertEquals(100, receipt.getAmountOfCharge()); assertEquals(creditCard, creditCardProcessor.getCardOfOnlyCharge()); assertEquals(100, creditCardProcessor.getAmountOfOnlyCharge()); assertTrue(transactionLog.wasSuccessLogged()); } }

這樣代碼還是有點笨拙,1個全局變量保存了實現實例,這樣我們要非常謹慎該變量的賦值與值釋放,如果tailDown方法失敗了,
全局變量依然有效,這可能就會給其它的測試帶來問題,這樣還不能并行運行多個測試用例。最大的問題在于,隨著利用的擴大,
有新的依賴的時候就會出現愈來愈多的工廠類,使利用效力降落。

第3種方式:依賴注入
像工廠模式1樣,依賴注入也是1種設計模式,其主要原則是將行動與依賴分離開來,在上面的例子中RealBillingService不負責TransactionLog與CreditCardProcessor對象的創建,換之的是這兩個對象在RealBillingService的構造方法參數中傳遞進來。


public class RealBillingService implements BillingService { private final CreditCardProcessor processor; private final TransactionLog transactionLog; public RealBillingService(CreditCardProcessor processor, TransactionLog transactionLog) { this.processor = processor; this.transactionLog = transactionLog; } public Receipt chargeOrder(PizzaOrder order, CreditCard creditCard) { try { ChargeResult result = processor.charge(creditCard, order.getAmount()); transactionLog.logChargeResult(result); return result.wasSuccessful() ? Receipt.forSuccessfulCharge(order.getAmount()) : Receipt.forDeclinedCharge(result.getDeclineMessage()); } catch (UnreachableException e) { transactionLog.logConnectException(e); return Receipt.forSystemFailure(e.getMessage()); } } }

這樣,我們不需要任何的工廠類,還可以移除setUp與tearDown方法來簡化單元測試:

public class RealBillingServiceTest extends TestCase { private final PizzaOrder order = new PizzaOrder(100); private final CreditCard creditCard = new CreditCard("1234", 11, 2010); private final InMemoryTransactionLog transactionLog = new InMemoryTransactionLog(); private final FakeCreditCardProcessor creditCardProcessor = new FakeCreditCardProcessor(); public void testSuccessfulCharge() { RealBillingService billingService = new RealBillingService(creditCardProcessor, transactionLog); Receipt receipt = billingService.chargeOrder(order, creditCard); assertTrue(receipt.hasSuccessfulCharge()); assertEquals(100, receipt.getAmountOfCharge()); assertEquals(creditCard, creditCardProcessor.getCardOfOnlyCharge()); assertEquals(100, creditCardProcessor.getAmountOfOnlyCharge()); assertTrue(transactionLog.wasSuccessLogged()); } }

現在不幸的是,BillingService的客戶端需要創建它的依賴,現在最好是有1框架來自動創建這些依賴,不然我們就要手動地去創建這些循環依賴。


現在到Guice出場的時候,使用Guice進行依賴注入

依賴注入模式可讓代碼更具模塊性,更容易于測試,而且Guice使其易于編寫。在上面的計費例子中,我們第1步要告知Guice怎樣映照接口與實現類,這是通過Guice的Module進行配置的,它可以是任何1個實現了Module接口的Java類。

public class BillingModule extends AbstractModule { @Override protected void configure() { bind(TransactionLog.class).to(DatabaseTransactionLog.class);//將接口與實現進行映照綁定 bind(CreditCardProcessor.class).to(PaypalCreditCardProcessor.class); bind(BillingService.class).to(RealBillingService.class); } }

當進行依賴注入的時候,對象在它們的構造參數中接收依賴。要創建1個對象,必須先創建出它的依賴,但是要創建每個依賴,就要創建依賴的每個依賴,如此往復。所以當你創建1個對象的時候真正要創建的是1張對象圖。手動創建1張對象圖是費勞力的,趨于毛病的,而且使測試變得困難。好在Guice可以為我們創建這張對象圖,而我們要做的就是進行配置告知它如果去準確地創建這張對象圖。

在RealBillingService的構造方法中添加@Inject注解,Guice會檢查添加了注解的構造方法,并為每個參數查找值。
添加@Inject注解就是在進行配置式作,告知Guice如果創建對象圖,固然@Inject注解不但可以放置于構造方法上,也能夠放置于setter方法與字段上。


public class RealBillingService implements BillingService { private final CreditCardProcessor processor; private final TransactionLog transactionLog; @Inject public RealBillingService(CreditCardProcessor processor, TransactionLog transactionLog) { this.processor = processor; this.transactionLog = transactionLog; } public Receipt chargeOrder(PizzaOrder order, CreditCard creditCard) { try { ChargeResult result = processor.charge(creditCard, order.getAmount()); transactionLog.logChargeResult(result); return result.wasSuccessful() ? Receipt.forSuccessfulCharge(order.getAmount()) : Receipt.forDeclinedCharge(result.getDeclineMessage()); } catch (UnreachableException e) { transactionLog.logConnectException(e); return Receipt.forSystemFailure(e.getMessage()); } } }

最后,我們將這些整合在1起以下,Injector類用于獲得任何綁定類的實例:

public static void main(String[] args) { Injector injector = Guice.createInjector(new BillingModule()); BillingService billingService = injector.getInstance(BillingService.class); ... }



生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 美国免费高清一级毛片 | 国产精品夜色视频一级区 | 国内自拍小视频 | 亚洲国产精品久久卡一 | 国产欧美精品一区二区 | 亚洲免费成人 | 国产成人精品午夜在线播放 | 亚洲女人天堂a在线播放 | 亚洲三级黄色 | 波多野结衣91 | 日韩精品一区二区三区毛片 | 久久国产经典视频 | 美女网站免费看 | 91久久九九精品国产综合 | 日韩一区二区三区四区 | 麻豆亚洲精品一区二区 | 亚洲高清免费 | 久久亚洲一级α片 | 欧美videos粗暴高清性 | 精品一区二区三区四区乱码90 | 最近中文字幕免费高清mv | 久久久久成人精品一区二区 | 国产亚洲网站 | 国产video| 91www在线观看 | 亚洲综合一区二区精品久久 | 激情另类国内一区二区视频 | 亚洲视频在线观看 | tube12xxxxhd曰本 | 小说区图片区综合视频区 | 国产精品一二三区 | 91亚洲在线| 亚洲天堂.com | 波多野结衣一级视频 | 一级欧美日韩 | 国产啪视频1000部免费视频 | xxx暴力xxx | 亚洲欧美四级在线播放 | 精品在线播放 | 羞羞免费网站在线 | 最近手机中文字幕大全8 |