工廠模式,是一種建立型設計模式,其在父類中提供一個建立對象的方法,容許子類決定實例化對象的類型。java
工廠模式是 Java 開發中最多見的一種模式,其主要意圖是定義一個建立對象的接口,讓其子類決定實例化哪個工廠類,工廠模式使其建立過程延遲到子類進行。設計模式
簡單說就是爲了提供代碼的可擴展性,屏蔽每個功能類中的具體實現邏輯。讓外部能夠更加簡單的調用。同時,能夠去掉衆多 ifelse
。ide
優勢: 一、一個調用者想建立一個對象,只要知道其名稱就能夠了。 二、擴展性高,若是想增長一個產品,只要擴展一個工廠類就能夠。 三、屏蔽產品的具體實現,調用者只關心產品的接口。測試
缺點:每次增長一個產品時,都須要增長一個具體類和對象實現工廠,使得系統中類的個數成倍增長,在必定程度上增長了系統的複雜度,同時也增長了系統具體類的依賴。這並非什麼好事。優化
營銷場景中常常會有抽獎活動,咱們在這裏模擬兌換多種類型的商品。設計
假如咱們有以下三種類型的商品接口:code
序號 | 類型 | 接口 |
---|---|---|
1 | 代金劵 | VoucherResult sendVoucher(String userId, String voucherId, int voucherNumber) |
2 | VIP體驗卡 | void openVIP(String userId, Date date, String time) |
3 | 實物獎品 | Boolean deliverGoods(DeliverRequest req) |
public class PrizeController { private static final String CODE_SUCCESS = "11111111"; private static final String CODE_FAIL = "00000000"; public AwardResult awardToUser(AwardRequest req) { AwardResult res = null; // 按照不一樣類型分法商品[1代金劵、2VIP體驗卡、3實物獎品] if (req.getAwardType() == 1) { VoucherService voucherService = new VoucherService(); VoucherResult voucherResult = voucherService.sendVoucher(req.getUserId(), req.getAwardId(), req.getAwardNumber()); if (CODE_SUCCESS.equals(voucherResult.getCode())) { res = new AwardResult(CODE_SUCCESS, "成功"); } else { res = new AwardResult(CODE_FAIL, voucherResult.getInfo()); } } else if (req.getAwardType() == 2) { VIPService vipService = new VIPService(); Date date = new Date(System.currentTimeMillis()); vipService.openVip(req.getUserId(), date, req.getTime()); res = new AwardResult(CODE_SUCCESS, "成功"); } else if (req.getAwardType() == 3) { GoodsService goodsService = new GoodsService(); DeliverRequest deliverRequest = new DeliverRequest(); deliverRequest.setUserId(req.getUserId()); deliverRequest.setUserName(queryUserNameById(req.getUserId())); deliverRequest.setUserPhone(queryUserPhoneById(req.getUserId())); deliverRequest.setUserAddress(queryUserAddressById(req.getUserId())); Boolean isSuccess = goodsService.deliverGoods(deliverRequest); if (isSuccess) { res = new AwardResult(CODE_SUCCESS, "成功"); } else { res = new AwardResult(CODE_FAIL, "失敗"); } } return res; } public String queryUserNameById(String userId) { return "Tom"; } public String queryUserPhoneById(String userId) { return "123456789"; } public String queryUserAddressById(String userId) { return "BeiJin"; } }
ifelse
實現業務需求。若是僅從業務角度看,已經實現了基本功能。@Test public void testAwardToUser() { PrizeController prizeController = new PrizeController(); AwardResult awardResult = null; System.out.println("******模擬多種獎品發放測試******"); AwardRequest awardReq = new AwardRequest(); awardReq.setAwardId("0001"); awardReq.setAwardNumber(1); awardReq.setUserId("10001"); System.out.println("\n------ 代金券的發放 ------"); awardReq.setAwardType(1); awardResult = prizeController.awardToUser(awardReq); System.out.println("代金券發放結果:" + awardResult.getRes()); System.out.println("\n------ VIP體驗卡的發放 -------"); awardReq.setAwardType(2); awardResult = prizeController.awardToUser(awardReq); System.out.println("VIP體驗卡發放結果:" + awardResult.getRes()); System.out.println("\n------ 實物獎品的發放 -------"); awardReq.setAwardType(3); awardResult = prizeController.awardToUser(awardReq); System.out.println("實物獎品發放結果:" + awardResult.getRes()); }
結果:對象
public interface IAward { void sendAward(String userId, String awardId, Map<String, Object> map); }
代金券blog
public class VoucherAwardService implements IAward{ private VoucherService voucherService = new VoucherService(); @Override public void sendAward(String userId, String awardId, Map<String, Object> map) throws Exception{ VoucherResult voucherResult = voucherService.sendVoucher(userId, awardId, (int) map.get("voucherNumber")); if (PrizeController.CODE_FAIL.equals(voucherResult.getCode())) { throw new RuntimeException("失敗"); } } }
VIP體驗卡接口
public class VIPAwardService implements IAward{ private VIPService vipService = new VIPService(); @Override public void sendAward(String userId, String awardId, Map<String, Object> map) throws Exception { Date date = new Date(System.currentTimeMillis()); vipService.openVip(userId, (Date) map.get("data"), (String) map.get("time")); } }
實物獎品
public class GoodsAwardService implements IAward{ private GoodsService goodsService = new GoodsService(); @Override public void sendAward(String userId, String awardId, Map<String, Object> map) throws Exception { DeliverRequest deliverRequest = new DeliverRequest(); deliverRequest.setUserId(userId); deliverRequest.setUserName(queryUserNameById(userId)); deliverRequest.setUserPhone(queryUserPhoneById(userId)); deliverRequest.setUserAddress(queryUserAddressById(userId)); Boolean isSuccess = goodsService.deliverGoods(deliverRequest); if (!isSuccess) { throw new RuntimeException("失敗"); } } public String queryUserNameById(String userId) { return "Tom"; } public String queryUserPhoneById(String userId) { return "123456789"; } public String queryUserAddressById(String userId) { return "BeiJin"; } }
public class AwardFactory { public IAward getAwardService(Integer awardType) throws Exception{ if (awardType == null) return null; if (1 == awardType) return new VoucherAwardService(); if (2 == awardType) return new VIPAwardService(); if (3 == awardType) return new GoodsAwardService(); throw new RuntimeException("不存在此獎品類型"); } }
@Test public void testIAward() throws Exception{ AwardFactory awardFactory = new AwardFactory(); System.out.println("******模擬多種獎品發放測試******"); System.out.println("\n------ 代金券的發放 ------"); IAward awardService1 = awardFactory.getAwardService(1); Map<String, Object> map1 = new HashMap<>(); map1.put("voucherNumber", 1); awardService1.sendAward("10001", "123456712", map1); System.out.println("\n------ VIP體驗卡的發放 -------"); IAward awardService2 = awardFactory.getAwardService(2); Map<String, Object> map2 = new HashMap<>(); map2.put("data", new Date(System.currentTimeMillis())); map2.put("time", "23:59:59"); awardService2.sendAward("10002", "123123414", map2); System.out.println("\n------ 實物獎品的發放 -------"); IAward awardService3 = awardFactory.getAwardService(3); awardService3.sendAward("10003", "12312451", null); }
工廠模式能夠避免建立者與具體的產品邏輯耦合、知足單一職責,每個業務邏輯實現都在所屬本身的類中完成、知足開閉原則,無需修改調用方就能夠在程序中引入新的產品類型。
但這樣也會帶來一些問題,好比有很是多的獎品類型,那麼實現的子類會急速擴張。