您的位置:首页 > 娱乐 > 明星 > 定制系统开发公司_猴哥影院在线电影观看_拉新平台哪个好佣金高_优化大师客服

定制系统开发公司_猴哥影院在线电影观看_拉新平台哪个好佣金高_优化大师客服

2024/12/6 13:35:37 来源:https://blog.csdn.net/CSDN_LiMingfly/article/details/143614955  浏览:    关键词:定制系统开发公司_猴哥影院在线电影观看_拉新平台哪个好佣金高_优化大师客服
定制系统开发公司_猴哥影院在线电影观看_拉新平台哪个好佣金高_优化大师客服

前言:
该说不说几乎是程序员就都知道或者了解设计模式,但大部分小伙伴写代码总是习惯于一把梭。无论多少业务逻辑就一个类几千行,这样的开发也可以归纳为三步;定义属性、创建方法、调用展示,Done!只不过开发一时爽,重构火葬场。
我怎么学不会设计模式?
钱也花了,书也买了。代码还是一坨一坨的!设计模式是由多年的经验提炼出来开发指导思想。就像我告诉你自行车怎么骑、汽车怎么开,但只要你没跑过几千公里,你能记住的只是理论,想上道依旧很慌!
工厂方法模式
在这里插入图片描述
工厂模式又称工厂方法模式,是一种创建型设计模式,其在父类中提供一个创建对象的方法, 允许子类决定实例化对象的类型。

这种设计模式也是 Java 开发中最常见的一种模式,它的主要意图是定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

简单说就是为了提供代码结构的扩展性,屏蔽每一个功能类中的具体实现逻辑。让外部可以更加简单的只是知道调用即可,同时,这也是去掉众多ifelse的方式。当然这可能也有一些缺点,比如需要实现的类非常多,如何去维护,怎样减低开发成本。但这些问题都可以在后续的设计模式结合使用中,逐步降低。
模拟发奖多种商品
在这里插入图片描述
这里模拟互联网中在营销场景下的业务。由于营销场景的复杂、多变、临时的特性,它所需要的设计需要更加深入,否则会经常面临各种紧急CRUD操作,从而让代码结构混乱不堪,难以维护。
在这里我们模拟积分兑换中的发放多种类型商品,假如现在我们有如下三种类型的商品接口;
在这里插入图片描述
1:三个接口返回类型不同,有对象类型、布尔类型、还有一个空类型。
2:入参不同,发放优惠券需要仿重、兑换卡需要卡ID、实物商品需要发货位置(对象中含有)。
3:另外可能会随着后续的业务的发展,会新增其他种商品类型。因为你所有的开发需求都是随着业务对市场的拓展而带来的。
我们先看下 一坨坨代码实现
在这里插入图片描述
工程结构上非常简单,一个入参对象 AwardReq 、一个出参对象 AwardRes,以及一个接口类 PrizeController
ifelse实现需求

