带你读《2022技术人的百宝黑皮书》——浅析设计模式2 —— 策略模式(3)

简介: 带你读《2022技术人的百宝黑皮书》——浅析设计模式2 —— 策略模式

带你读《2022技术人的百宝黑皮书》——浅析设计模式2 —— 策略模式(2)

https://developer.aliyun.com/article/1262320?groupCode=taobaotech



与简单工厂模式的区别


从上面的代码示例及类图可以看出来,策略模式和上一篇文章中介绍的简单工厂模式很像,两者主要区别在于 Context 类和工厂类。为了方便对比,我们把这两个类的代码单独拎出来看看:

public class Context_TaoPlatform{
 //持有抽象策略的引用
 private Strategy myStrategy;
 //生成构造方法,让平台根据传入的策略参数选择促销活动
 public TaoPlatform(Strategy strategyType) {
 this.myStrategy = strategyType;
 }
 //向用户展示促销活动
 public void taoPlatformShow(String time) {
 System.out.println(time + "的促销策略是:");
 myStrategy.show();
 }
}
public class Factory{
 public static Shirt exhibit(String ShirtName){
 switch(ShirtName){
 case "女款衬衫":
 return new WomenShirt();
 case "男款衬衫":
 return new MenShirt();
 default:
 return null;
 }
 }
}


首先看一下接收参数:工厂类 Factory 中的 exhibit() 方法接收字符串,返回一个 Shirt 对象;

环境类 Context_TaoPlatform 初始化时需要接收一个 Strategy 对象。也就是说:工厂类中是根据接收的条件创建一个相应的对 象,而 Context 类接收的是一个对象,可以调用方法去执行此对象的方法。


举个例子:笔有很多种,假设有一个工厂专门负责生产不同用途的笔。

1.工厂模式:根据用户给出的目的来生产不同用途的笔,如:要写毛笔字就生产毛笔、要写钢笔字就生产钢笔。即 根据用户给出的某种属性,生产能做出相应行为的一种对象返回给用户,重点在于创建何种对象。

2.策略模式:用工厂生产的笔去出做对应的行为,如:用毛笔写毛笔字、用钢笔写钢笔字。即根据用户给出的某种 对象,执行相应的方法,重点在于选择何种行为。


JDK源码赏析


这里以 Comparator 比较器为例,通过分析其源码实现来深入理策略模式。


在 JDK 中,我们调用数组工具类 Arrays 的一个排序方法 sort() 时,可以使用默认的排序规则(升序),也可以自 定义一种排序的规则,即自定义实现升序或降序的排序。源码如下:

public class Arrays{
 public static <T> void sort(T[] a, Comparator<? super T> c) {
 if (c == null) {
 //若没有传入Comparator接口的实现类对象,调用默认的升序排序方法
 sort(a);
 } else {
 if (LegacyMergeSort.userRequested)
 //jdk5及之前的传统归并排序,新版本中LegacyMergeSort.userRequested默认false
 legacyMergeSort(a, c);
 else
 //改进后的归并排序
 TimSort.sort(a, 0, a.length, c, null, 0, 0);
 }
 }
}


此时我们需要传入两个参数:一个是待排序的数组,另一个则是 Comparator 接口的实现类对象。其中,Comparator 接口是一种函数式接口,该接口中定义了一个抽象方法 int compare(T o1, T o2),用于定义具体的排序规 则。这里,Comparator 接口就是策略模式中的抽象策略接口,它定义了一个排序算法,而具体策略(具体的排序 算法)将由用户来定义,那么Arrays 就是一个环境类,sort() 方法可以传入一个策略 c ,让 Arrays 根据这个策略 进行排序任务。

public class demo {
 public static void main(String[] args) {
 Integer[] data = {2, 0, 22, 14, 1, 3, 4};
 // 实现降序排序
 Arrays.sort(data, new Comparator<Integer>() {
 // 排序策略 降序
 public int compare(Integer o1, Integer o2) {
 return o2 - o1;
 }
 });
 System.out.println(Arrays.toString(data));
 }
}


在上面这个 demo 中,我们在调用 Arrays.sort() 方法时,第二个参数传递的是 Comparator 接口的子实现类对 象。由此可见,Comparator充当的是抽象策略角色,而具体的子实现类充当的是具体策略角色,环境角色类 Arrays 应该持有抽象策略的引用来调用。那么,Arrays.sort() 方法究竟有没有使用 Comparator 子实现类中的 compare() 方法?下面再看看 TimSort.sort() 方法,源码如下:

