5分钟学会Android设计模式之策略模式Strategy Pattern教程

目录
  • 5分钟设计模式之策略模式(Strategy Pattern)
    • 1、收到需求
    • 2、不使用策略模式
    • 3、使用策略模式
    • 4、小结
  • 结尾

5分钟设计模式之策略模式(Strategy Pattern)

设计模式是软件开发中的常用模式,但是实际上很多人只是了解其概念,而在实际开发中并不知道如何应用。因此,我们可以结合实际开发案例来详细讲解策略模式。

如果您有任何疑问、对文章写的不满意、发现错误或者有更好的方法,欢迎在评论、私信或邮件中提出,非常感谢您的支持。

1、收到需求

假设我们需要自定义的 View 类,它需要实现不同的动画效果,包括平移、旋转、缩放等等等等。我们可以使用策略模式来实现这个功能,使得每种动画效果都对应一个策略类。

2、不使用策略模式

需要在 AnimatedView 类中实现所有的动画效果

class AnimatedView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
    var animationType: String = "translate"
    fun startAnimation() {
        when (animationType) {
            "translate" -> {
                // 实现平移动画
            }
            "rotate" -> {
                // 实现旋转动画
            }
            "scale" -> {
                // 实现缩放动画
            }
            else -> {
                throw IllegalArgumentException("Invalid animation type")
            }
        }
        invalidate()
    }
}

调用如下,需要在 AnimatedView 对象中设置动画类型,然后调用 startAnimation 方法来开始动画:

animatedView.apply {
    animationType = "translate"
}.startAnimation()
animatedView().apply {
    animationType = "rotate"
}.startAnimation()

在这种实现方式中,如果需要增加或修改动画效果,我们需要修改 AnimatedView 类中的代码,这样会增加代码的复杂度和维护成本。

3、使用策略模式

而使用策略模式,我们只需要增加或修改策略实现类即可,而不需要修改现有的代码。因此,使用策略模式能够更好地实现代码的可扩展性和可维护性。

我们将动画有多种实现方法(不同的行为)这些行为看成一个AnimationStrategy 策略接口

定义了一个应用动画的策略

interface AnimationStrategy {
    fun applyAnimation(view: View)
}

它只是一个接口,等待具体的动画实现 ,而刚开始的通过设置animationType,在onDraw中通过if来判断的方式

修改为了使用当前的策略对象

private var animationStrategy: AnimationStrategy? = null

在onDraw中调用

override fun onDraw(canvas: Canvas?) {
    super.onDraw(canvas)
    if (animationStrategy != null) {
        animationStrategy!!.applyAnimation(this)
    }
}

我们再随便写几个定义不同的策略实现类,这些实现类实现了 AnimationStrategy 接口,并且根据不同的需求,可以选择不同的策略实现类来应用不同的动画效果。

class TranslateAnimationStrategy : AnimationStrategy {
    override fun applyAnimation(view: View) {
        // 实现平移动画
    }
}
class RotateAnimationStrategy : AnimationStrategy {
    override fun applyAnimation(view: View) {
        // 实现旋转动画
    }
}
class ScaleAnimationStrategy : AnimationStrategy {
    override fun applyAnimation(view: View) {
        // 实现缩放动画
    }
}

使用方法如下,根据不同的需求来选择不同的策略实现类

animatedView.apply {
    animationStrategy = TranslateAnimationStrategy() // 执行平移动画
    //or
    animationStrategy = RotateAnimationStrategy() // 执行旋转动画
    //or
    animationStrategy = ScaleAnimationStrategy()// 执行缩放动画
}

AnimationStrategy 接口作为一个统一的接口,可以使得不同的策略实现类可以被统一地使用,从而实现了代码的解耦和可扩展性。

整合起来

class AnimatedView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
    var animationStrategy: AnimationStrategy? = null
        set(value) {
            field = value
            invalidate()
        }
    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        animationStrategy?.applyAnimation(this)
    }
}

4、小结

策略模式是一种行为型设计模式,它允许在运行时动态地选择算法或行为,从而使得算法或行为可以独立于使用它们的客户端而变化。在例子中动画的改变,并不需要修改AnimatedView

通常由一个接口或抽象类和多个实现类组成。客户端通过调用接口或抽象类中的方法来执行算法或行为,而具体的实现则由策略实现类来完成。在例子中AnimationStrategy为接口,各个动画为实现类。AnimatedView通过animationStrategy?.applyAnimation(this)来执行

如此我们也可以看出

  • 一个类需要在运行时根据不同的情况采用不同的算法或行为。
  • 一个类定义了许多行为,而且这些行为在类的方法中以多个条件语句的形式出现,将这些行为“分解”到不同的策略类中,可以避免条件语句的复杂度。
  • 算法的使用频率不高,可以把它们封装到策略类中,从而避免让整个系统变得臃肿。
  • 多个类只有在算法或行为上稍有不同的情况。

