应用场景 ">

项目模式(三)—— 分散的自组织模块

27 October 2019

应用场景

项目模块组成比较容易划分,接口不算复杂,每个模块可以用一个单例去表示的。每个模块中有很多种实现方法和配合方案,至于如何选择则通过配置决定。

不适合

  1. 无法使用单例承载的模块组织架构。也就是说,其他模块希望平行调用某个模块中的很多平行的方法。这种不适合使用这种松散耦合结构。

实现

.
├── project_name
    ├── module1
    │   ├── base.py
    │   ├── implementation_1.py
    │   ├── implementation_2.py
    │   └── __init__.py
    ├── module2
    │   ├── base.py
    │   ├── implementation_1.py
    │   ├── implementation_2.py
    │   └── __init__.py
  1. 在每个module中仅__init__作为引出的结构。其他模块不要访问其内部结构。
  2. 模块内部base.py(或使用某种有意义的名字)定义各种子模块(一般就是数据结构和一个核心类接口)
  3. __init__.py中导出抽象层(数据结构+单例的类),注意抽象层命名。尽量不要使用 Base, Abstract 字样。
  4. __init__.py还要导出一个工厂方法(可以lazy load)、或直接导出某个对象。在这个工厂方法中,可以无参数的构造某个对象,这个对象的构造需要使用哪个子类,需要哪些参数,都应由模块从配置中读取获得。

分析

  1. 这种方法从功能上来说,非常类似大工厂模式。每个工厂是一种配置组,通过不同的配置组去实现不同的功能组合。但是工厂模式如果用在此处有几个问题:

    1. 工厂是类,也就是代码,主要用在代码内部的实现。功能较重,可读性差,切换配置还需要重写工厂,不适合作为配置
    2. 一般配置都是相互无关的,个配个的,组合起来都能使用,和工厂这种产生组件的不一样。
    3. 工厂耦合了所有类的构造方式。而我们希望在每个模块里面建立自有的工程去生产该模块的产品(类似一个车间)。最终进行组合。

一些实现上的方案

  1. 堆叠项,对于一些模块,我们定义的是其中一步子任务的过程,而这种过程又是可以叠加的。那么有两种设计方式将多例转化为单例。

    • 装饰器模式:将某种基操定义在模块顶层,具体操作定义为装饰器,用以装饰顶层操作。
    • 堆叠项:设置一个特殊的操作,这个操作的输入是其他操作的组合,在项内解决如何综合结果的问题(Stack-Embedder/ Stack-processor 等)。
  2. 由于解决了依赖问题,每个模块可以认为是一个项目,可以递归的去构造项目(和配置)
  3. 和抽象工厂模式的兼容性:对于一些需要临时参数构造的类,可再使用抽象工厂进行包装。让模块返回的单例类为工厂,其他类通过这个工厂的基类去构造其想要的东西。
Loading Disqus comments...
Table of Contents