编程思想 定义过滤的方式解耦
本文将会很少涉及 dotnet 的知识,主要讲用定义过滤的方式解除过程业务的耦合。在一些业务上,可以从业务层面或逻辑层面明显分为几层,每一层之前的数据相互依赖或处理顺序相互依赖,但逻辑都独立。此时如果将业务处理放在过程处理里面,将会让过程处理耦合具体业务。而定义过滤的方式为让过程逻辑只是搭建框架为主,具体业务通过注入过滤的形式加入到处理
假设我有某个业务需要处理,这个业务分为两个大步骤,分别是 F1 步骤和 F2 步骤。而 F1 里面自然有 F1 步骤的业务,同理 F2 也一样。而我的业务上对于数据处理的过程要求比较高,在过程处理上面的逻辑相对复杂,而如果将 F1 的业务和 F2 的业务放进来,大概的逻辑会是这样
// 复杂的过程处理代码
// 通用的过程处理业务代码
// F1 业务需要处理的代码
// 其他诡异的逻辑业务代码
// 过程处理的业务代码
// F2 业务需要处理的代码
// 其他处理代码
总体看起来逻辑将会比较复杂,同时耦合度也将会比较高
读到这里的小伙伴是否有一个疑问,在什么时候就能定义出过程处理的逻辑,而其中的 F1 业务和 F2 业务是如何能定义出哪些代码是属于哪个步骤
用一个比较具体的例子说明
我需要在 WPF 中处理一个视频文件,视频文件的处理包含了视频文件本身的专业逻辑,也就是如何解码视频文件,如何将视频文件拼接为一张张图片。而处理视频文件包含了业务上的事情,业务上的事情包含以下三个部分
- 打开视频文件之前需要看看这个视频文件的编码格式,如果不清真就提示用户(判断格式)
- 每一个视频转出来的图片,在拿到数据之前需要做一点点优化,如在数据上添加一个水印(添加水印)
- 从图片数据转图片完成之后,需要随机拿出一些图片给用户预览(提供预览)
而如果将上面的业务逻辑混合到整个视频处理逻辑上,大概会是这个样子
- 打开视频文件,分批加入到内存
- 判断格式(业务第一个步骤)
- 解码拿到 HEAD 数据
- 加载声音
- 获取视频分辨率,创建空白数据
- 杂七杂八的专业处理逻辑
- 按照一秒30张图片组合出视频处理,将视频一秒拆为 30 张图片
- 以下为视频的每一张图片处理逻辑
- 解析出视频中的图片
- 添加水印(业务第二个步骤)
- 将图片做一些优化
- 奇特的图片处理
- 保存图片到文件
- 提供预览(业务第三个步骤)
- 压缩处理的所有图片
- 我也编不出的业务逻辑
大概来说,其实上面的逻辑可以分为三个大部分,第一个部分就是算法部分,或者说专业逻辑代码。这部分主要就是如何解码视频,如何将视频转图片以及优化图片等逻辑。这些逻辑基本都是很通用的,同时这部分逻辑也应该做到很独立。业务上使用只是调用方法传入参数而已,不应该将具体代码写入到耦合某个业务里面
第二个部分就是定义处理的过程,其实上面的逻辑应该可以分为以下过程
- 从文件加载到内存
- 解码视频
- 从视频转图片
- 处理图片
- 保存处理逻辑
这里面大部分步骤都是几乎做到通用的,也就是在这些步骤上只是填充专业逻辑。这部分逻辑适合创建一个 NuGet 库存放,这样在多个项目之间都能共用。但是现在的问题来了,我的业务逻辑分散在三个过程里面
- 文件打开后
- 图片处理时
- 图片处理完成
而其中 文件打开后 这个过程在此业务中只用一次。而后面两个过程将会根据具体视频执行多次
这里的业务逻辑就是第三个部分。这里的逻辑划分其实和代码执行顺序没有直接关系,而是根据代码逻辑的层次划分。进一步说,其实第一部分专业逻辑和第二部分定义处理的过程这两个部分不是紧密的关系。假设咱有很多不同的专业逻辑,如针对不同的视频采用不同的处理方式,但是这些处理方式之前的处理过程是差不多的,也就是第二个部分定义处理的过程部分可以独立出来,根据具体功能填写具体的专业逻辑。也就是从层次上,第二部分属于框架层面,但如果我将第三部分业务逻辑放在了整个处理逻辑里面,那么此时的功能就都无法独立
是否可以让第三部分业务逻辑分离?其实从上面说的内容,连第一部分都可以分离。假设将第二部分框架层面的部分作为框架使用,那么框架就是独立的,但是框架没有任何具体的功能。此时通过在框架各个部分填补专业逻辑可以让第一部分和第二部分联合作出实际的功能
但是想要完成功能还需要有业务的存在,此时的业务就不能写入到库的代码中。这里的库指的是如 NuGet 一样的代码库,或者说是通用代码里面,通用代码不含各个产品的具体业务
既然在第二部分已经可以定义出框架了,那么可以在框架里面应用过滤的方式进行解耦。在框架里面可以定义逻辑处理的顺序,在关键的处理里面开放注入接口。如在视频文件打开之后,此时添加一个可以注入的点,可以让业务层注入业务逻辑
而此时注入的部分的建议是注入一个接口,在框架里面定义了过程用到传入的数据,在某些处理的过程里面可以让开发者注入具体的实现类,通过接口进行约束和获取数据进行处理的方式,就是本文说的定义过滤的方式解耦
例如有简化的逻辑,我的框架的定义如下
interface IFooHandler{void AddF1Filter(IF1Filter filter);void AddF2Filter(IF2Filter filter);}
框架里面提供了添加两个不同的业务过滤的方法,而这两个不同的业务过滤将会在整个过程的不同步骤进行调用,同时也使用两个不同的接口限定了具体的业务逻辑的注入的类的实现方式。这个方法的优点在于,可以将业务的逻辑放在具体的业务上做,而框架和库的部分只是做通用的处理逻辑。换句话说是将不通用的代码作为接口的方式提出,而在业务层进行注入,注入的方式就是调用框架给出的方法传入对应的接口实现。如上面代码,框架在两个步骤里面给出了两个可以注入的方法,通过调用框架的这两个方法传入具体实现就能做到在框架处理的过程调用注入的业务
而对比将所有逻辑都写在一起的优势在于降低耦合,原先的业务逻辑可以分散写,同时还能访问上下文更多信息。而现在只能通过约束的接口,如上面代码的 IF1Filter 定义,此时将可以让业务逻辑不影响到框架里面的逻辑,换句话是框架里面只需要了解接口的内容而不需要了解具体业务
而这个过滤的方式可以在框架里面各个地方提供,甚至框架可以通过判断有注入实际业务和没有注入的行为,如有注入业务时采用业务特殊方法替换原有的逻辑,如下面代码定义
public void SetF1Filter(IF1Filter filter){Filter = filter;}private IF1Filter Filter { get; set; } = DefaultFilter;private static readonly IF1Filter DefaultFilter = new F1Filter();
如果用户没有注入实际的逻辑,那么将会使用 DefaultFilter 的逻辑,如果用户注入了,那么将使用用户的逻辑
对于部分业务处理,如上面说到的在文件打开之后的处理,此时的处理不应该限定只有一个,于是如上面代码定义,可以让用户调用方法多次,之后进行每个用户传入的业务处理
private static void HandleFoo(IFooHandler fooHandler){fooHandler.AddF1Filter(new F1Filter());fooHandler.AddF1Filter(new F1Filter());fooHandler.AddF1Filter(new F1Filter());}
如上面代码可以让框架在 F1 步骤处理三次,虽然上面代码都是传入一样的类创建
而如果将整个注入好了逻辑的框架作为一个实例存放,在软件中的不同业务使用,此时也许会遇到某些业务需要添加一点功能,而某些业务不需要的情况,如下面代码的 fooHandle 是已经注入好了业务逻辑的实例,但是此时我需要在某个业务里面对他的处理过程进行一点更改
var fooHandle = new FooHandler();HandleFoo(fooHandle);
此时的修改如果依然对 fooHandle 进行注入不加任何逻辑,那么此时将会影响到其他使用的业务,这里在 C# 里面可以采用 using 的方法,大概的写法如下
var f1Filter = new F1Filter();using (f1Filter){fooHandle.AddF1Filter(f1Filter);// 其他业务}
在本次处理完成 F1Filter 和业务之后,将会调用 f1Filter 的释放代码,在释放代码里面可以反过来调用 fooHandle 的移除添加方法
大概实现逻辑请看我的代码 这里面只是简单定义
我搭建了自己的博客 https://blog.lindexi.com/ 欢迎大家访问,里面有很多新的博客。只有在我看到博客写成熟之后才会放在csdn或博客园,但是一旦发布了就不再更新
如果在博客看到有任何不懂的,欢迎交流,我搭建了 dotnet 职业技术学院 欢迎大家加入
如有不方便在博客评论的问题,可以加我 QQ 2844808902 交流
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。
http://www.taodudu.cc/news/show-4448863.html
相关文章:
- 为什么现在用的otm8018b型LCD屏的ID不能被读取?
- 微软开始为厂商提供 SQL Server 2014 OTM
- Hibernate的多种关系映射(oto、otm、mtm)
- OTM区块链应用离我们的生活有多近?
- OTM1287A在MSM8909上的移植
- OTM应用能解决人工智能领域的数据安全问题
- OTM order management(订单管理)--ORDER BASE
- 调试OTM4001A液晶驱动的一点心得
- 虚幻引擎中导出模型,并导入到Unity
- 如何在UnrealEngine虚幻引擎中进行版本管理
- 虚幻引擎5 C++编程学习
- 二叉树的前序中序后序遍历图示
- Vue-生命周期的理解+生命周期图示的理解
- Stata:图示连续变量的连续边际效应
- matlab绘制磁场图,基于Matlab的电磁场图示化教学
- 三分钟学会快速排序(图示讲解,附代码,通俗易懂)
- Vue2 生命周期 详细讲解+图示
- 单点登录SSO:图示和讲解
- python实现批量修改图片颜色
- pycharm启动图片修改
- 学习Discuz! X3.2记录:新建模板及修改logo
- jQuery的css()如何修改背景图片
- 修改服务器文件权限centos,Centos7系统使用chmod修改文件权限方法
- AMC美国数学竞赛考试信息大全
- 运用JAVA基础阶段知识,模拟双色球机选抽奖过程
- 练习牛客网笔试题--前端js--60-双色球机选一注
- C语言实现模拟大乐透和双色球彩票机选【纯娱乐】
- 用Java做的模拟“双色球”机选号码
- python实现双色球_python实现双色球随机选号
- postman的完美替代品,超好用的api测试软件
编程思想 定义过滤的方式解耦相关推荐
- python class 是否存在某个变量_Python编程思想(29):使用type()函数定义类
----------支持作者请转发本文-----------李宁老师已经在「极客起源」 微信公众号推出<Python编程思想>电子书,囊括了Python的核心技术,以及Python的主要函 ...
- linux sh 定义变量,Shell编程定义变量的方式有哪些?
1. 三种定义变量的方式 (1) 直接赋值 (2) 传参 (传递参数) (3) 交互式设置变量,使用read命令 2. read命令说明 在命令行中使用[root@oldboy scripts]# r ...
- Java编程思想 (1~10)
[注:此博客旨在从<Java编程思想>这本书的目录结构上来检验自己的Java基础知识,只为笔记之用] 第一章 对象导论 1.万物皆对象 2.程序就是对象的集合 3.每个对象都是由其它对象所 ...
- 《Go语言精进之路,从新手到高手的编程思想、方法和技巧1》读书笔记和分享
Go语言精进之路,从新手到高手的编程思想.方法和技巧 读书分享 1 本书定位 2 本书内容总览 3 选择本书的原因 4 小收获分享 第7-12条 真的不知道咋命名 第13-19条 能用--怎么用更好 ...
- 编程_三大编程思想:POP、OOP、AOP
文章目录 三大编程思想 POP:面向过程编程 优点: 缺点: OOP:面向对象编程 1.抽象性: 2.封装性: 3.继承性: 4.多态性: 优点: 缺点: AOP:面向切面编程 优点: 缺点: 总结 ...
- 23种开发设计模式总结,追求高内聚低耦合的编程思想。
目录 一.概述 二.7个设计原则 1.单一职责原则 ( SRP ) 2.开闭原则 ( OCP ) 3.里氏替换原则 ( LSP ) 4.依赖倒置原则 ( DIP ) 5.接口隔离原则 ( ISP ) ...
- Rxswift学习之(一)函数响应式编程思想
Rxswift学习之(一)函数响应式编程思想 1. 函数响应式编程思想必备基本概念简介 2. iOS中三种编程思想:链式.函数式和响应式编程 2.1 链式编程 2.2 函数式编程 2.3 响应式编程 ...
- 【java】《java编程思想》 读书笔记
之前主要用的C++的比较多,之前花了快2个月的实际认真系统全面的学习了以下java的基础语法,<java编程思想>这本书翻译水平确实不是很好,很多话读着会比较拗口.推荐读之前,先去网上搜索 ...
- Java编程思想日志
Thinking In Java的作者是大牛!做事要站在巨人的肩膀上有助于提高效率和开阔眼界!建议学习java的小伙伴儿有时间可以抽空了解一下,以下内容为读书笔记,比较杂乱,仅供参考,推荐阅读原著: ...
最新文章
- 分布式之elk日志架构的演进
- [转]JDBC中日期时间的处理技巧
- C程序设计的抽象思维-递归过程-砝码称重
- linux环境下的小练习
- Ruby中求50之内的素数方法
- java filesystem 追加_java 如何往已经存在的excel表格里面追加数据的方法
- MySQL5.6开启慢查询
- OpenSession与getCurrentSession的区别
- JUnit学习摘要+入门实例 (junit4)
- 【转】三、QT例子-打开一个图片并且显示
- oracle o7参数,Oracle技术之初始化参数O7_DICTIONARY_ACCESSIBILITY
- 计蒜客---函数规律
- 系统学习NLP(十七)--文本相似度
- IDEA反编译java.class文件
- Mac 下载破译版本 secureFX 和 secureCRT
- 用计算机三角函数公式,电脑是通过什么公式计算出三角函数的?
- HTML中的SEO优化
- new Date在safair浏览器中不兼容
- 数据库课程设计:图书信息管理系统(Java+MySQL)(附程序)
- 音视频编解码流程与如何使用 FFMPEG 命令进行音视频处理