package com.lm.design;import com.alibaba.fastjson.JSON;
import com.lm.design.card.IQiYiCardService;
import com.lm.design.coupon.CouponResult;
import com.lm.design.coupon.CouponService;
import com.lm.design.goods.DeliverReq;
import com.lm.design.goods.GoodsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/*** 模拟发奖服务* */
public class PrizeController {private Logger logger = LoggerFactory.getLogger(PrizeController.class);public AwardRes awardToUser(AwardReq req) {String reqJson = JSON.toJSONString(req);AwardRes awardRes = null;try {logger.info("奖品发放开始{}。req:{}", req.getuId(), reqJson);// 按照不同类型方法商品[1优惠券、2实物商品、3第三方兑换卡(爱奇艺)]if (req.getAwardType() == 1) {CouponService couponService = new CouponService();CouponResult couponResult = couponService.sendCoupon(req.getuId(), req.getAwardNumber(), req.getBizId());if ("0000".equals(couponResult.getCode())) {awardRes = new AwardRes("0000", "发放成功");} else {awardRes = new AwardRes("0001", couponResult.getInfo());}} else if (req.getAwardType() == 2) {GoodsService goodsService = new GoodsService();DeliverReq deliverReq = new DeliverReq();deliverReq.setUserName(queryUserName(req.getuId()));deliverReq.setUserPhone(queryUserPhoneNumber(req.getuId()));deliverReq.setSku(req.getAwardNumber());deliverReq.setOrderId(req.getBizId());deliverReq.setConsigneeUserName(req.getExtMap().get("consigneeUserName"));deliverReq.setConsigneeUserPhone(req.getExtMap().get("consigneeUserPhone"));deliverReq.setConsigneeUserAddress(req.getExtMap().get("consigneeUserAddress"));Boolean isSuccess = goodsService.deliverGoods(deliverReq);if (isSuccess) {awardRes = new AwardRes("0000", "发放成功");} else {awardRes = new AwardRes("0001", "发放失败");}} else if (req.getAwardType() == 3) {String bindMobileNumber = queryUserPhoneNumber(req.getuId());IQiYiCardService iQiYiCardService = new IQiYiCardService();iQiYiCardService.grantToken(bindMobileNumber, req.getAwardNumber());awardRes = new AwardRes("0000", "发放成功");}logger.info("奖品发放完成{}。", req.getuId());} catch (Exception e) {logger.error("奖品发放失败{}。req:{}", req.getuId(), reqJson, e);awardRes = new AwardRes("0001", e.getMessage());}return awardRes;}private String queryUserName(String uId) {return "花花";}private String queryUserPhoneNumber(String uId) {return "15200101232";}}

1:如上就是使用 ifelse 非常直接的实现出来业务需求的一坨代码,如果仅从业务角度看,研发如期甚至提前实现了功能。
2:那这样的代码目前来看并不会有什么问题,但如果在经过几次的迭代和拓展,接手这段代码的研发将十分痛苦。重构成本高需要理清之前每一个接口的使用,测试回归验证时间长,需要全部验证一次。这也就是很多人并不愿意接手别人的代码,如果接手了又被压榨开发时间。那么可想而知这样的 ifelse 还会继续增加。
测试结果
在这里插入图片描述
使用工厂模式优化代码
在这里插入图片描述
首先,从上面的工程结构中你是否一些感觉,比如;它看上去清晰了、这样分层可以更好扩展了、似乎可以想象到每一个类做了什么。
如果还不能理解为什么这样修改,也没有关系。因为你是在通过这样的文章,来学习设计模式的魅力。
代码实现
定义发奖接口

public interface ICommodity {void sendCommodity(String uId, String commodityId, String bizId, Map<String, String> extMap) throws Exception;}

实现奖品发放接口
优惠券

package com.lm.design.store.impl;import com.alibaba.fastjson.JSON;
import com.lm.design.coupon.CouponResult;
import com.lm.design.coupon.CouponService;
import com.lm.design.store.ICommodity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.util.Map;public class CouponCommodityService implements ICommodity {private Logger logger = LoggerFactory.getLogger(CouponCommodityService.class);private CouponService couponService = new CouponService();public void sendCommodity(String uId, String commodityId, String bizId, Map<String, String> extMap) throws Exception {CouponResult couponResult = couponService.sendCoupon(uId, commodityId, bizId);logger.info("请求参数[优惠券] => uId:{} commodityId:{} bizId:{} extMap:{}", uId, commodityId, bizId, JSON.toJSON(extMap));logger.info("测试结果[优惠券]:{}", JSON.toJSON(couponResult));if (!"0000".equals(couponResult.getCode())) {throw new RuntimeException(couponResult.getInfo());}}}

实物商品

package com.lm.design.store.impl;import com.alibaba.fastjson.JSON;
import com.lm.design.goods.DeliverReq;
import com.lm.design.goods.GoodsService;
import com.lm.design.store.ICommodity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.util.Map;public class GoodsCommodityService implements ICommodity {private Logger logger = LoggerFactory.getLogger(GoodsCommodityService.class);private GoodsService goodsService = new GoodsService();@Overridepublic void sendCommodity(String uId, String commodityId, String bizId, Map<String, String> extMap) throws Exception {DeliverReq deliverReq = new DeliverReq();deliverReq.setUserName(queryUserName(uId));deliverReq.setUserPhone(queryUserPhoneNumber(uId));deliverReq.setSku(commodityId);deliverReq.setOrderId(bizId);deliverReq.setConsigneeUserName(extMap.get("consigneeUserName"));deliverReq.setConsigneeUserPhone(extMap.get("consigneeUserPhone"));deliverReq.setConsigneeUserAddress(extMap.get("consigneeUserAddress"));Boolean isSuccess = goodsService.deliverGoods(deliverReq);logger.info("请求参数[优惠券] => uId:{} commodityId:{} bizId:{} extMap:{}", uId, commodityId, bizId, JSON.toJSON(extMap));logger.info("测试结果[优惠券]:{}", isSuccess);if (!isSuccess) {throw new RuntimeException("实物商品发放失败");}}private String queryUserName(String uId) {return "花花";}private String queryUserPhoneNumber(String uId) {return "15200101232";}}

第三方兑换卡

package com.lm.design.store.impl;import com.alibaba.fastjson.JSON;
import com.lm.design.card.IQiYiCardService;
import com.lm.design.store.ICommodity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.util.Map;public class CardCommodityService implements ICommodity {private Logger logger = LoggerFactory.getLogger(CardCommodityService.class);// 模拟注入private IQiYiCardService iQiYiCardService = new IQiYiCardService();@Overridepublic void sendCommodity(String uId, String commodityId, String bizId, Map<String, String> extMap) throws Exception {String mobile = queryUserMobile(uId);iQiYiCardService.grantToken(mobile, bizId);logger.info("请求参数[爱奇艺兑换卡] => uId:{} commodityId:{} bizId:{} extMap:{}", uId, commodityId, bizId, JSON.toJSON(extMap));logger.info("测试结果[爱奇艺兑换卡]:success");}private String queryUserMobile(String uId) {return "15200101232";}}

A:从上面可以看到每一种奖品的实现都包括在自己的类中,新增、修改或者删除都不会影响其他奖品功能的测试,降低回归测试的可能。
B:后续在新增的奖品只需要按照此结构进行填充即可,非常易于维护和扩展。
C:在统一了入参以及出参后,调用方不再需要关心奖品发放的内部逻辑,按照统一的方式即可处理。
创建商店工厂

package com.lm.design;import com.lm.design.store.ICommodity;
import com.lm.design.store.impl.CardCommodityService;
import com.lm.design.store.impl.CouponCommodityService;
import com.lm.design.store.impl.GoodsCommodityService;public class StoreFactory {public ICommodity getCommodityService(Integer commodityType) {if (null == commodityType) {return null;}if (1 == commodityType) {return new CouponCommodityService();}if (2 == commodityType) {return new GoodsCommodityService();}if (3 == commodityType) {return new CardCommodityService();}throw new RuntimeException("不存在的商品服务类型");}}

我们定义了一个商店的工厂类,在里面按照类型实现各种商品的服务。可以非常干净整洁的处理你的代码,后续新增的商品在这里扩展即可。如果你不喜欢if判断,也可以使用switch或者map配置结构,会让代码更加干净。
测试验证

package com.lm.test;import com.lm.design.StoreFactory;
import com.lm.design.store.ICommodity;
import org.junit.Test;import java.util.HashMap;
import java.util.Map;public class ApiTest {@Testpublic void commodity() throws Exception {StoreFactory storeFactory = new StoreFactory();// 1. 优惠券ICommodity commodityService_1 = storeFactory.getCommodityService(1);commodityService_1.sendCommodity("10001", "EGM1023938910232121323432", "791098764902132", null);// 2. 实物商品ICommodity commodityService_2 = storeFactory.getCommodityService(2);Map<String,String> extMap = new HashMap<String,String>();extMap.put("consigneeUserName", "谢飞机");extMap.put("consigneeUserPhone", "15200292123");extMap.put("consigneeUserAddress", "吉林省.长春市.双阳区.XX街道.檀溪苑小区.#18-2109");commodityService_2.sendCommodity("10001","9820198721311","1023000020112221113",new HashMap<String, String>() {{put("consigneeUserName", "谢飞机");put("consigneeUserPhone", "15200292123");put("consigneeUserAddress", "吉林省.长春市.双阳区.XX街道.檀溪苑小区.#18-2109");}});// 3. 第三方兑换卡(爱奇艺)ICommodity commodityService_3 = storeFactory.getCommodityService(3);commodityService_3.sendCommodity("10001","AQY1xjkUodl8LO975GdfrYUio",null,null);}}

运行结果正常,既满足了业务产品需求,也满足了自己对代码的追求。这样的代码部署上线运行,内心不会恐慌,不会觉得半夜会有电话。
另外从运行测试结果上也可以看出来,在进行封装后可以非常清晰的看到一整套发放奖品服务的完整性,统一了入参、统一了结果。
总结
么这样的开发的好处知道后,也可以总结出来它的优点;避免创建者与具体的产品逻辑耦合、满足单一职责,每一个业务逻辑实现都在所属自己的类中完成、满足开闭原则,无需更改使用调用方就可以在程序中引入新的产品类型。但这样也会带来一些问题,比如有非常多的奖品类型,那么实现的子类会极速扩张。因此也需要使用其他的模式进行优化。

好了 至此设计模式之工厂方法模式 学习结束了 友友们 点点关注不迷路 老铁们!!!!!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com