Android中的设计模式之策略模式

简介: 参考《设计模式:可复用面向对象软件的基础 》5.9 Strategy--对象行为型模式《设计模式解析》(第二版)第九章 Strategy模式《Android源码设计模式解析与实战》第七章策略模式处理新需求的一种途径灾难往往是由短期未甄选最优的决策,长期积累而引起的在软件开发中也是如此,只关心眼前的事情,而忽视长期问题原因:我们确实无法预测新需求将如何变化如果要把软件编写得能够方便地添加新功能,在设计阶段就永远止步不前了客户或老板正死死盯着我们的进度,要求立即实现,我们没有时间多想。

参考

  • 《设计模式:可复用面向对象软件的基础 》5.9 Strategy--对象行为型模式
  • 《设计模式解析》(第二版)第九章 Strategy模式
  • 《Android源码设计模式解析与实战》第七章策略模式

处理新需求的一种途径

  • 灾难往往是由短期未甄选最优的决策,长期积累而引起的

  • 在软件开发中也是如此,只关心眼前的事情,而忽视长期问题
    原因:

  • 我们确实无法预测新需求将如何变化

  • 如果要把软件编写得能够方便地添加新功能,在设计阶段就永远止步不前了

  • 客户或老板正死死盯着我们的进度,要求立即实现,我们没有时间多想。

  • 我们以后会考虑这个问题

  • 似乎就是两种选择:

    • 过度分析或过度设计
    • 一上来就扎进细节中,编写代码,根本不考虑长期问题。

考虑变化的设计

  • 针对接口进行编程,而不要针对实现编程。
  • 优先使用对象组合,而不是类继承
  • 考虑设计中什么应该是可变的,关注对变化的概念进行封装

例子1:国际电子商务系统

这个系统的总架构中有一个控制器对象,用于处理销售请求。他能够确认何时有人在请求销售订单,并将请求转发给SalesOrder对象进行订单处理。

总架构中的SalesOrder

SalesOrder对象的功能包括:

  • 允许客户通过GUI填写订单
  • 处理税额的计算
  • 处理订单,打印销售数据

当然这些功能可以借助其他对象去实现,他的作用应该是充当一个存在销售订单信息的容器。

处理新的需求

比如必须处理美国之外的顾客的订单税额。
那么我们至少需要添加新的税额计算规则

那么该怎样添呢?

  • 复制和粘贴
    一份代码,两个版本,维护很麻烦
  • 使用switch或者if语句,用一个变量指定各种情况
    如果有很多个国家呢?以后添加国家还要慢慢检查分支,看漏掉那个国家没有。条件复杂后,分支的流向也开始模糊了,反而难以阅读和理解。
  • 使用函数指针或者委托
    函数指针和委托无法维持每个对象的状态,功能受限。
  • 继承
    如果错误使用,继承会使设计非常脆弱和僵化。

比如:


继承方案

这种方案的困难之处在于,它这次能够凑效,但是无法次次凑效,比如,如果要处理德国订单,或者应对其他方面发生变化(如日期格式,语言和运费规则),我们构建的继承层次将无法轻松应对

使用策略模式方法

第一步 发现变化并封装之

在本例中,已经确定缴税规则是变化的,“将它封装”就应该创建一个抽象类定义如何在概念上完成税额计算,然后根据每种变化派生具体类。

封装变化

第二步 组合优先

应该使用组合代替继承,用组合包含变化,也就是说,只有一个SalesOrder类,让它包含处理变化的CalcTax类

组合代替继承

直接继承方和策略模式方案比较

一个是自己直接派生处理变化,另一个是包含引用指向变化,当然是后一种好,因为一些税额业务规则能更好的独立于使用自己的SalesOrder

《设计模式》中的Strategy 模式

意图

可以根据上下文,使用不同的业务规则或算法

解释

定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换,Strategy模式使算法可独立于使用它的客户而变化。

原则

  • 对象都具有指责
  • 这些指责不同的具体实现是通过多态的使用完成的
  • 概念上相同的算法具有多个不同的实现,需要进行管理

角色

  • Context 用来操作策略的上下文环境,比如上面说的Calculator类
  • Stragety 策略的对象
  • ConcreteStragetyA,ConcreteStragetyB 具体的策略实现


    策略模式UML类图

示例代码

public class PriceCalculator {
private Stragety stragety;
    public void setStragety(Stragety stragety){
        this.stragety=stragety;
    }
    
public void calculatePrice(int km) {
    int price=0;
    if (stragety!=null) {
        price=stragety.calculatePrice(km);
    }
    System.out.println(String.valueOf(price));
}
}
public class Bus implements Stragety{
    @Override
    public int calculatePrice(int km) {
        return 3*km;
    }
    
}
public class Subway implements Stragety{
    
