Android设计模式--策略模式

news2024/10/6 14:34:05

每天都要完成一个小目标

一,定义

策略模式定义了一系列的算法,并将每一个算法封装起来,而且使他们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化

什么意思呢?在我们平时的开发中,难免会遇到这种情况,实现某一个功能会有多种算法,如果我们将这些算法都放到一个类里面,通过if else 来选择具体的算法,那么这个类就会变得臃肿,维护成本也会提高,后面如果再增加一种算法,就需要修改这个类本身,这违反了OCP原则和单一职责原则。

如果我们将这些算法抽象出来,提供一个统一的接口,不同的算法有不同的实现类,这样在程序客户端就可以通过注入不同的实现对象来实现算法的动态替换,这种方式可扩展性,维护性高,这就是策略模式。

二,使用场景

1,针对同一类型问题的多种处理方式,仅仅是具体行为有差别时。

2,需要安全的封装多种同一类型的操作时。

3,出现同一抽象类有多个子类,而又需要使用if-else 或者switch case来选择具体子类时。

三,使用案例

假设有一个队列的排序功能,有三种算法,正序,倒序,随机排序。

如果不用策略模式,实现方式为:

先实现具体的策略类,根据不同的值采用不同的算法:

public class NormalStrategy {
    private static final String TAG = "NormalStrategy";

    public void order(String strategy){
        if(strategy.equals("order")){
            //正序算法
            Log.d(TAG,"1,2,3,4,5,6,7,8,9");
        }else if(strategy.equals("inorder")){
            //倒序算法
            Log.d(TAG,"9,8,7,6,5,4,3,2,1");
        }else {
            //随机数
            Log.d(TAG,"5,4,6,7,8,9,2,3,1");
        }
    }
}

具体应用:

NormalStrategy normalStrategy =new NormalStrategy();
normalStrategy.order("order");
normalStrategy.order("inorder");
normalStrategy.order("random");

输出:

如果我们 再增加一种排序算法,就需要修改策略类,比如,我们再增加一中算法,让1在第二位输出:

public class NormalStrategy {
    private static final String TAG = "NormalStrategy";

    public void order(String strategy){
        if(strategy.equals("order")){
            //正序算法
            Log.d(TAG,"1,2,3,4,5,6,7,8,9");
        }else if(strategy.equals("inorder")){
            //倒序算法
            Log.d(TAG,"9,8,7,6,5,4,3,2,1");
        }else if(strategy.equals("random")){
            //随机数
            Log.d(TAG,"5,4,6,7,8,9,2,3,1");
        }else {
            //让1在第二位输出
            Log.d(TAG,"2,1,3,4,5,6,7,8,9");
        }
    }
}

具体应用:

NormalStrategy normalStrategy =new NormalStrategy();
normalStrategy.order("order");
normalStrategy.order("inorder");
normalStrategy.order("random");
normalStrategy.order("new");

输出:

那下面我们使用策略模式来实现:

首先创建一个抽象的策略接口:

/**
 * 排序策略接口
 * */
public interface Strategy {

    void orderStrategy();
}

然后实现具体的策略类:

正序策略类

public class OrderStrategy implements Strategy{
    private static final String TAG = "OrderStrategy";
    @Override
    public void orderStrategy() {
        //正序算法
        Log.d(TAG,"1,2,3,4,5,6,7,8,9");
    }
}

倒序策略类

public class InOrderStrategy implements Strategy{
    private static final String TAG = "InOrderStrategy";
    @Override
    public void orderStrategy() {
        //倒序算法
        Log.d(TAG,"9,8,7,6,5,4,3,2,1");
    }
}

随机数策略类

public class RandomStrategy implements Strategy{
    private static final String TAG = "RandomStrategy";
    @Override
    public void orderStrategy() {
        //随机数算法
        Log.d(TAG,"5,4,6,7,8,9,2,3,1");
    }
}

策略类的中转上下文类

public class StrategyImp {
    private Strategy strategy;

    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }

    public void order(){
        strategy.orderStrategy();
    }
}

