Oop 模块化设计和模块间参考

Oop 模块化设计和模块间参考,oop,design-patterns,Oop,Design Patterns,我不太确定这个标题是否与我想提出的这个问题相匹配 我计划创建一个web MVC框架作为我的毕业论文,在之前与我的导师的一次对话中,他试图定义一些成就,他说服我在这个项目中应该选择模块化设计 那时我已经开发了一些东西,停下来分析了一下它的模块化程度,但我无法真正做到这一点,因为我不知道“模块化”的真正含义 有些事情对我来说不是很清楚,比如,仅仅引用另一个模块就破坏了我系统的模块性 假设我有一个数据库访问模块,它可以选择使用缓存模块来存储复杂查询的结果。正如任何人所看到的,我至少对缓存模块有一个命名

我不太确定这个标题是否与我想提出的这个问题相匹配

我计划创建一个web MVC框架作为我的毕业论文,在之前与我的导师的一次对话中,他试图定义一些成就,他说服我在这个项目中应该选择模块化设计

那时我已经开发了一些东西,停下来分析了一下它的模块化程度,但我无法真正做到这一点,因为我不知道“模块化”的真正含义

有些事情对我来说不是很清楚,比如,仅仅引用另一个模块就破坏了我系统的模块性

假设我有一个数据库访问模块,它可以选择使用缓存模块来存储复杂查询的结果。正如任何人所看到的,我至少对缓存模块有一个命名依赖项

在我的“模块化设计”概念中,我可以将每个组件单独分发,并使其与其他人开发的其他组件交互。在本例中,我展示了,如果有人想使用我的数据库访问模块,他们也必须获取缓存,即使他不使用它,只是为了引用/命名目的

所以,我想知道这是否真的是一个模块化设计

我提出了一个替代方案,类似于单独创建每个组件,而不知道其他组件的存在,这些组件的功能不是绝对必需的。为了扩展功能,我可以基于装饰器和适配器创建一些结构

为了稍微澄清一下,下面是一个示例(在PHP中):

之前 之后 现在我的问题是: 这是最好的解决方案吗?我应该这样做的所有模块,没有作为一个要求一起工作,但可以更有效地这样做

有人会用不同的方式吗

我还有一些关于这方面的问题,但我不知道这是否是stackoverflow可以接受的问题

附言:英语不是我的第一语言,可能有些部分会让人有点困惑

一些资源(非理论):

  • (在那一边使用NoScript,他们有一些奇怪的登录策略)

  • 其他SO线程()

  • Django中间件概念

一些资源(非理论):

  • (在那一边使用NoScript,他们有一些奇怪的登录策略)

  • 其他SO线程()

  • Django中间件概念

我提出了一个替代方案,类似于单独创建每个组件,而不知道其他组件的存在,这些组件的功能不是绝对必需的

如果你自己想出这个主意,那就太好了。语句本身是模块化编程的关键

插件体系结构在可扩展性方面是最好的,但它很难维护,特别是在应用程序内部。根据插件架构的复杂性,它可以通过添加插件逻辑等方式使代码更加复杂

因此,对于模块内设计,我选择基于接口的N层体系结构。基本上,架构依赖于这些层:

  • 域/实体
  • 接口[取决于1]
  • 服务[取决于1和2]
  • 存储库/DAL[取决于1和2]
  • 表示层[取决于1,2,3,4]
  • 不幸的是,我认为这在php项目中是无法实现的,因为它需要在每一层中分别引用project/dll。但是,遵循体系结构有助于模块化应用程序

    对于每个模块,我们需要进行基于接口的设计。它有助于增强代码的模块性,因为您可以在以后更改实现,但仍然保持使用者不变

    在这个问题上,我提供了一个类似于基于接口的设计的答案

    最后但并非最不重要的一点是,如果您想使您的应用程序模块化到UI中,您可以执行
    面向服务的体系结构
    。这只是将您的应用程序作为一组服务,然后使用UI来使用服务。此设计有助于将UI与逻辑分离。您以后可以使用不同的UI,如桌面应用程序,但仍然使用相同的逻辑。不幸的是,我没有任何可靠的SOA来源

    编辑:

    我误解了这个问题。这是我对模块化框架的观点。不幸的是,我对Zend了解不多,所以我将用C#给出一些例子:

    • 它由模块组成,从最小的模块到较大的模块。C#中的示例是,您可以在应用程序中使用Windows
      窗体
      (较大)以及
      图形
      (较小)类在屏幕中绘制自定义形状
    • 它是可扩展的或可替换的,无需更改基类。在C#中,您可以将
      FormLoad
      事件(可扩展)分配给表单类,继承
      Form
      List
      类(可扩展)或重写表单绘制方法以创建自定义窗口图形(可替换)
    • (可选)易于使用。在正常的DI接口设计中,我们通常将较小的模块注入较大的(高级)模块。这将需要一个IOC容器。有关详细信息,请参阅我的
    • 易于配置,不涉及任何神奇的逻辑,如
      服务定位器模式
      。搜索
      服务定位器是谷歌的反模式
    我对Zend了解不多,但是我想Zend中的模块化意味着它可以在不改变框架内部核心(替换代码)的情况下进行扩展

    如果你说:

    如果有人想使用我的数据库访问模块,他们也必须获取缓存,即使他不使用它,只是出于引用/命名目的。
    interface Cache {
        public function isValid();
        public function setValue();
        public function getValue();
    }
    
    interface CacheManager {
        public function get($name);
        public function put($name, $value);
    }
    
    // Some concrete implementations...
    
    interface DbAccessInterface {
        public doComplexOperation();
    }
    
    class DbAccess implements DbAccessInterface {
        private $cacheManager;
    
        public function __construct(..., CacheManager $cacheManager = null) {
            // ...
            $this->cacheManager = $cacheManager;
        }
    
        public function doComplexOperation() {
            if ($this->cacheManager !== null) {
                // return from cache if valid
            } 
            // complex operation
        }
    }
    
    interface Cache {
        public function isValid();
        public function setValue();
        public function getValue();
    }
    
    interface CacheManager {
        public function get($name);
        public function put($name, $value);
    }
    
    // Some concrete implementations...
    
    interface DbAccessInterface {
        public function doComplexOperation();
    }
    
    class DbAccess implements DbAccessInterface {
        public function __construct(...) {
            // ...
        }
    
        public function doComplexQuery() {
            // complex operation
        }
    }
    
    // And now the integration module
    
    class CachedDbAcess implements DbAccessInterface {
        private $dbAccess;
        private $cacheManager;
    
        public function __construct(DbAccessInterface $dbAccess, CacheManager $cacheManager) {
            $this->dbAccess = $dbAccess;
            $this->cacheManager = $cacheManager;
        }
    
        public function doComplexOperation() {
            $cache = $this->cacheManager->get("Foo")
            if($cache->isValid()) {
                return $cache->getValue();
            }
            // Do complex operation...
        }
    }