【Kotlin设计模式】Kotlin实现装饰器模式

前言


装饰器模式(Decorator Pattern),用于动态地为对象添加新功能,而无需修改其结构,通过使用不用装饰类及这些装饰类的排列组合,可以实现不同的功能和效果,但是这样的效果就是会增加很多类,过度使用增加程序的复杂性。

适配器模式主要包括以下几个角色:

1、组件接口(Component:定义一个对象接口,可以有基本功能或抽象功能。
2、具体组件(ConcreteComponent:实现组件接口的基本功能。
3、装饰器(Decorator:持有一个组件对象的引用,并实现组件接口。
4、具体装饰器(ConcreteDecorator:实现了装饰器,并为组件对象添加了具体的附加功能。

在这里插入图片描述


实现


以下例子实现装饰器模式,定义图像处理接口BitmapProcessor,提供处理图片方法方法,具体组件实现基本的 BitmapProcessor,提供原始的 Bitmap对象。


interface BitmapProcessor {fun process(bitmap: Bitmap): Bitmap
}class BasicBitmapProcessor(private val bitmap: Bitmap) : BitmapProcessor {override fun process(bitmap: Bitmap): Bitmap {return this.bitmap}
}

实现一个通用的装饰器,持有一个 BitmapProcessor 对象的引用。


abstract class BitmapProcessDecorator(private val process: BitmapProcessor) : BitmapProcessor {override fun process(bitmap: Bitmap): Bitmap {return process.process(bitmap)}
}

实现具体装饰器继承,选择图片、缩放图片功能。


class RotateDecorator(process: BitmapProcessor, private val angle:Float): BitmapProcessDecorator(process) {override fun process(bitmap: Bitmap): Bitmap {val matrix = Matrix().apply {postRotate(angle)}return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)}
}class ScaleDecorator(process: BitmapProcessor, private val sx: Float, private val sy: Float) : BitmapProcessDecorator(process) {override fun process(bitmap: Bitmap): Bitmap {val matrix = Matrix().apply {postScale(sx, sy)}return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)}
}

客户端创建对应的装饰器


//创建原始图片对象
val originalBitmap = BitmapFactory.decodeResource(resources, R.drawable.ic_launcher_foreground)//创建具体图片处理对象
val basicProcessor = BasicBitmapProcessor(originalBitmap)//创建图片旋转装饰器
val rotateDecorator = RotateDecorator(basicProcessor, 45.0f)
rotateDecorator.process(originalBitmap)   //旋转90度//创建图片缩放装饰器
val scaleDecorator = ScaleDecorator(basicProcessor, 2.0f, 2.0f)
scaleDecorator.process(originalBitmap)    //缩放2倍//处理图片,显示
val processorBitmap= basicProcessor.process(originalBitmap)
mBinding.image.setImageBitmap(processorBitmap)

Android中,经常使用的控件RecyclerView中就提供了装饰器模式的应用,ItemDecoration它允许你在不修改原始 RecyclerView 的情况下为每个项添加装饰比如分割线、边距等。


/*** An ItemDecoration allows the application to add a special drawing and layout offset* to specific item views from the adapter's data set. This can be useful for drawing dividers* between items, highlights, visual grouping boundaries and more.*/
public abstract static class ItemDecoration {/*** Draw any appropriate decorations into the Canvas supplied to the RecyclerView.* Any content drawn by this method will be drawn before the item views are */public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull State state) {onDraw(c, parent);}/*** Draw any appropriate decorations into the Canvas supplied to the RecyclerView.* Any content drawn by this method will be drawn after the item views are drawn*/public void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent,@NonNull State state) {onDrawOver(c, parent);}/*** Retrieve any offsets for the given item. Each field of <code>outRect</code> specifies* the number of pixels that the item view should be inset by, similar to padding or margin.* The default implementation sets the bounds of outRect to 0 and returns.** <p>* If this ItemDecoration does not affect the positioning of item views, it should set* all four fields of <code>outRect</code> (left, top, right, bottom) to zero* before returning.** <p>* If you need to access Adapter for additional data, you can call* {@link RecyclerView#getChildAdapterPosition(View)} to get the adapter position of the* View.** @param outRect Rect to receive the output.* @param view    The child view to decorate* @param parent  RecyclerView this ItemDecoration is decorating* @param state   The current state of RecyclerView.*/public void getItemOffsets(@NonNull Rect outRect, @NonNull View view,@NonNull RecyclerView parent, @NonNull State state) {getItemOffsets(outRect, ((LayoutParams) view.getLayoutParams()).getViewLayoutPosition(),parent);}
}

