命令式编程和声明式编程

常见图像加密性能评价指标(详解加python实现) 前言 本文目的 介绍一些常见的用于图像加密的评价指标并予以代码实现,方便以后做实验时参考查阅。 图像加密领域所有常见的安全分析技术汇总如下图。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7N8tbKNx-1618308894314)(%E5%B8%B8%E8%A7%81%E5%9B%BE%E5%83%8F%E5%8A%A0%E5%AF%86%E6%80%A7%E8%83%BD%E8%AF%84%E4%BB%B7%E6%8C%87%E6%A0%87/1-s2.0-S0165 阅读详情
Aspect Oriented Programming(面向方面编程,简称AOP)是一种Declarative Programming(声明式编程)。Declarative Programming(声明式编程)是和Imperative Programming(命令式编程)相对的概念。我们平时使用的编程语言,比如C++、Java、Ruby、Python等,都属于Imperative Programming(命令式编程)。Imperative Programming(命令式编程)的意思是,程序员需要一步步写清楚程序需要如何做什么(How to do What)。Declarative Programming(声明式编程)的意思是,程序员不需要一步步告诉程序如何做,只需要告诉程序在哪些地方做什么(Where to do What)。比起Imperative Programming(命令式编程)来,Declarative Programming(声明式编程)是在一个更高的层次上编程。Declarative Programming编程语言是更高级的语言。Declarative Programming通常处理一些总结性、总览性的工作,不适合做顺序相关的细节相关的底层工作。


如果说Imperative Programming是拼杀在第一线的基层工作人员,Declarative Programming就是总设计师、规则制定者。Declarative Programming Language的概念,和Domain Specific Language(领域专用语言,简称DSL)的概念有相通之处。DSL主要是指一些对应专门领域的高层编程语言,和通用编程语言的概念相对。DSL对应的专门领域(Domain)一般比较狭窄,或者对应于某个行业,或者对应于某一类具体应用程序,比如数据库等。

最常见的DSL就是关系数据库的结构化数据查询语言SQL。同时,SQL也是一门Declarative Programming Language。SQL只需要告诉数据库,处理符合一定条件的数据,而不需要自己一步步判断每一条数据是否符合条件。SQL的形式一般是 select … where …,update … where …,delete … where …。当然,这样一来,很多基层工作,SQL做不了。因此,大部分数据库都提供了另外的Imperative Programming Language,用来编写Stored Procedure(存储过程)等,以便处理一些更加细节的工作。

常见的DSL还有Rule Engine(规则引擎)语言、Workflow(工作流)语言等。Rule Engine和Workflow同时带有Imperative Programming和Declarative Programming的特点。Rule Engine允许用户按照优先级定义一系列条件组合,并定义对满足条件的数据的处理过程。Workflow也大致类似。Workflow把最基本的条件判断和循环语句的常见组合,定义为更加高级复杂的常用程序流程逻辑块。用户可以用这些高级流程块组合更加复杂的流程块,从而定义更加复杂的流程跳转条件。用户也可以定义当程序运行上下文满足一定条件的时候,应该做什么样的处理工作。Rule Engine和Workflow的语言形式有可能是XML格式,也有可能是Ruby、Python、Javascript等脚本格式。我个人比较倾向于脚本格式,因为XML适合表达结构化数据,而不擅长表达逻辑流程。当然,XML格式的好处也是显而易见的。解析器可以很容易分析XML文件的结构,XML定义的条件或者程序流程都可以很方便地作为数据来处理。

介绍了Declarative Programming和DSL之后,我们来看本章题目表达的内容——AOP。AOP是Declarative Programming,AOP语言也可以看作是DSL。AOP语言对应的专门领域(Domain)就是程序结构的方方面面(Aspect),比如程序的类、方法、成员变量等结构,以及针对这些程序结构的通用工作处理,比如日志管理、权限管理、事务管理等。

AOP处理的工作内容一般都是这样的一些总结性工作:“我想让所有的数据库类都自动进行数据库映射”、“我想打印出所有业务类的工作流程日志”、“我想给所有关键业务方法都加上事务管理功能”、“我想给所有敏感数据处理方法都加上安全管理授权机制”等等。
下面我们介绍AOP的实现原理和使用方法。

AOP实现原理

AOP的实现原理可以看作是Proxy/Decorator设计模式的泛化。
我们先来看Proxy模式的简单例子。
Proxy {
    innerObject; // 真正的对象
    f1() {
        // 做一些额外的事情

        innerObject.f1(); // 调用真正的对象的对应方法

          // 做一些额外的事情
    }
}

在Python、Ruby等动态类型语言中,只要实现了f1()方法的类,都可以被Proxy包装。在Java等静态类型语言中,则要求Proxy和被包装对象实现相同的接口。动态语言实现Proxy模式要比静态语言容易得多,动态语言实现AOP也要比静态语言容易得多。假设我们用Proxy包装了10个类,我们通过调用Proxy的f1()方法来调用这10个类的f1()方法,这样,所有的f1()调用都会执行同样的一段“额外的工作”,从而实现了“所有被Proxy包装的类,都执行一段同样的额外工作”的任务。这段“额外的工作”可能是进行日志记录,权限检查,事务管理等常见工作。

Proxy模式是可以叠加的。我们可以定义多种完成特定方面任务(Aspect),比如,我们可以定义LogProxy、SecurityProxy、TransactionProxy,分别进行日志管理、权限管理、事务管理。
LogProxy {
      f1(){
            // 记录方法进入信息

            innerObject.f1();// 调用真正的对象的对应方法

          // 记录方法退出信息
    }
}

SecurityProxy {
      f1(){
          // 进行权限验证

          innerObject.f1();// 调用真正的对象的对应方法
      }
}

TransactonProxy {
      f1(){
          Open Transaction

          innerObject.f1();// 调用真正的对象的对应方法

          Close Transaction
      }
}

根据AOP的惯用叫法,上述的这些Proxy也叫做Advice。这些Proxy(or Advice)可以按照一定的内外顺序套起来,最外面的Proxy会最先执行。包装f1()方法,也叫做截获(Intercept)f1()方法。Proxy/Advice有时候也叫做Interceptor。

看到这里,读者可能会产生两个问题。
问题一:上述代码采用的Proxy模式只是面向对象的特性,怎么会扯上一个新概念“面向方面(AOP)”呢?
问题二:Proxy模式虽然避免了重复“额外工作”代码的问题,但是,每个相关类都要被Proxy包装,这个工作也是很烦人。AOP Proxy如何能在应用程序中大规模使用呢?
下面我们来解答着两个问题。

对于问题一,我们来看一个复杂一点的例子。
假设被包装对象有f1()和f2()两个方法都要被包装。
RealObject{
      f1() {…}
      f2() {…}
}

这个时候,我们应该如何做?难道让Proxy也定义f1()和f2()两个方法?就象下面代码这样?
Proxy {
    innerObject; // 真正的对象
    f1() {
        // 做一些额外的事情

        innerObject.f1(); // 调用真正的对象的对应方法

        // 做一些额外的事情
    }

    f2() {
        // 做一些额外的事情
       
        innerObject.f2(); // 调用真正的对象的对应方法
       
        // 做一些额外的事情
    }

}

这样做有几个不利之处。一是会造成代码重复,Proxy的f1()和f2()里面的“做一些额外的事情”代码重复。二是难以扩展,被包装对象可能有多个不同的方法,不同的被包装对象需要被包装的方法也可能不同。现在的问题就变成,“Proxy如何才能包装截获任何类的任何方法?”
答案呼之欲出。对,就是Reflection。Java、Python、Ruby都支持Reflection,都支持Method(方法)对象。那么我们就利用Method Reflection编写一个能够解惑任何类的任何方法的Proxy/Advice/Interceptor。

MethodInterceptor{

    around( method ){
        // 做些额外的工作
       
        method.invoke(…); // 调用真正的对象方法
       
        // 做些额外的工作
    }
}

上述的MethodInterceptor就可以分别包装和截获f1()和f2()两个方法。
这里的method参数就是方法对象,在Java、Ruby等面向对象语言中,需要用Reflection获取方法对象。这个方法对象就相当于函数式编程的函数对象。在函数式编程中,函数对象属于“一等公民”,函数对象的获取不需要经过Reflection机制。所以,函数式编程对AOP的支持,比面向对象编程更好。由此我们看到,AOP对应的问题领域确实超出了OOP的力所能及的范围。OOP只能处理同一个类体系内的同一个方法签名的截获和包装工作,一旦涉及到一个类的多个不同方法,或者多个不同类体系的不同方法,OOP就黔驴技穷,无能为力了。
使用Method Reflection的方式截获任何方法对象,是AOP的常用实现手段之一。另一个常见手段就是自动代码生成了。这也回答了前面提出的问题二——如何在应用系统中大规模使用AOP。

Proxy Pattern + Method Reflection + 自动代码生成这样一个三元组合,就是AOP的基本实现原理。Proxy Pattern 和 Method Reflection,前面已经做了阐述,下面我们来讲解自动代码生成。

首先,AOP需要定义一种Aspect描述的DSL。Aspect DSL主要用来描述这样的内容:“用TransactionProxy包装截获business目录下的所有类的公共业务方法”、“ 用SecurityProxy包装截获所有Login/Logout开头的类的所有公共方法”、“用LogProxy包装截获所有文件的所有方法”等等。Aspect DSL的形式有多种多样。有的是一种类似Java的语法,比如AspectJ;有的是XML格式或者各种脚本语言,比如,Spring AOP等。

有了Aspect DSL,AOP处理程序就可以生成代码了。AOP生成代码有三种可能方式:
(1)静态编译时期,源代码生成。为每个符合条件的类方法产生对应的Proxy对象。AspectJ以前就是这种方式。
(2)静态编译时期,处理编译后的字节码。Java、Python之类的虚拟机语言都有一种中间代码(Java的中间代码叫做字节码),AOP处理程序可以分析字节码,并直接产生字节码形式的Proxy。这种方式也叫做静态字节码增强。AspectJ也支持这种方式。Java有一些开源项目,比如 ASM、Cglib等,可以分析并生成Java字节码。这些开源项目不仅可以静态分析增强字节码,还可以在程序运行期动态分析增强字节码。很多AOP项目,比如Spring AOP,都采用ASM/Cglib处理字节码。
(3)动态运行时期,即时处理装载到虚拟机内部的类结构字节码。这也叫做动态增强。比如,Spring AOP。如前所述,Spring AOP使用ASM/Cglib之类的处理字节码的开源项目。Java运行库本身也提供了类似于ASM/Cglib的简单的动态处理字节码的API,叫做 Dynamic Proxy。

以上就是AOP的实现原理:Proxy Pattern + Method Reflection + Aspect DSL + 自动代码生成。

总体来说,实现AOP的便利程度,函数式编程语言 > 动态类型语言 > 静态类型语言。当然,这个不等式并不是绝对的。有些动态类型语言提供了丰富强大的语法特性,实现AOP的便利程度,可能要超过函数式编程语言。
PCIe Gen4 Switch芯片PM40028调试踩坑实录:从boot引脚设置到串口无输出的诡异问题 本文记录了PCIe Gen4 Switch芯片PM40028的实战调试过程,重点剖析了从boot引脚配置错误导致串口无输出,到使用逻辑分析仪定位并解决启动问题的完整排障思路。文章深入探讨了芯片启动流程、硬件信号测量方法,并总结了高速硬件调试的核心经验与系统性排查清单,为工程师解决类似PCIe Gen4设备调试难题提供实用指南。 阅读详情

相关推荐

别再死记硬背了!用这5个Qt Design Studio小项目,彻底玩转核心组件

本文通过5个Qt Design Studio实战项目,帮助开发者深入理解核心组件的协作与应用。从动态登录界面到游戏化任务列表,每个项目都展示了组件属性与交互设计的巧妙结合,让你不再死记硬背,而是真正掌握Qt Design Studio的核心技能。

weixin_29202213的博客 271

AOP实现原理:从命令式编程和声明式编程说起

面向方面编程(Aspect Oriented Programming,简称AOP)是一种声明式编程(Declarative Programming)。声明式编程是和命令式编程(Imperative Programming)相对的概念。我们平时使用的编程语言,比如C++、Java、Ruby、Python等,都属命令式编程。命令式编程的意思是,程序员需要一步步写清楚程序需要如何做什么(How to d

我的学习历程 1630

PostGIS 小白入门详细指南

PostGIS 是 PostgreSQL 的一个扩展,它将 PostgreSQL 转变为一个功能强大的空间数据库,使其能够存储、查询和分析地理空间数据。PostGIS 遵循开放地理空间联盟(OGC)的标准,支持各种空间数据类型和操作,如点、线、多边形、缓冲区、空间连接等。存储各种空间数据类型(如几何类型和地理类型)空间索引,提高查询性能丰富的空间函数和操作支持投影和坐标系统转换城市规划与管理环境监测与分析物流与运输优化地图制作与可视化位置服务与导航。

落魄书生的职业学习生涯 1万+

一步一步学习spring(七)——采用声明方式实现AOP的例子

上篇博客中描述了一个采用注解形式实现spring中AOP的例子,下面向大家展示一下采用 spring中声明的方式实现Spring AOP的实例。 采用注解实现的,大家可参考该blog: [url]http://xtu-xiaoxin.iteye.com/blog/630206[/url] 先向大家声明,该篇博客只是给新手一个关于AOP的例子,以及方便我...

yingxiongtnt的专栏 175

2026深度破解:OpenClaw开源AI框架架构与实战全景解析

2026年初,一款名为OpenClaw的开源AI Agent框架以惊人的速度席卷全球开发者社区,短短数周GitHub星标突破20万,成为史上增长最快的开源项目。本文从架构设计、核心原理、代码实现和工程实战四个维度,深度剖析OpenClaw的技术内核,帮助开发者从理解到实践,快速掌握这一革命性的AI开发框架。

fox0329的博客 2373

adb详细教程(四)-使用adb启动应用、关闭应用、清空应用数据、获取设备已安装应用列表

adb对于安卓移动端来说,是个非常重要的调试工具。通过ADB可以操作、管理设备上的应用。

公众号|软件测试老吴 3万+

注解和声明方式实现AOP

下面主要描述spring中使用AOP的两个例子:一个采用注解的方式来实现,另一个采用声明的方式来实现。描述这两个例子有两个目的:一是熟悉spring中的AOP使用,二就是以这些例子作为以后对spring AOP分析作铺垫。废话少说,首先复兴下AOP种一些比较重要的概念:     Joinpoint(连接点):程序执行时的某个特定的点,在Spring中就是某一个方法的执行     Pointcu

RYP_S 的专栏 702

springboot+shardingsphere+druid 实现基于时间的水平分表

使用shardingsphere基于时间字段的动态水平分片。

weixin_42207940的博客 2627

AOP如何实现及实现原理

概述: 最近在开发中遇到了一个刚好可以用AOP实现的例子,就顺便研究了AOP的实现原理,把学习到的东西进行一个总结。文章中用到的编程语言为kotlin,需要的可以在IDEA中直接转为java。 这篇文章将会按照如下目录展开: AOP简介 代码中实现举例 AOP实现原理 部分源码解析 1. AOP简介 相信大家或多或少的了解过AOP,都知道它是面向切面编程,在网上搜索可以找到很多的解释。这里我用...

weixin_34224941的博客 5582

CarPlay盒子选购避坑指南:为什么你的车机破解了却用不了?从USB设备ID说起

本文深入解析CarPlay盒子硬件兼容性问题,从USB设备ID匹配到车机适配逻辑,揭示破解成功却无法使用的根本原因。通过分析USB设备识别的核心要素和逆向工程usb_device_manager.xml文件,提供三种主流解决方案对比,并强调操作中的硬件保护机制,帮助车主避免常见陷阱。

weixin_30706691的博客 474

【数据集】MODIS 的 MOD07 大气廓线产品概述及下载

MODIS 的 MOD07 大气廓线产品概述及下载

WW、forever的博客 550

Spring系列之AOP实现的两种方式

AOP常用的实现方式有两种,一种是采用声明的方式来实现(基于XML),一种是采用注解的方式来实现(基于AspectJ)。 首先复习下AOP中一些比较重要的概念: Joinpoint(连接点):程序执行时的某个特定的点,在Spring中就是某一个方法的执行 。Pointcut(切点):说的通俗点,spring中AOP的切点就是指一些方法的集合,而这些方法是需要被增强、被代理的。一般都是按照一定的约定规则来表示的,如正则表达式等。切点是由一类连接点组成。Advice(通知):还是说的通俗点,就是在指定切点上

u013733643的博客 2872

零基础学simulink仿真建模--使用Simulink来构建一个混合动力无人机中燃料电池与锂电池协同控制的仿真模型

延长飞行时间:燃料电池的能量密度高于锂电池,适合长时间稳定供电。提高功率密度:锂电池能够快速响应瞬时高功率需求,比如起飞和加速阶段。优化能源管理:通过有效的能量管理系统,可以根据实际需求动态调整燃料电池和锂电池的工作状态,从而提高整体效率。通过上述步骤,我们简要介绍了如何基于Simulink实现混合动力无人机中燃料电池与锂电池协同控制的仿真模型。

amy_mhd的博客 190

【命令式编程和声明式编程】

显而易见,你只是想要吃糖醋排骨,至于糖醋排骨是你妈妈忙活一番做出来的,还是你妈妈点了外卖,外卖小哥冒着风雪送来的,只要糖醋排骨能让你满意,其它的你也许都不关心。操作DOM时,你关注的是结果,而js操心的是怎么把你要的结果都找到和拿回来,你是在做声明式编程,而js引擎是在做命令式编程。在家时,你关注的是糖醋排骨,妈妈操心怎么给你弄来糖醋排骨,你是在做声明式编程,而你妈妈是在做命令式编程。在公司时,领导关注的是业绩,你操心的是怎么把业绩做到上千,领导是在做声明式编程,而你是在做命令式编程。

橙子的博客 1434

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

声明式编程和命令式编程

命令式编程(Imperative Programming)是一种编程范式,它通过明确的步骤和指令告诉计算机如何执行任务。这种编程风格非常详细,程序员需要明确地指定计算机的操作顺序。声明式编程(Declarative Programming)是一种编程范式,强调描述“做什么”而不是“怎么做”。在声明式编程中,程序员定义预期的结果或行为,而不是编写实现这些结果的具体步骤。编译器或解释器负责确定如何实现这些结果。

weixin_44814196的博客 1033

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

声明式和命令式编程_命令式与声明式编程

声明式和命令式编程At this point you’ve undoubtedly heard about imperative programming vs declarative programming. You might have even searched for what those terms actually mean. 至此,您无疑已经听说了命令式编程与声明式编程。 您甚至可能已...

cumi6497的博客 849

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

声明式编程和命令式编程的比较

原文 :Imperative vs Declarative 作者 @Philip Roberts 先统一一下概念,我们有两种编程方式:命令式和声明式。 我们可以像下面这样定义它们之间的不同: 命令式编程:命令“机器”如何去做事情 (how),这样不管你想要的是什么 (what) ,它都会按照你的命令实现。 声明式编程:告诉“机器”你想要的是什么 (what),让机器想出如何去做 (how)。 声明式编程和命令式编程的代码例子 举个简单的例子,假设我们想让一个数组里的数值翻倍。 我们用命令式编程风格实现,

gdtown的博客 1335

编程中的声明式范式和命令式范式有什么区别?

我一直在网上搜索 declarative 和 imperative 编程的定义,这将为我带来一些启发。但是,在我发现的一些资源中使用的语言令人生畏——例如在 Wikipedia。有没有人有一个真实的例子,他们可以向我展示这可能会给这个主题带来一些观点(也许在 C# 中)?

HuntsBot的博客 1363

命令式编程、声明式编程和函数式编程的理解与思考

命令式、声明式和函数式三种编程范式都各有特色。 命令式编程关注的是具体步骤。 声明式编程关注的是最后的结果。 函数式编程在声明式编程基础上更进一步,将函数作为第一公民。 命令式编程 在平时常见的编程范式就是命令式编程。 来个生活中的例子说明一下什么是命令式编程。比如,小红想吃西红柿炒鸡蛋,然后她妈妈就去买菜、洗菜、做好西红柿炒鸡蛋。小红她妈妈就是在执行命令式编程,必须清楚的知道每一步的动作。 下面...

一直在努力的小渣渣 4821

[转]声明式编程和命令式编程的比较

英文原文:Imperative vs Declarative 先统一一下概念,我们有两种编程方式:命令式和声明式。 我们可以像下面这样定义它们之间的不同: ■ 命令式编程:命令“机器”如何去做事情(how),这样不管你想要的是什么(what),它都会按照你的命令实现。 ■ 声明式编程:告诉“机器”你想要的是什么(what),让机器想出如何去做(how)。 声明式编程和命令式编程的代码例子 举个简...

fate252的博客 351

一文读懂命令式、声明式和函数式编程

大家好,我是二毛。话不多说,直接进入主题。1. 命令式编程(Imperative Programming)命令式编程是一种以“怎么做”为核心的编程范式,程序员需要明确地告诉计算机如何一步步地完成任务。在这种范式中,程序由一系列的语句组成,每个语句都改变程序的状态。特点:强调步骤和过程,即如何实现某个目标。程序员需要管理程序的状态变化。典型的命令式编程语言包括 C、C++、Java、Python 等...

qq_38606782的博客 3756

编程语言的主要类型,声明式编程,命令式编程()和函数式编程的区别

编程语言的主要类型Common programming paradigms include imperative which allows side effects, functional which disallows side effects, declarative which does not state the order in which operations execute (翻译:

默默的守护的专栏 9079

声明式和命令式编程_命令式与声明式Swift编程

声明式和命令式编程Difficulty: Beginner | Easy | Normal | Challenging 难度:初学者| 容易 | 普通| 具有挑战性的 This article has been developed using Xcode 11.4.1, and Swift 5.2.2 本文是使用Xcode 11.4.1和Swift 5.2.2开发的。 先决条件: (Prer...

weixin_26638123的博客 389

声明式编程和命令式编程的区别

声明式编程和命令式编程的区别

人生快意事,读的好书,觅得良友 900

命令式和声明式编程的区别

命令式和声明式编程的区别 声明式和命令式是两种编程范式。react是声明式的,jquery那样直接操作dom是命令式. 一般来说,声明式编程关注于发生了啥,而命令式则同时关注于咋发生的。 ...

actionzh的博客 1228

java理论知识之命令式编程,声明式编程和函数式编程的区别

命令式编程,声明式编程和函数式编程的区别

亲测,只为展现最完美的有效! 1934
上一篇: 浅谈 Java 中 this 的使用
下一篇: Oracle 归档日志
Hack_Bug
博客等级 码龄15年 34粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值