class TimSort<T> {
 static <T> void sort(T[] a, int lo, int hi, Comparator<? super T> c,
 T[] work, int workBase, int workLen) {
 assert c != null && a != null && lo >= 0 && lo <= hi && hi <= a.length;
 int nRemaining = hi - lo;
 if (nRemaining < 2)
 return; 
  if (nRemaining < MIN_MERGE) {
 int initRunLen = countRunAndMakeAscending(a, lo, hi, c);
 binarySort(a, lo, hi, lo + initRunLen, c);
 return;
 }
 ...
 } 
 private static <T> int countRunAndMakeAscending(T[] a, int lo, int hi,Comparator<? super T> c) {
 assert lo < hi;
int runHi = lo + 1;
 if (runHi == hi)
 return 1;
 if (c.compare(a[runHi++], a[lo]) < 0) {
 while (runHi < hi && c.compare(a[runHi], a[runHi - 1]) < 0)
 runHi++;
 reverseRange(a, lo, runHi);
 } else {
 while (runHi < hi && c.compare(a[runHi], a[runHi - 1]) >= 0)
 runHi++;
 }
 return runHi - lo;
 }
}


上面的代码最后会执行到 countRunAndMakeAscending() 方法中,在执行判断语句时调用了 compare() 方法。 那么如果只用了 compare() 方法,在调用 Arrays.sort() 方法时只要传具体 compare() 重写方法的类对象。



带你读《2022技术人的百宝黑皮书》——浅析设计模式2 —— 策略模式(4)

https://developer.aliyun.com/article/1262317?groupCode=taobaotech

相关文章
|
6月前
|
设计模式 算法 搜索推荐
Java 设计模式之策略模式:灵活切换算法的艺术
策略模式通过封装不同算法并实现灵活切换,将算法与使用解耦。以支付为例,微信、支付宝等支付方式作为独立策略,购物车根据选择调用对应支付逻辑,提升代码可维护性与扩展性,避免冗长条件判断,符合开闭原则。
1371 35
|
7月前
|
设计模式 人工智能 算法
基于多设计模式的状态扭转设计:策略模式与责任链模式的实战应用
接下来,我会结合实战案例,聊聊如何用「策略模式 + 责任链模式」构建灵活可扩展的状态引擎,让抽奖系统的状态管理从「混乱战场」变成「有序流水线」。
|
11月前
|
设计模式 算法 Java
设计模式觉醒系列(04)策略模式|简单工厂模式的升级版
本文介绍了简单工厂模式与策略模式的概念及其融合实践。简单工厂模式用于对象创建,通过隐藏实现细节简化代码;策略模式关注行为封装与切换,支持动态替换算法,增强灵活性。两者结合形成“策略工厂”,既简化对象创建又保持低耦合。文章通过支付案例演示了模式的应用,并强调实际开发中应根据需求选择合适的设计模式,避免生搬硬套。最后推荐了JVM调优、并发编程等技术专题,助力开发者提升技能。
|
设计模式 算法 Kotlin
Kotlin - 改良设计模式 - 策略模式
Kotlin - 改良设计模式 - 策略模式
185 4
|
11月前
|
设计模式 算法 搜索推荐
【设计模式】【行为型模式】策略模式(Strategy)
一、入门 什么是策略模式? 策略模式是一种行为设计模式,允许在运行时选择算法或行为。它将算法封装在独立的类中,使得它们可以互换,而不影响客户端代码。 为什么需要策略模式? 策略模式的主要目的是解决算法
230 14
|
设计模式 算法 开发者
「全网最细 + 实战源码案例」设计模式——策略模式
策略模式(Strategy Pattern)是一种行为型设计模式,用于定义一系列可替换的算法或行为,并将它们封装成独立的类。通过上下文持有策略对象,在运行时动态切换算法,提高代码的可维护性和扩展性。适用于需要动态切换算法、避免条件语句、经常扩展算法或保持算法独立性的场景。优点包括符合开闭原则、运行时切换算法、解耦上下文与策略实现、减少条件判断;缺点是增加类数量和策略切换成本。示例中通过定义抽象策略接口和具体策略类,结合上下文类实现动态算法选择。
495 8
「全网最细 + 实战源码案例」设计模式——策略模式
|
设计模式 存储 缓存
前端必须掌握的设计模式——策略模式
策略模式(Strategy Pattern)是一种行为型设计模式,旨在将多分支复杂逻辑解耦。每个分支类只关心自身实现,无需处理策略切换。它避免了大量if-else或switch-case代码,符合开闭原则。常见应用场景包括表单验证、风格切换和缓存调度等。通过定义接口和上下文类,策略模式实现了灵活的逻辑分离与扩展。例如,在国际化需求中,可根据语言切换不同的词条包,使代码更加简洁优雅。总结来说,策略模式简化了多条件判断,提升了代码的可维护性和扩展性。
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
175 1
|
设计模式 前端开发 JavaScript
JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式
本文深入探讨了JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式,结合电商网站案例,展示了设计模式如何提升代码的可维护性、扩展性和可读性,强调了其在前端开发中的重要性。
246 2
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
139 2

热门文章

最新文章