愿景:"让编程不再难学,让技术与生活更加有趣"
更多架构课程请访问 xdclass.net
目录
第5集 经典中的经典-Observer观察者设计模式介绍和应用
第6集 老王上班摸鱼-Observer观察者设计模式案例实战
第1集 三十六计-玩转策略模式和应用场景
简介:策略设计模式介绍和应用场景
-
策略模式(Strategy Pattern)
- 定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换
- 淘宝天猫双十一,正在搞活动有打折的、有满减的、有返利的等等,这些算法只是一种策略,并且是随时都可能互相替换的, 我们就可以定义一组算法,将每个算法都封装起来,并且使它们之间可以互换
-
应用场景
- 老王计划外出旅游,选择骑自行车、坐汽车、飞机等,每一种旅行方式都是一个策略
- Java AWT中的LayoutManager,即布局管理器
- 如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么可以使用策略模式
- 不希望暴露复杂的、与算法有关的数据结构,那么可以使用策略模式来封装算法
-
角色
- Context上下文:屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化
- Strategy策略角色:抽象策略角色,是对策略、算法家族的抽象,定义每个策略或算法必须具有的方法和属性
- ConcreteStrategy具体策略角色:用于实现抽象策略中的操作,即实现具体的算法

第2集 策略设计模式实战之电商多场景促销活动方案
简介:策略设计模式应用实战-电商多场景促销活动方案
- 业务需求
老王面试进了大厂,是电商项目的营销活动组,负责多个营销活动,有折扣、优惠券抵扣、满减等,项目上线后,产品经理找茬,经常新增营销活动,导致代码改动多,加班严重搞的老王很恼火。
他发现这些都是活动策略,商品的价格是根据不同的活动策略进行计算的,因此用策略设计模式进行了优化,后续新增策略后只要简单配置就行了,不用大动干戈
- 编码实战
public class ProductOrder {
private double oldPrice;
private int userId;
private int productId;
public ProductOrder(double oldPrice, int userId, int productId){
this.oldPrice = oldPrice;
this.userId = userId;
this.productId = productId;
}
//set get 方法省略
}
/**
* 小滴课堂,愿景:让技术不再难学 https://xdclass.net
*
* @Description
* @Author 二当家小D
* @Remark 有问题直接联系我,源码-笔记-技术交流群 微信 xdclass6
* @Version 1.0
**/
public abstract class Strategy {
/**
* 根据简单订单对象,计算商品折扣后的价格
* @param productOrder
* @return
*/
public abstract double computePrice(ProductOrder productOrder);
}
public class PromotionContext {
private Strategy strategy;
public PromotionContext(Strategy strategy){
this.strategy = strategy;
}
/**
* 根据策略计算最终的价格
* @param productOrder
* @return
*/
public double executeStrategy(ProductOrder productOrder){
return strategy.computePrice(productOrder);
}
}
public class NormalActivity extends Strategy{
@Override
public double computePrice(ProductOrder productOrder) {
return productOrder.getOldPrice();
}
}
public class DiscountActivity extends Strategy{
/**
* 具体的折扣
*/
private double rate;
public DiscountActivity(double rate){
this.rate = rate;
}
@Override
public double computePrice(ProductOrder productOrder) {
//一系列复杂的计算
return productOrder.getOldPrice() * rate;
}
}
public class VoucherActivity extends Strategy {
/**
* 传入优惠券
*/
private double voucher;
public VoucherActivity(double voucher){
this.voucher = voucher;
}
@Override
public double computePrice(ProductOrder productOrder) {
if(productOrder.getOldPrice() > voucher){
return productOrder.getOldPrice() - voucher;
}else {
return 0;
}
}
}
//使用
public static void main(String[] args) {
ProductOrder productOrder = new ProductOrder(800,1,32);
PromotionContext context;
double finalPrice;
//不同策略算出不同的活动价格
//没活动
context = new PromotionContext(new NormalActivity());
finalPrice = context.executeStrategy(productOrder);
System.out.println("NormalActivity = "+finalPrice);
//折扣策略
context = new PromotionContext(new DiscountActivity(0.8));
finalPrice = context.executeStrategy(productOrder);
System.out.println("DiscountActivity = "+finalPrice);
//优惠券抵扣
context = new PromotionContext(new VoucherActivity(100));
finalPrice = context.executeStrategy(productOrder);
System.out.println("VoucherActivity = "+finalPrice);
}
-
优点
- 满足开闭原则,当增加新的具体策略时,不需要修改上下文类的代码,上下文就可以引用新的具体策略的实例
- 避免使用多重条件判断,如果不用策略模式可能会使用多重条件语句不利于维护,和工厂模式的搭配使用可以很好地消除代码if-else的多层嵌套(工厂模式主要是根据参数,获取不同的策略)
-
缺点
- 策略类数量会增多,每个策略都是一个类,复用的可能性很小
- 对外暴露了类所有的行为和算法,行为过多导致策略类膨胀
-
JDK源码的应用
- Comparator 接口常用的 compare()方法,就是一个策略设计模式的应用,把 Comparator 作为参数使用生成不同的排序策略
List<Student> list = new ArrayList<>(); list.add(new Student("Anna", 15)); list.add(new Student("小D", 18)); list.add(new Student("老王", 20)); // 对伙伴的集合按年龄进行排序 Collections.sort(list, new Comparator<Student>() { @Override public int compare(Student s1, Student s2) { // 升序 //return s1.getAge()-s2.getAge(); // 降序 // return s2.getAge()-s1.getAge(); } });
第3集 大象装进冰箱分几步?模板方法设计模式介绍
简介: 模板方法设计模式讲解和应用场景介绍
-
模板方法模式Template Method
- 定义一个操作中的算法骨架,将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤,属于行为型模式
-
应用场景
- javaweb里面的Servlet,HttpService类提供了一个service()方法,
- 有多个子类共有逻辑相同的方法,可以考虑作为模板方法
- 设计一个系统时知道了算法所需的关键步骤,且确定了这些步骤的执行顺序,但某些步骤的具体实现还未知,可以延迟到子类进行完成
/**
* 抽象类(Abstract Class)
*/
public abstract class AbstractClass {
/**
* 模版方法
*/
public void templateMethod() {
specificMethod();
abstractMethod1();
abstractMethod2();
}
/**
* 具体方法
*/
public void specificMethod() {
System.out.println("抽象类中的具体方法被调用");
}
// 抽象方法1
public abstract void abstractMethod1();
// 抽象方法2
public abstract void abstractMethod2();
}
-
角色
-
抽象模板(Abstract Template): 定义一个模板方法,这个模板方法一般是一个具体方法,给出一个顶级算法骨架,而逻辑骨架的组成步骤在相应的抽象操作中,推迟到子类实现
-
模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法
-
基本方法:是整个算法中的一个步骤,包括抽象方法和具体方
- 抽象方法:在抽象类中申明,由具体子类实现。
- 具体方法:在抽象类中已经实现,在具体子类中可以继承或重写它
-
-
具体模板(Concrete Template):实现父类所定义的一个或多个抽象方法,它们是一个顶级算法逻辑的组成步骤
-