具体的实现

StrategyImp strategyImp =new StrategyImp();
strategyImp.setStrategy(new OrderStrategy());
strategyImp.order();
strategyImp.setStrategy(new InOrderStrategy());
strategyImp.order();
strategyImp.setStrategy(new RandomStrategy());
strategyImp.order();

输出:

如果在增加一种排序算法的话,就不需要修改现有的代码,只需要新建一个类,实现策略接口即可。假如现在还要再增加一中排序算法,让1在第二位输出,那么实现为:

public class NewStrategy implements Strategy{
    private static final String TAG = "NewStrategy";
    @Override
    public void orderStrategy() {
        //让1在第二位输出
        Log.d(TAG,"2,1,3,4,5,6,7,8,9");
    }
}

至此,就完成了策略模式的封装。

四,总结

策略模式主要用来分离算法,在相同的行为抽象下有不同的具体实现策略。

优点 :

1,结构清晰明了,使用简单直观

2,耦合度低,扩展性强

3,操作封装也更为彻底,数据更为安全

缺点 :

随着策略的增加,子类也会变得繁多

参考文献:Android源码设计模式第二版

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1214198.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

保姆级fastDFS安装教程

一、软件准备 环境需要准备四个包,分别是: 1. libfastcommon_1.0.36 2. FastdfsFastdfs_v5.11 3. fastdfs-nginx-module5.11 4. nginxnginx-1.12.2 二、环境准备 安装perl环境,后续编译fastdfs会用到 yum -y install perl* yum -y ins…

MySQL数据库清理Relay_Log_File日志

背景 “Relay_Log_File” 是 MySQL 中用于复制的参数之一。在 MySQL 复制中,当一个服务器作为主服务器(master)时,它会将其更改写入二进制日志文件(binary log file)。而另一个服务器作为从服务器&#xf…

springboot--单元测试

单元测试 前言1、写测试要用的类2、写测试要用的类3、运行测试类4、spring-boot-starter-test默认提供了以下库4.1 junit54.1.1 DisplayName:为测试类或者测试方法设置展示名称4.1.2 BeforeAll:所有测试方法运行之前先运行这个4.1.3 BeforeEach:每个测试…

Vue3问题:如何实现拼图验证+邮箱登录功能?前后端!

前端功能问题系列文章,点击上方合集↑ 序言 大家好,我是大澈! 本文约3500字,整篇阅读大约需要5分钟。 本文主要内容分三部分,第一部分是需求分析,第二部分是实现步骤,第三部分是问题详解。 …

给女朋友开发个小程序低价点外卖吃还能赚钱

前言 今天又是无聊的一天,逛了下GitHub,发现一个库里面介绍美团饿了吗外卖红包外卖优惠券,先领红包再下单。外卖红包优惠券,cps分成,别人领红包下单,你拿佣金。哇靠,那我岂不是可以省钱还可以赚钱,yyds。。。。想想都美好哈哈哈!!! 回到正题,这个是美团饿了么分销…

esp-01刷固件/下载软件到内部单片机的方法

此文章为转载,非原创 一、准备 需要准备三个东西: 1.esp模块。ESP-01 和 ESP-01s 的引脚及 flash 容量基本完全兼容,只是内部硬件设计粗糙与否的区别,所以理论上都适用。 2.官方固件。此部分可以从安信可官方教程中下载&#xff0…

python之使用深度学习创建自己的表情符号