下面实现为RecyclerView的条目添加分割线,继承ItemDecoration类,实现onDrawOver方法。


class DividerItemDecoration(context: Context) : RecyclerView.ItemDecoration() {private val divider: Drawable?init {val styledAttributes = context.obtainStyledAttributes(intArrayOf(android.R.attr.listDivider))divider = styledAttributes.getDrawable(0)styledAttributes.recycle()}override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {val left = parent.paddingLeftval right = parent.width - parent.paddingRightval childCount = parent.childCountfor (i in 0 until childCount - 1) {val child = parent.getChildAt(i)val params = child.layoutParams as RecyclerView.LayoutParamsval top = child.bottom + params.bottomMarginval bottom = top + divider!!.intrinsicHeightdivider.setBounds(left, top, right, bottom)divider.draw(c)}}
}

总结


装饰器模式在需要动态扩展对象功能的场景中非常有用,可以提高灵活性和复用性。然而,它也可能增加系统的复杂性,并带来一定的性能开销。在使用装饰器模式时,需要权衡其优缺点,并根据实际需求做出合理的设计决策。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Cypress第二次安装遇到的问题

问题一&#xff1a;吐血&#xff0c;谁会想到node.js的官网访问不了呢&#xff01; 中文网站&#xff1a;http://url.nodejs.cn/download/ 官网&#xff1a;https://nodejs.org/zh-cn nodejs安装的两种方法(官网、NVM安装-node版本切换)不知道这种方式是否可行&#xff0c;还…

62. 不同路径 -dp6

. - 力扣&#xff08;LeetCode&#xff09;. - 备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/unique-paths/ 输入&#xff1a;m 3, n 2 输出&#xff1a;3 解释&a…

汽车功能安全--TC3xx LBIST触发时机讨论

目录 1. LBIST架构 2. LBIST寄存器配置 3. LBIST触发时机 LBIST&#xff0c;全称Logic Built-in Self Test。 在TC3xx中&#xff0c;LBIST是一种硬件功能安全机制&#xff0c;目的是为了探测MCU内部逻辑电路的潜伏故障(latent faults)。 从使用者角度来看&#xff0c;只需…

基于x86 平台opencv的图像采集和seetaface6的图像质量评估功能

目录 一、概述二、环境要求2.1 硬件环境2.2 软件环境三、开发流程3.1 编写测试3.2 配置资源文件3.3 验证功能一、概述 本文档是针对x86 平台opencv的图像采集和seetaface6的图像质量评估功能,opencv通过摄像头采集视频图像,将采集的视频图像送给seetaface6的图像质量评估模块…

63. 不同路径 II -dp7

63. 不同路径 IIhttps://leetcode.cn/problems/unique-paths-ii/ 输入&#xff1a;obstacleGrid [[0,0,0],[0,1,0],[0,0,0]] 输出&#xff1a;2 解释&#xff1a;3x3 网格的正中间有一个障碍物。 从左上角到右下角一共有 2 条不同的路径&#xff1a; 1. 向右 -> 向右 ->…

对各项数据的统计汇总,集中展示,便于查看厂区情况的智慧物流开源了。

智慧物流视频监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒&#xff0c;省去繁琐重复的适配流程&#xff0c;实现芯片、算法、应用的全流程组合&#xff0c;从而大大减少企业级应用约95%的开发成本。构建基于Ai技术的…

关于kafka的分区和消费者之间的关系

消费者和消费者组 当生产者向 Topic 写入消息的速度超过了消费者&#xff08;consumer&#xff09;的处理速度&#xff0c;导致大量的消息在 Kafka 中淤积&#xff0c;此时需要对消费者进行横向伸缩&#xff0c;用多个消费者从同一个主题读取消息&#xff0c;对消息进行分流。 …

yolov8 安装流程

1、克隆远端代码 git clone https://gitcode.com/gh_mirrors/ul/ultralytics.git 2、配置pyshon环境安装 3.10的版本&#xff0c;注意3.12后期会出现标注都在顶部的问题 使用idea可以在项目结构中直接添加python SDK 3、下载依赖&#xff0c;安装8.0210&#xff0c;注意新依赖…

脑靶向肽 ;SHp ;CLEVSRKNC ;缺血归巢肽

【脑靶向肽 SHp 简介】 SHp多肽是一种抗肿瘤多肽&#xff0c;它可以通过激活P53基因&#xff0c;调节细胞凋亡相关基因的蛋白表达&#xff0c;从而抑制肿瘤细胞的增殖并诱导细胞凋亡。在最新的研究中&#xff0c;SHp多肽被发现可以促进T细胞对肿瘤细胞的杀伤作用&#xff0c;显…