第4集 项目里程碑把控案例-模板方法设计模式案例实战
简介: 模板方法设计模式讲解和应用场景介绍
- 需求背景
小滴课堂-老王成功晋升为管理者,但是团队来了很多新兵,由于团队水平参差不齐,经常有新项目进来,但整体流程很不规范。
一个项目的生命周期:需求评审-设计-开发-测试-上线-运维。整个周期里面,需求评审-设计是固定的操作,而其他步骤则流程耗时等是根据项目来定的。
因此老王梳理了一个模板,来规范化项目,他只管核心步骤和项目里程碑产出的结果,具体的工时安排和开发就让团队成员去操作
- 编码实战
-
优点
- 扩展性好,对不变的代码进行封装,对可变的进行扩展,符合 开闭原则
-
提高代码复用性 将相同部分的代码放在抽象的父类中,将不同的代码放入不同的子类中
- 通过一个父类调用其子类的操作,通过对子类的具体实现扩展不同的行为,实现了反向控制
-
缺点
- 每一个不同的实现都需要一个子类来实现,导致类的个数增加,会使系统变得复杂
- 模板方法模式和建造者模式区别
两者很大的交集,建造者模式比模板方法模式多了一个指挥类,该类体现的是模板方法模式中抽象类的固定算法的功能,是一个创建对象的固定算法
第5集 经典中的经典-Observer观察者设计模式介绍和应用
简介: Observer观察者设计模式介绍和应用
-
观察者模式
- 定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新,也叫做发布订阅模式Publish/Subscribe,属于行为型模式
-
应用场景
-
消息通知里面:邮件通知、广播通知、微信朋友圈、微博私信等,就是监听观察事件
-
当一个对象的改变需要同时改变其它对象,且它不知道具体有多少对象有待改变的时候,考虑使用观察者模式
-
-
角色
- Subject主题:持有多个观察者对象的引用,抽象主题提供了一个接口可以增加和删除观察者对象;有一个观察者数组,并实现增、删及通知操作
- Observer抽象观察者:为具体观察者定义一个接口,在得到主题的通知时更新自己
- ConcreteSubject具体主题:将有关状态存入具体观察者对象,在具体主题内部状态改变时,给所有登记过的观察者发出通知
- ConcreteObserver具体观察者:实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态保持一致