使用策略模式可以增加代码的灵活性和可维护性,使得代码更易于扩展和修改。不过可不要乱用,毕竟多了很多个类,不是嘛。

结尾

设计模式是一个非常广泛的话题,很多设计模式又有极高的相似度,刚接触很容易混淆,因此很难知道在什么情况下应该使用哪种设计模式。我将尽力提供在开发过程中遇到的最小单元的设计模式案例。更好地理解何时以及如何使用设计模式。

以上就是5分钟学会Android设计模式之策略模式Strategy Pattern教程的详细内容,更多关于Android策略模式Strategy Pattern的资料请关注我们其它相关文章!

(0)

相关推荐

  • Andriod事件分发事件由来初识

    目录 Android事件分发的事件从何而来 Activity的事件分发 ViewRootImpl事件分发 DecorView事件处理 Android事件分发的事件从何而来 事件分发一直以来都是一个android知识的重点.从应用开发角度和用户的交互就是在处理事件. Activity的事件分发 事件分发一般情况都会讲view的分发过程,他的过程缩略起来就可以这样表示. public boolean diapatchTouchEvent(MotionEvent ev) { boolean consu

  • Android AIDL通信DeadObjectException解决方法示例

    目录 崩溃来源 解决方法 方法1 调用跨进程接口之前,先判断Binder是否存活 方法2 监听Binder死亡通知 总结 崩溃来源 使用过AIDL进行跨进程通信的同学,肯定遇到过DeadObjectException这个崩溃,那么这个崩溃是怎么来的,我们又该如何解决它呢?今天这篇文章就来聊一聊. 首先,这个崩溃的意思是,多进程在进行跨进程Binder通信的时候,发现通信的Binder对端已经死亡了. 抛出异常的Java堆栈最后一行是BinderProxy.transactNative,所以我们从

  • Android事件分发的事件由来原理分析

    目录 Andriod事件分发的事件从何而来 调用WMS中的成员mInputManager 调用的mNative的方法 看看InputManager怎么初始化 createInputChannel干了3件事 首先看下openInputChannelPair 回到createInputChannel中 Andriod事件分发的事件从何而来 上一篇最后留下了一个疑问,WMS的事件是哪里来的? 注册事件回调是通过mWindowSession.addToDisplayAsUser来实现的,这是一个Bind

  • Android Service启动绑定流程详解

    目录 前言 一.Service 的启动流程 二.Service的绑定 三.Service的Context 总结 前言 本文基于Android 11,参考<Android进阶解密>一书资料.了解Service的启动和绑定流程,以及Service的Context创建过程. 由于基于分析流程,忽略很多细节分支.各位在看源码的时候,要尽可能忽略细节,分析整体流程之后,还有精力的话再去看细节.例如有些属性是在后面赋值的,如果在前面追究,难哦. 另:阅读这种流程需要很大的耐心和毅力.建议在心情愉悦想要学习

  • Android Jetpack 组件LiveData源码解析

    目录 前言 基本使用 疑问 源码分析 Observer ObserverWrapper LifecycleBoundObserver MutableLiveData postValue setValue 问题答疑 LiveData 特性引出的问题 问题解决 最后 前言 本文来分析下 LiveData 的源码,以及其在实际开发中的一些问题. 基本使用 一般来说 LiveData 都会配合 ViewModel 使用,篇幅原因关于 ViewModel 的内容将在后续博客中分析,目前可以将 ViewMo

  • PHP设计模式之 策略模式Strategy详解【对象行为型】

    本文实例讲述了PHP设计模式之 策略模式Strategy.分享给大家供大家参考,具体如下: 1.概述 在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能.如查找.排序等,一种常用的方法是硬编码(Hard Coding)在一个类中,如需要提供多种查找算法,可以将这些算法写到一个类中,在该类中提供多个方法,每一个方法对应一个具体的查找算法:当然也可以将这些查找算法封装在一个统一的方法中,通过if-else-或者case

  • Android设计模式之策略模式详解

    策略模式 一个功能的效果,有不同的算法与策略,根据不同的选择选择不同的结果. 简单来说,只要你写过程序就用过策略模式,不要说没用过,难道if-else(switch)没用过吗-.. if-else在其实就是一个策略模式的体现,根据不同的选择处理不同的结果. 问题 如果把所有的方法全部用if-else(switch)来处理,从功能上说没问题,但是冲代码层面的维护与使用来说,if-else多了之后会让类变的过于庞大,阅读不利,修改困难 解决问题 使用策略模式,定义统一接口,每一个不同的功能(if-e

  • C#策略模式(Strategy Pattern)实例教程

    本文以一个简单的实例来说明C#策略模式的实现方法,分享给大家供大家参考.具体实现方法如下: 一般来说,当一个动作有多种实现方法,在实际使用时,需要根据不同情况选择某个方法执行动作,就可以考虑使用策略模式. 把动作抽象成接口,比如把玩球抽象成接口.代码如下: public interface IBall { void Play(); } 有可能是玩足球.篮球.排球等,把这些球类抽象成实现接口的类.分别如下: public class Football : IBall { public void P

  • PHP设计模式之策略模式原理与用法实例分析

    本文实例讲述了PHP设计模式之策略模式原理与用法.分享给大家供大家参考,具体如下: 策略模式(Strategy Pattern) 策略模式是对象的行为模式,用意是对一组算法的封装.动态的选择需要的算法并使用. 策略模式指的是程序中涉及决策控制的一种模式.策略模式功能非常强大,因为这个设计模式本身的核心思想就是面向对象编程的多形性思想. 策略模式的三个角色: 1. 抽象策略角色 2. 具体策略角色 3. 环境角色(对抽象策略角色的引用) 实现步骤: 1. 定义抽象角色类(定义好各个实现的共同抽象方

  • Python设计模式之策略模式实例详解

    本文实例讲述了Python设计模式之策略模式.分享给大家供大家参考,具体如下: 策略模式(Strategy Pattern):它定义了算法家族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客户. 下面是一个商场活动的实现 #!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'Andy' ''' 大话设计模式 设计模式--策略模式 策略模式(strategy):它定义了算法家族,分别封装起来,让他们之

  • Android编程设计模式之策略模式详解

    本文实例讲述了Android编程设计模式之策略模式.分享给大家供大家参考,具体如下: 一.介绍 在软件开发中也常常遇到这样的情况:实现某一个功能可以有多种算法或者策略,我们根据实际情况选择不同的算法或者策略来完成该功能.例如,排序算法,可以使用插入排序.归并排序.冒泡排序等. 针对这种情况,一种常规的方法是将多种算法写在一个类中.例如,需要提供多种排序算法,可以将这些算法写到一个类中,每一个方法对应一个具体的排序算法:当然,也可以将这些排序算法封装在一个统一的方法中,通过if-else-或者ca

  • Java经典设计模式之策略模式原理与用法详解

    本文实例讲述了Java经典设计模式之策略模式.分享给大家供大家参考,具体如下: 策略模式指:策略模式指将程序中可变部分抽象分离成一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化. 策略模式一般由下面三部分组成: 1. 抽象策略角色: 策略类,通常由一个接口或者抽象类实现. 2. 具体策略角色:包装了相关的算法和行为. 3. 环境角色:持有某一个策略类的引用,客户端调用. 策略模式设计原则: 1. 把程序中需要变化的部分抽离出来,独立于不变

  • Java设计模式之策略模式_动力节点Java学院整理

    定义:定义一组算法,将每个算法都封装起来,并且使他们之间可以互换. 类型:行为类模式 类图: 策略模式是对算法的封装,把一系列的算法分别封装到对应的类中,并且这些类实现相同的接口,相互之间可以替换.在前面说过的行为类模式中,有一种模式也是关注对算法的封装--模版方法模式,对照类图可以看到,策略模式与模版方法模式的区别仅仅是多了一个单独的封装类Context,它与模版方法模式的区别在于:在模版方法模式中,调用算法的主体在抽象的父类中,而在策略模式中,调用算法的主体则是封装到了封装类Context中

  • Java设计模式之策略模式原理与用法实例详解

    本文实例讲述了Java设计模式之策略模式原理与用法.分享给大家供大家参考,具体如下: 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化.其中JDK里面的TreeSet类和TreeMap类就用到了策略模式.这两个类是带排序的集合类,其中排序的规则就相当于策略模式里定义的一系列算法,而集合类就相当于是策略模式里的环境类,供用户使用,用只知道TreeSet和TreeMap是带排序的,至于怎么排序的,是由排序的算法决定的. 策略模式

  • Java设计模式之策略模式定义与用法详解

    本文实例讲述了Java策略模式定义与用法.分享给大家供大家参考,具体如下: 一. 定义: 定义一系列算法,把他们一个一个封装起来,并且使他们可以相互替换. 二. 优点: (1)上下文(Context)和具体策略(ConcreteStrategy)是松耦合关系,因此上下文只需要知道他要使用某一个实现  Strategy接口类的实例,但不需要知道是哪个类. (2)策略模式满足开闭原则,当增加新的具体类时,不需要修改上下文类的代码,上下文即可以引用新的具体策略的实例. 三. 实例: 下面就通过一个问题

随机推荐