Vue3源码调试-第三篇

前言 上两篇已经调试完packages/runtime-dom/src/index.ts下的createApp函数的第一行了&#xff0c;接下来我们看下一行 injectNativeTagCheck 首先说下这个__DEV__估计也是定义在dev.js下&#xff0c;又或者是哪里的&#xff0c;这里控制台输出是true&#xff0c;那我估计是…

深入解析css-学习小结

绪论 盒模型 层叠 优先级 继承 层叠 层叠指规则冲突时&#xff0c;如何选择规则。规则冲突解决顺序&#xff1a; 样式表来源 用户代理样式 用户代理样式&#xff1a;浏览器默认样式 作者样式表&#xff1a;你自己写的css样式 作者样式表会覆盖用户代理样式&#xff0c;因…

Java 入门指南:Java IO流 —— 字节流

何为Java流 Java 中的流&#xff08;Stream&#xff09; 是用于在程序中读取或写入数据的抽象概念。流可以从不同的数据源&#xff08;输入流&#xff09;读取数据&#xff0c;也可以将数据写入到不同的目标&#xff08;输出流&#xff09;。流提供了一种统一的方式来处理不同…

2024.8.27 作业

1> 提示并输入一个字符串&#xff0c;统计该字符串中字母个数、数字个数、空格个数、其他字符的个数 #include <iostream>using namespace std;int main() {string s;cout << "请输入字符串>>>";getline(cin,s);int letter0,digit0,blank0,…

华为eNSP:静态路由配置、浮动路由配置

静态路由&#xff1a; 一、拓扑图 二、路由器配置 2.1&#xff1a;配置接口 R1&#xff1a; [r1]int g0/0/0 [r1-GigabitEthernet0/0/0]ip add 192.168.1.254 24 [r1-GigabitEthernet0/0/0]qu [r1]int g0/0/1 [r1-GigabitEthernet0/0/1]ip add 10.1.1.1 24 [r1-GigabitEth…

CMake之PUBLIC、PRIVATE、INTERFACE

竹杖芒鞋轻胜马,谁怕?一蓑烟雨任平生~ 个人主页&#xff1a; rainInSunny | 个人专栏&#xff1a; C那些事儿、 Qt那些事儿 文章目录 写在前面抽象版解释头文件和链接库传递测试代码结构PUBLIC传递PRIVATE传递INTERFACE传递 写在前面 使用CMake必然离不开target_include_dir…

第2章 双向链表

双向链表 概念 对链表而言&#xff0c;双向均可遍历是最方便的&#xff0c;另外首尾相连循环遍历也可大大增加链表操作的便捷性。因 此&#xff0c;双向循环链表&#xff0c;是在实际运用中是最常见的链表形态。 基本操作 与普通的链表完全一致&#xff0c;双向循环链表虽然…

FPGA 如何进入 AI 领域的思考

FPGA在AI领域如何发力&#xff0c;如何抢碗饭吃&#xff1f;大多数提到是硬件加速&#xff0c;在AI工程里&#xff0c;完成数据前处理&#xff08;加速&#xff09;。大家很少提到AI模型的本身的推理过程&#xff0c;让FPGA成为AI模型的推理/算力芯片&#xff0c;这自然是 FPGA…

2535. 解密 [CSP-J 2022]

代码 #include <bits/stdc.h> using namespace std; long long m,n; int check(int x){if(x * (m - x) n) return 0;if(x * (m - x) < n) return 1;if(x * (m - x) > n) return 2; } int main(){int k;cin >> k;while(k--){long long e, d,p0,q0;scanf(&q…

如何抠去PPT图片的背景?推荐这款AI智能抠图软件!

做ppt的过程中&#xff0c;我们会用到各式各样的图片素材&#xff0c;其中有些图片不能完全满足我们的需求&#xff0c;得先对图片进行处理&#xff0c;最常见的是抠图&#xff0c;去除图片原有的背景&#xff0c;得到一张包含透明像素的图片&#xff0c;方便我们排版PPT页面上…

高德企业用车负责人:以AI技术革新出行服务体验

在助力产业数字化转型的大潮中&#xff0c;高德企业用车以其前沿的科技理念和创新服务&#xff0c;正在成为出行领域的领跑者。近日接受采访时&#xff0c;高德地图行业合作业务总经理姜义丹先生分享了AI技术在出行领域应用的思考&#xff0c;以及如何提升企业服务智能化水平&a…