第6集 老王上班摸鱼-Observer观察者设计模式案例实战
简介: Observer观察者设计模式案例实战
- 业务需求
小滴课堂-老王,技术比较厉害,因此上班不想那么辛苦,领导又在周围,所以选了个好位置,方便监听老板的到来,
当领导即将出现时老王可以立马观察到,赶紧工作。
用观察者模式帮助老王实现这个需求
- 编码
/**
* 小滴课堂,愿景:让技术不再难学
*
* @Description 消息发布者
* @Author 二当家小D
* @Remark 有问题直接联系我,源码-笔记-技术交流群
* @Version 1.0
**/
public class Subject {
private List<Observer> observerList = new ArrayList<>();
/**
* 新增观察者
* @param observer
*/
public void addObserver(Observer observer){
this.observerList.add(observer);
}
/**
*删除观察者
* @param observer
*/
public void deleteObserver(Observer observer){
this.observerList.remove(observer);
}
public void notifyAllObserver(){
for(Observer observer:this.observerList){
observer.update();
}
}
}
public interface Observer {
/**
* 观察到消息后进行的操作,就是响应
*/
void update();
}
/**
* 小滴课堂,愿景:让技术不再难学 https://xdclass.net
* @Description 消息发布者
* @Author 二当家小D
* @Remark 有问题直接联系我,源码-笔记-技术交流群 微信 xdclass6
* @Version 1.0
**/
public class BossConcreteSubject extends Subject {
public void doSomething(){
System.out.println("老板完成自己的工作");
//还有其他操作
System.out.println("视察公司工作情况");
super.notifyAllObserver();
}
}
/**
* 小滴课堂,愿景:让技术不再难学 https://xdclass.net
*
* @Description 消息的消费者
* @Author 二当家小D
* @Remark 有问题直接联系我,源码-笔记-技术交流群 微信 xdclass6
* @Version 1.0
**/
public class LWConcreteObserver implements Observer {
@Override
public void update() {
System.out.println("老王发现领导到来,暂停在线摸鱼,回归工作");
}
}
public class AnnaConcreteObserver implements Observer {
@Override
public void update() {
System.out.println("Anna小姐姐发现领导到来,暂停在线摸鱼,回归工作");
}
}
//使用
public static void main(String[] args) {
//创建一个主题,老板
BossConcreteSubject subject = new BossConcreteSubject();
//创建观察者,就是摸鱼的同事
Observer lwObserver = new LWConcreteObserver();
//创建观察者,就是摸鱼的同事
Observer annaObserver = new AnnaConcreteObserver();
//建立对应的关系,老板这个主题被同事进行观察
subject.addObserver(lwObserver);
subject.addObserver(annaObserver);
//主题开始活动,里面会通知观察者(相当于发布消息)
subject.doSomething();
}
-
优点
- 降低了目标与观察者之间的耦合关系,目标与观察者之间建立了一套触发机制
- 观察者和被观察者是抽象耦合的
-
缺点
- 观察者和观察目标之间有循环依赖的话,会触发它们之间进行循环调用,可能导致系统崩溃
- 一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间

干货文档





三大设计模式介绍与实战案例

596

被折叠的 条评论
为什么被折叠?



