《冒号课堂:编程范式与OOP思想》笔记二

《冒号课堂:编程范式与OOP思想》笔记二

第三课 常用范式

超级范式,元编程

泛型编程:Generic Programming,GP

GP基本思想:将算法与其作用的数据结构分离,并将后者尽可能泛化,最大限度地实现算法重用。以算法为起点和中心点。

函子:在范畴论中,函子是范畴间的一类映射。函子也可以解释为小范畴范畴内的态射。

STL有三要素:算法、容器和迭代器。算法使一系列切实有效的步骤;容器是数据的集合,可理解为抽象的数组;迭代器是算法与容器之间的接口,可理解为抽象的指针或游标。

容器通常以迭代器的形式参与过程。算法串联数据,如脊贯肉;数据实化算法,如肉附脊。

泛型思维:对指定集合中满足指定条件的元素进行指定处理。

泛型编程不仅能泛化算法中涉及地概念(数据类型),还能泛化行为(函数、方法、运算)。

Java泛型实现原理:类型擦除,编译为字节码时参数类型会在代码中被擦除,单独记录在Class文件的attributes域内,而在使用泛型处做类型检查与类型转换。

多态与泛化:多态性(polymorphism),可简单概括为“一个接口,多种方法”。是指相同对象收到不同消息或不同对象收到相同消息时产生不同的实现动作。泛化(Generalization)定义了一般元素和特殊元素之间的分类关系,是一种“a-kind-of”关系。泛化和继承不是一回事,其中心对象不同,如“苹果继承了水果,水果泛化了苹果。”

Lex、Yacc:能根据格式标准生成相应地解析器代码。是编写编译器和解释器的工具。设计编写DSL

领域特定语言(DSL)一般通过现成的编译器生成器首先转化为第三代的高级语言。

元编程(Metaprogramming,MP)作为超级范式的一个体现是,它能提升语言的级别。进一步思考,便是语言导向式编程(Language-Oriented Programming,LOP),其思路是,在建立一套DSL体系之后,直接用它们来编写软件。

MP,LOP都是提供越来越高级的抽象,使编程语言更符合人类思考的方式。越来越专业化,应用的领域也越来越狭窄。
在这里插入图片描述

如果处理一些复杂、非标准格式的文档,可以考虑用元编程;如果整个业务逻辑复杂多变,可以考虑利用现有的DSL或创造新的DSL来处理业务。

针对小的业务要求,可以利用使用中的编程语言自带的特性进行元编程;对于大而复杂的业务系统,可以考虑设计一个新的DSL以适应业务要求。

元编程应用:IDE通过向导、、拖放控件等方式自动生成源码;UML建模工具将类图转换为代码;Servlet引擎将JSP转换为Java代码;Spring、Hibernate等框架和工具能从配置文件、annotation/attribute等中产生代码。

IDE内置的代码生成功能,一方面局限性很大,另一方面无法自动化和版本化。

IDE下自动生成的代码本身可以被记录,但产生代码时的行为却不能被记录。可以自编无需人机交互的元程序来生成代码,只须将元程序的数据来源版本化。

产生式编程(Generative Programming),自动生成源代码。其更看重代码的生成。而静态元编程看重的是生成代码的可执行性。此外,动态元编程并不生成源代码,但能在运行期间修改程序。

元编程是编写、操纵程序的程序。在传统的编程中,运算是动态的,但程序本身是静态的;在元编程中,二者都是动态的。

元编程写出一套规则,利用这套规则生成适应特定情况的源代码。“正则表达式”

切面范式

面向切面编程:Aspect Oriented Programming,AOP

关注点分离:Separation of Concerns,SoC

尽量减少重复代码:Don’t Repeat Yourself

抽象是前提,分解是方式,模块化是结果。

我们先将业务中的对象抽象为现实实体和逻辑实体(抽象),再根据业务逻辑将对象和行为提取出来(分解),分别将对象和行为用代码实现(模块化)。

抽象与分解的原则:单一化,正交化。每一个模块职责明确专一,模块之间相互独立,即高内聚低耦合。

人类能同时处理的逻辑实体至多六个。所以代码尽可能简单、清晰。结合《代码大全》看