    @Override
    public int calculatePrice(int km) {
        return 5*km;
    }
    
}
public class Taxi implements Stragety{
    
    @Override
    public int calculatePrice(int km) {
        return 2*km;
    }
    
}
    public static void main(String[] args) {
        PriceCalculator laowang=new PriceCalculator();
        laowang.setStragety(new Bus());
        laowang.calculatePrice(3);
        laowang.setStragety(new Subway());
        laowang.calculatePrice(3);
        laowang.setStragety(new Taxi());
        laowang.calculatePrice(3);
    }

效果

使用if-else暴露的问题是代码臃肿,逻辑复杂,难以升级和维护,没有结构可言;策略模式是通过建立抽象,将不同的策略构建成一个具体的策略实现,通过不同的策略实现算法替换。在简化逻辑,结构的同时,增强了系统的可读性,稳定性,可扩展性。

应用例子2 Android动画中的时间插值器

待研究

目录
相关文章
|
2月前
|
设计模式 算法 Kotlin
Kotlin - 改良设计模式 - 策略模式
Kotlin - 改良设计模式 - 策略模式
57 4
|
4月前
|
设计模式 算法 测试技术
PHP中的设计模式:策略模式的应用与实践
在软件开发的浩瀚海洋中,设计模式如同灯塔,指引着开发者们避开重复造轮子的暗礁,驶向高效、可维护的代码彼岸。今天,我们将聚焦于PHP领域中的一种重要设计模式——策略模式,探讨其原理、应用及最佳实践,揭示如何通过策略模式赋予PHP应用灵活多变的业务逻辑处理能力,让代码之美在策略的变换中熠熠生辉。
|
22天前
|
设计模式 存储 缓存
前端必须掌握的设计模式——策略模式
策略模式(Strategy Pattern)是一种行为型设计模式,旨在将多分支复杂逻辑解耦。每个分支类只关心自身实现,无需处理策略切换。它避免了大量if-else或switch-case代码,符合开闭原则。常见应用场景包括表单验证、风格切换和缓存调度等。通过定义接口和上下文类,策略模式实现了灵活的逻辑分离与扩展。例如,在国际化需求中,可根据语言切换不同的词条包,使代码更加简洁优雅。总结来说,策略模式简化了多条件判断,提升了代码的可维护性和扩展性。
|
2月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
54 1
|
2月前
|
设计模式 前端开发 JavaScript
JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式
本文深入探讨了JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式,结合电商网站案例,展示了设计模式如何提升代码的可维护性、扩展性和可读性,强调了其在前端开发中的重要性。
49 2
|
2月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
54 2
|
3月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
本教程详细讲解Kotlin语法,适合深入学习。快速入门可参考“简洁”系列教程。本文通过游泳运动员的案例,介绍策略模式及其在Kotlin中的改良应用,利用高阶函数简化代码结构,提高灵活性。
50 3
|
3月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
本教程详细讲解Kotlin语法,适合深入学习。快速入门可参考“简洁”系列教程。本文介绍策略模式在Kotlin中的应用,通过游泳运动员的例子,展示如何使用接口和高阶函数实现策略模式,使代码更简洁、灵活。
40 2
|
3月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
73 3
|
3月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
34 3

热门文章

最新文章

  • 1
    设计模式转型:从传统同步到Python协程异步编程的实践与思考
    64
  • 2
    C++一分钟之-设计模式:工厂模式与抽象工厂
    55
  • 3
    《手把手教你》系列基础篇(九十四)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-下篇(详解教程)
    65
  • 4
    C++一分钟之-C++中的设计模式:单例模式
    80
  • 5
    《手把手教你》系列基础篇(九十三)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-上篇(详解教程)
    52
  • 6
    《手把手教你》系列基础篇(九十二)-java+ selenium自动化测试-框架设计基础-POM设计模式简介(详解教程)
    82
  • 7
    Java面试题:结合设计模式与并发工具包实现高效缓存;多线程与内存管理优化实践;并发框架与设计模式在复杂系统中的应用
    70
  • 8
    Java面试题:设计模式在并发编程中的创新应用,Java内存管理与多线程工具类的综合应用,Java并发工具包与并发框架的创新应用
    54
  • 9
    Java面试题:如何使用设计模式优化多线程环境下的资源管理?Java内存模型与并发工具类的协同工作,描述ForkJoinPool的工作机制,并解释其在并行计算中的优势。如何根据任务特性调整线程池参数
    63
  • 10
    Java面试题:请列举三种常用的设计模式,并分别给出在Java中的应用场景?请分析Java内存管理中的主要问题,并提出相应的优化策略?请简述Java多线程编程中的常见问题,并给出解决方案
    137