软件框架的要素

Scroll Down

0、框架的定义

框架通常是为了做某件事情,这件事情对用户透明。用户只需关注功能使用。

1、结构化语言描述一些信息

实现的方式通常有两种:
(1)、XML
(2)、注解

2、框架中的数据结构

用于框架运行时需要用到的关键数据结构,该数据结构中包含了描述某个实体的全部信息。

3、框架运行的主流程

就是完成一次运行的核心步骤。框架的运行过程中需要几个模块的协同。

协同的实现手段通常是通过按照业务进行分层,每一层都具有独有的功能意义。
协同的另一方面要求是每个分层都需要具备水平扩展的能力,以此来应对功能的变化。

另外在实体域的生命周期管理,通常有两种实现方式:
(1)、工厂模式
(2)、注册器

4、功能模块

在设计功能模块的时候,通常会先抽象出核心接口,该接口定义了操作方法。然后可以根据不同的场景对该接口进行实现,具体实现方式可以通过抽象类的方式将共性的内容进行提取,个性的内容子类实现。最后通过策略+工厂模式将获取该功能模块的方式暴露给上层调用。
有一些特殊的场景比如想要在模块上增加缓存、权限等等功能时可以使用装饰模式或者filter模式。

5、可扩展性

大凡一个优秀的框架通常的一个要求就是可扩展性非常好,达到可扩展性非常好的一个要求就是尽可能的发现、识别框架中的扩展点(未来会产生变化)。通常的实现方式是:
(1)、SPI
(2)、多层嵌套动态代理
(3)、接口加多实现类

另外还有一些其他的方式:
(1)、重要节点留出Filter
(2)、重要节点留出Listener

6、框架的边界及防腐

框架是有边界的,因为功能的限制,它不能无限制的支持各种功能,另外框架也是需要防腐层的,这种防腐层通常是使用适配器模式将三方的SDK隔离开来。

扩展点组装原则:按“微核+插件”体系组装。

但凡有生命力的产品,都是在扩展性方面设计的比较好的,因为没有哪个产品可以覆盖所有需求,对于开源软件尤其如此。

所以,产品只有具有良好的扩展性,允许用户或第三方参与进来,进行二次开发,才能保持生命力。

怎么样的扩展性才是最好的?通常来讲,就是没有任何功能是硬编码的,所有的功能都可被用户替换。

那要如何才能做到这样?一个重要的原则就是:平等对待第三方。

也就是凡是原作者能实现的功能,第三方也要能够在不改变源代码的前提下实现。

换言之,原作者应把自己也当作扩展者,自己添加功能时,也要用第三方扩展者同样的方式进行,而不要有特权。

要做到这一点,就需要一个良好的框架支撑,“微核+插件”是一个不错的选择,Eclipse, Maven等知名软件都采用该体系。

什么是“微核+插件”?微核,即最小化核心,内核只负责插件的组装,不带任何功能逻辑,所有功能都由可替换的插件实现,

并且,组装过程应基于统一的规则,比如基于setter注入,而不能对不同插件硬编码组装,这样可以确保没有任何功能在内核中硬编码。

比如:Spring, OSGI, JMX, ServiceLoader等都是常见的微核容器,它们负责基于统一规则的组装,但不带功能逻辑。

  1. 中心领域模型是什么?
  2. 微核心是什么?
  3. 给用户的API是什么?
  4. 给扩展者的SPI是什么?
  5. 扩展者可否基于微核心替换任意位置上的实现?
  6. 服务域,实体域,会话域各是什么?
  7. 客户端,服务器端各自关心什么?
  8. 所有涉众都考虑周全了?
  9. 有哪些需要特殊化处理?是否可以抽象到一起?
  10. 设计有没有防碍非功能性需求的优化?