目录 部署项目1、首先运行train.py训练模型2、接下运行gui.py测试 一、使用 CNN 进行面部情绪识别二、GUI 代码和表情符号映射 在这个深度学习项目中,我们将对人类面部表情进行分类,以过滤和映射相应的表情符号或头像。 数据集(面部表情识别&…

提效神器!10%标注数据,比肩全量标注的模型效果!

不知道大家有没有遇到过数据标注成本高、周期长的困扰,有没有那么一种可能,精心标注少量的数据,配合大量的无标注数据,就能达到比肩全量标注的模型精度呢?是的,PaddleX就带来了这样一款提效神器——大模型半…

超级干货!如何挖公益SRC实战/SQL注入

目录 一、信息收集 二、实战演示 三、使用sqlmap进行验证 四、总结 一、信息收集 1.查找带有ID传参的网站(可以查找sql注入漏洞) inurl:asp idxx 2.查找网站后台(多数有登陆框,可以查找弱口令,暴力破解等漏洞&…

第一百七十四回 如何创建扇形渐变背景

文章目录 1. 概念介绍2. 实现方法3. 代码与效果3.1 示例代码3.2 运行效果 4. 内容总结 我们在 上一章回中介绍了"如何创建线性渐变背景"相关的内容,本章回中将介绍" 如何创建扇形渐变背景"。闲话休提,让我们一起Talk Flutter吧。 …

打开GeoTIFF文件失败:Unknown field with tag

用QGIS输出的数据类型为UInt16的TIFF文件,无法在GIMP中打开。 GIMP消息提示: 调查 用ImageMagick打开TIFF文件,虽然会出现警告,但是最终还是打开了: 在ImageMagick中重新保存后,就可以用GIMP打开了。使用…

Mapstruct 搭配MP分页食用 - 参考自ballcat项目

参考自 ballcat 一键抵达: Gitee GitHub 场景 使用MyBatis Plus的selectPage方法进行分页查询之后,如果需要将Entity对象转换为Vo对象,需要从Page对象中取出集合列表,手动转换成Vo集合列表数据重新放进Page对象中。 取出集合 设置…

使用postman测试

第一步: 第二步: 第三步:添加请求 第四步:填写请求 代码实现自动关联的位置: 为相关联的接口设置环境: 使用设置的环境变量: 参数化实现测试:测试脚本中仅测试数据不一样&#xff…

[答疑]改善系统的性能,用得着业务建模吗

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 第五元素 2023-10-27 22:02 潘老师,请教一个实践中遇到的问题: 假设生产人员使用某个工具处理数据,需要10天时间;现在改进了这个工具…

Java排序算法之堆排序

图解 堆排序是一种常见的排序算法,它借助了堆这种数据结构。堆是一种完全二叉树,它可以分为两种类型:最大堆和最小堆。在最大堆中,每个结点的值都大于等于它的子结点的值,而在最小堆中,每个结点的值都小于等…

SpringSecurity6从入门到上天系列第六篇:解决这个问题为什么在引入SpringSecurity之后所有的请求都需要先做登录认证才可以进行访问呢

文章目录 问题引入 1:问题阐述 2:问题分析 一:从SpringBoot的自动装配 1:SpringBootApplication介绍 2:自动装配的核心方法 3:核心方法的调用路径 4:SpringSecurity核心配置 5&#xf…

PMP备考短期极限上岸攻略!

作为一位通过PMP考试成功上岸的3A人士,下面的文章包含了所有PMP考试的实用知识,是一本适合初学者的PMP备考攻略手册。如果你有意向了解或者报考PMP考试,这篇文章肯定会对你有很大的帮助! 对于新手第一个需要知道的就是PMP是什么&…

【python】—— 控制语句和组合数据类型(其一)

🎃个人专栏: 🐬 算法设计与分析:算法设计与分析_IT闫的博客-CSDN博客 🐳Java基础:Java基础_IT闫的博客-CSDN博客 🐋c语言:c语言_IT闫的博客-CSDN博客 🐟MySQL&#xff1a…

Flume(一)【Flume 概述】

前言 今天实在不知道学点什么好了,早上学了3个多小时的 Flink ,整天只学一门技术是很容易丧失兴趣的。那就学点新的东西 Flume,虽然 Kafka 还没学完,但是大数据生态圈的基础组件也基本就剩这倆了。 Flume 概述 生产环境中的数据一…

Sql Prompt 10下载安装图文教程

在操作过程中,请暂时关闭你的防病毒软件,以免其误报导致操作失败。 资源 SQL Prompt 10 https://www.aliyundrive.com/s/QuMWkvE1Sv6 点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看&…