AOP将每类横切关注点封装到单独的Aspect模块中,将程序中的一些执行点与相应的代码绑定起来。单个的执行带你称为接入点(join point)。例如调用某个对象的方法前后;符合预先指定条件的接入点集合称为切入点(pointcut)。再如所有以set为命名开头的方法;每段绑定的代码称为一个建议(advice)。

  • Aspect – a standard code/feature that is scattered across multiple places in the application and is typically different than the actual Business Logic (for example, Transaction management). Each aspect focuses on a specific cross-cutting functionality
  • Joinpoint – it’s a particular point during execution of programs like method execution, constructor call, or field assignment
  • Advice – the action taken by the aspect in a specific joinpoint
  • Pointcut – a regular expression that matches a joinpoint. Each time any join point matches a pointcut, a specified advice associated with that pointcut is executed
  • Weaving – the process of linking aspects with targeted objects to create an advised object

面向切面编程,根据需要,动态的将重复的代码切入到指定类的指定位置上的方法

切入的代码片段是建议,多为重复且与切入类关系不大的代码;切入的类和方法称为切入点。切入点与建议组成了切面。切入的过程称为编织。编织分为静态编织:通过修改源码或字节码在编译期、后编译期或加载期嵌入代码;动态编织:通过代理等技术在运行期实现嵌入通过AOP,可以将几个类共有但关系都不大的代码封装到切面中,按需切入。满足了“高内聚,松耦合”要求

AOP的实施分为三步:切面分解、切面实现和切面合成。需要程序员编码的部分在第二步。

在这里插入图片描述

AOP更适合与大中型程序。对于小型程序,AOP带来的复杂度和性能损耗可能远大于便利。

OOP只能沿继承树纵向方向重用,AOP可以沿横向方向重用。

事件驱动

基于事件驱动的系统一般提供两类内建事件:一类是底层事件或称原生事件,在GUI系统中这类事件直接由鼠标、键盘等硬件设备触发;一类是语义事件,一般代表用户的行为逻辑,是若干底层事件的组合。比如鼠标拖放。

程序员也可以创建用户自定义事件。模拟用户鼠标点击或键盘输入等产生事件,称为合成事件。

WinForm,爬虫

创建一个能响应用户操作的win32窗口共分四步:注册窗口类别、创建窗口、消息循环和窗口过程。

消息和事件从严格来说不是一回事,消息是Windows内部最基本的通信方式,事件需要通过消息来传递。是消息的主要来源。每当用户触发一个事件,系统都会将其转化为消息并放入相应程序的消息序列中。

函数指针是C和C++用来实现callback的一种方式。此外,抽象类、接口、C++中的泛型函子和C#中的委托都可以实现callback。

Java实现:

//文件1 声明callback函数

public interface callbackF{
    pubilc void doSomething(int para1,int para2,int result);
}

//文件2 实现callback函数
public class Test implements callbackF{
    private int a = 0;
    private int b = 0;
    
    public Test(int a, int b){
        this.a = a;
        this.b = b;
    }
    @Override
    public void doSomething(int a, int b, int result){
        System.out.println(a+b+result);
    }
}

//文件3 调用callback函数
 
public class CallF{
    public void helpDoSomething(int para1,int para2, callbackF callbacked){
        int res = para1 + para2;//对其进行操作
        callbacked.doSomething(para1, para2, res);//调用callback函数
    }
}

在这里插入图片描述

同步回调和异步回调都使调用者不再依赖被调者,将二者从代码上解耦,异步调用更将二者从时间上解耦。

控制反转(Inversion of Control,IoC):一般用callback来实现,其目的是降低模块之间的依赖性,从而降低模块的耦合度和复杂度。

依赖反转原则(Dependency-Inversion Principle,DIP):高层模块不应依赖底层模块,它们都应依赖抽象;抽象不应依赖细节,细节应依赖抽象。

依赖注射(Dependency Injection,DI):动态的为一个软件组件提供外部依赖。

独立是异步的前提,耗时是异步的理由。

只有独立了,才能将其剥离出来;因为无用的过程消耗了大量时间,所以要进行异步处理。

事件驱动式编程的三个步骤:实现事件处理器;注册事件处理器;实现事件循环。

观察者模式又名发行/订阅模式,既是事件驱动式的简化,也是事件驱动的核心思想。MVC架构是观察者模式在架构设计上的一个应用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章