内容简介:沉淀、分享、成长,让自己和他人都能有所收获!:smile:有人举过这样一个例子,先给你张北大的录取通知书,但要求你每天5点起床,12点睡觉:sleepy:,刻苦学习,勤奋上进。只要你坚持三年,这张通知书就有效。如果是你,你能坚持吗?其实对于这个例子很难在我们的人生中出现,因为它目标明确,有准确的行军路线。就像你是土豪家庭,家里给你安排的明明白白一样,只要你按照这个方式走就不会有问题。可大多数时候我们并没有这样的路线,甚至不知道多久到达自己的黎明。但!谁又不渴望见到黎明呢,坚持吧!
作者:小傅哥
博客: https://bugstack.cn - 原创系列专题文章
沉淀、分享、成长,让自己和他人都能有所收获!:smile:
一、前言
黎明前的坚守,的住吗?
有人举过这样一个例子,先给你张北大的录取通知书,但要求你每天5点起床,12点睡觉:sleepy:,刻苦学习,勤奋上进。只要你坚持三年,这张通知书就有效。如果是你,你能坚持吗?其实对于这个例子很难在我们的人生中出现,因为它目标明确,有准确的行军路线。就像你是土豪家庭,家里给你安排的明明白白一样,只要你按照这个方式走就不会有问题。可大多数时候我们并没有这样的路线,甚至不知道多久到达自己的黎明。但!谁又不渴望见到黎明呢,坚持吧!
不要轻易被洗脑
键盘侠⌨
、 网络喷壶
,几乎当你努力坚持一件事的时候,在这条路上会遇到形形色色的人和事。有时候接收建议完善自己是有必要的,但不能放弃自己的初心和底线,有时候只坚持自己也是难能可贵的。 子路之勇,子贡之辩,冉有之智,此三子者,皆天下之所谓难能而可贵者也
。阳光和努力是这个世界最温暖的东西,加油坚持好自己的选的路。
有时还好坚持了
当你为自己的一个决定而感到万分开心:smile:时,是不是也非常感谢自己还好坚持了。坚持、努力、终身学习,似乎在 程序员 这个行业是离不开的,当你意愿于把这当做一份可以努力的爱好时,你就会愿意为此而努力。而我们很难说只在机会要来时准备,而是一直努力等待机会。也就是很多人说的别人抓住机会是因为一直在准备着。
二、开发环境
- JDK 1.8
- Idea + Maven
- 涉及工程三个,可以通过关注 公众号 :
bugstack虫洞栈
,回复源码下载
获取(打开获取的链接,找到序号18)
工程 | 描述 |
---|---|
itstack-demo-design-21-00 | 场景模拟工程;模拟爬虫商品生成海报场景 |
三、模版模式介绍
模板模式的核心设计思路是通过在,抽象类中定义抽象方法的执行顺序,并将抽象方法设定为只有子类实现,但不设计 独立访问
的方法。简单说也就是把你安排的明明白白的。
就像西游记的99八十一难,基本每一关都是;师傅被掳走、打妖怪、妖怪被收走,具体什么妖怪你自己定义,怎么打你想办法,最后收走还是弄死看你本事,我只定义执行顺序和基本策略,具体的每一难由观音来安排。
四、案例场景模拟
在本案例中我们模拟爬虫各类电商商品,生成营销推广海报场景
关于模版模式的核心点在于由抽象类定义抽象方法执行策略,也就是说父类规定了好一系列的执行标准,这些标准的串联成一整套业务流程。
在这个场景中我们模拟爬虫爬取各类商家的商品信息,生成推广海报( 海报中含带个人的邀请码
)赚取商品返利。 声明,这里是模拟爬取,并没有真的爬取
而整个的爬取过程分为;模拟登录、爬取信息、生成海报,这三个步骤,另外;
- 因为有些商品只有登录后才可以爬取,并且登录可以看到一些特定的价格这与未登录用户看到的价格不同。
- 不同的电商网站爬取方式不同,解析方式也不同,因此可以作为每一个实现类中的特定实现。
- 生成海报的步骤基本一样,但会有特定的商品来源标识。所以这样三个步骤可以使用模版模式来设定,并有具体的场景做子类实现。
五、模版模式搭建工程
模版模式的业务场景可能在平时的开发中并不是很多,主要因为这个 设计模式 会在抽象类中定义逻辑行为的执行顺序。一般情况下,我们用的抽象类定义的逻辑行为都比较轻量级或者没有,只是提供一些基本方法公共调用和实现。
但如果遇到适合的场景使用这样的设计模式也是非常方便的,因为他可以控制整套逻辑的执行顺序和统一的输入、输出,而对于实现方只需要关心好自己的业务逻辑即可。
而在我们这个场景中,只需要记住这三步的实现即可; 模拟登录
、 爬取信息
、 生成海报
1. 工程结构
itstack-demo-design-21-00 └── src ├── main │ └── java │ └── org.itstack.demo.design │ ├── group │ │ ├── DangDangNetMall.java │ │ ├── JDNetMall.java │ │ └── TaoBaoNetMall.java │ ├── HttpClient.java │ └── NetMall.java └── test └── java └── org.itstack.demo.design.test └── ApiTest.java
模版模式模型结构
- 以上的代码结构还是比较简单的,一个定义了抽象方法执行顺序的核心抽象类,以及三个模拟具体的实现(
京东
、淘宝
、当当
)的电商服务。
2. 代码实现
2.1 定义执行顺序的抽象类
/** * 基础电商推广服务 * 1. 生成最优价商品海报 * 2. 海报含带推广邀请码 */ public abstract class NetMall { protected Logger logger = LoggerFactory.getLogger(NetMall.class); String uId; // 用户ID String uPwd; // 用户密码 public NetMall(String uId, String uPwd) { this.uId = uId; this.uPwd = uPwd; } /** * 生成商品推广海报 * * @param skuUrl 商品地址(京东、淘宝、当当) * @return 海报图片base64位信息 */ public String generateGoodsPoster(String skuUrl) { if (!login(uId, uPwd)) return null; // 1. 验证登录 Map<String, String> reptile = reptile(skuUrl); // 2. 爬虫商品 return createBase64(reptile); // 3. 组装海报 } // 模拟登录 protected abstract Boolean login(String uId, String uPwd); // 爬虫提取商品信息(登录后的优惠价格) protected abstract Map<String, String> reptile(String skuUrl); // 生成商品海报信息 protected abstract String createBase64(Map<String, String> goodsInfo); }
- 这个类是此设计模式的灵魂
- 定义可被外部访问的方法
generateGoodsPoster
,用于生成商品推广海报 -
generateGoodsPoster
在方法中定义抽象方法的执行顺序 1 2 3 步 - 提供三个具体的抽象方法,让外部继承方实现;模拟登录(
login
)、模拟爬取(reptile
)、生成海报(createBase64
)
2.2 模拟爬虫京东
public class JDNetMall extends NetMall { public JDNetMall(String uId, String uPwd) { super(uId, uPwd); } public Boolean login(String uId, String uPwd) { logger.info("模拟京东用户登录 uId:{} uPwd:{}", uId, uPwd); return true; } public Map<String, String> reptile(String skuUrl) { String str = HttpClient.doGet(skuUrl); Pattern p9 = Pattern.compile("(?<=title\\>).*(?=</title)"); Matcher m9 = p9.matcher(str); Map<String, String> map = new ConcurrentHashMap<String, String>(); if (m9.find()) { map.put("name", m9.group()); } map.put("price", "5999.00"); logger.info("模拟京东商品爬虫解析:{} | {} 元 {}", map.get("name"), map.get("price"), skuUrl); return map; } public String createBase64(Map<String, String> goodsInfo) { BASE64Encoder encoder = new BASE64Encoder(); logger.info("模拟生成京东商品base64海报"); return encoder.encode(JSON.toJSONString(goodsInfo).getBytes()); } }
title base64
2.3 模拟爬虫淘宝
public class TaoBaoNetMall extends NetMall { public TaoBaoNetMall(String uId, String uPwd) { super(uId, uPwd); } @Override public Boolean login(String uId, String uPwd) { logger.info("模拟淘宝用户登录 uId:{} uPwd:{}", uId, uPwd); return true; } @Override public Map<String, String> reptile(String skuUrl) { String str = HttpClient.doGet(skuUrl); Pattern p9 = Pattern.compile("(?<=title\\>).*(?=</title)"); Matcher m9 = p9.matcher(str); Map<String, String> map = new ConcurrentHashMap<String, String>(); if (m9.find()) { map.put("name", m9.group()); } map.put("price", "4799.00"); logger.info("模拟淘宝商品爬虫解析:{} | {} 元 {}", map.get("name"), map.get("price"), skuUrl); return map; } @Override public String createBase64(Map<String, String> goodsInfo) { BASE64Encoder encoder = new BASE64Encoder(); logger.info("模拟生成淘宝商品base64海报"); return encoder.encode(JSON.toJSONString(goodsInfo).getBytes()); } }
- 同上,模拟登录和爬取以及创建图片的
base64
2.4 模拟爬虫当当
public class DangDangNetMall extends NetMall { public DangDangNetMall(String uId, String uPwd) { super(uId, uPwd); } @Override public Boolean login(String uId, String uPwd) { logger.info("模拟当当用户登录 uId:{} uPwd:{}", uId, uPwd); return true; } @Override public Map<String, String> reptile(String skuUrl) { String str = HttpClient.doGet(skuUrl); Pattern p9 = Pattern.compile("(?<=title\\>).*(?=</title)"); Matcher m9 = p9.matcher(str); Map<String, String> map = new ConcurrentHashMap<String, String>(); if (m9.find()) { map.put("name", m9.group()); } map.put("price", "4548.00"); logger.info("模拟当当商品爬虫解析:{} | {} 元 {}", map.get("name"), map.get("price"), skuUrl); return map; } @Override public String createBase64(Map<String, String> goodsInfo) { BASE64Encoder encoder = new BASE64Encoder(); logger.info("模拟生成当当商品base64海报"); return encoder.encode(JSON.toJSONString(goodsInfo).getBytes()); } }
- 同上,模拟登录和爬取以及创建图片的
base64
3. 测试验证
3.1 编写测试类
/** * 测试链接 * 京东;https://item.jd.com/100008348542.html * 淘宝;https://detail.tmall.com/item.htm * 当当;http://product.dangdang.com/1509704171.html */ @Test public void test_NetMall() { NetMall netMall = new JDNetMall("1000001","*******"); String base64 = netMall.generateGoodsPoster("https://item.jd.com/100008348542.html"); logger.info("测试结果:{}", base64); }
- 测试类提供了三个商品链接,也可以是其他商品的链接
- 爬取的过程模拟爬取京东商品,可以替换为其他商品服务
new JDNetMall
、new TaoBaoNetMall
、new DangDangNetMall
3.2 测试结果
23:33:13.616 [main] INFO org.itstack.demo.design.NetMall - 模拟京东用户登录 uId:1000001 uPwd:******* 23:33:15.038 [main] INFO org.itstack.demo.design.NetMall - 模拟京东商品爬虫解析:【AppleiPhone 11】Apple iPhone 11 (A2223) 128GB 黑色 移动联通电信4G手机 双卡双待【行情 报价 价格 评测】-京东 | 5999.00 元 https://item.jd.com/100008348542.html 23:33:15.038 [main] INFO org.itstack.demo.design.NetMall - 模拟生成京东商品base64海报 23:33:15.086 [main] INFO org.itstack.demo.design.test.ApiTest - 测试结果:eyJwcmljZSI6IjU5OTkuMDAiLCJuYW1lIjoi44CQQXBwbGVpUGhvbmUgMTHjgJFBcHBsZSBpUGhv bmUgMTEgKEEyMjIzKSAxMjhHQiDpu5HoibIg56e75Yqo6IGU6YCa55S15L+hNEfmiYvmnLog5Y+M 5Y2h5Y+M5b6F44CQ6KGM5oOFIOaKpeS7tyDku7fmoLwg6K+E5rWL44CRLeS6rOS4nCJ9 Process finished with exit code 0
六、总结
模版模式
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。