gpt4 book ai didi

Perl 模块层次结构和组合

转载 作者:行者123 更新时间:2023-12-04 22:56:55 25 4
gpt4 key购买 nike

阅读更多关于 Perl 的内容后,我开始怀疑我是如何在当前项目中组织模块的。

我有一个主命名空间——我们称之为“MyProject”。

在这个项目中,基础数据是每个对象都有一个类的图。对象与关系相关联。对象和关系都可以具有属性。

在项目的一部分中,我使用模型来验证这些图表。
所以我有一个模型类,它由类、关系和属性的对象组成。

类 Class、Relation 和 Attribute 仅由类 Model 使用,所以对我来说,按如下方式组织模块是有意义的:

  • 我的项目::型号
  • MyProject::Model::Class
  • MyProject::Model::Relation
  • MyProject::Model::Attribute

  • 但我开始认为,只有当我敢于在 CPAN 中发布我的项目的部分内容时,它才会对我有意义。我想人们会相信 Class、Relation 和 Attribute 是继承 Model 而不是组成它。

    所以:我应该以这种方式重新组织我的模块:
  • 我的项目::型号
  • MyProject::Class
  • 我的项目::关系
  • 我的项目::属性

  • 或者也许通过附加它们的名称来表明 Class、Relation 和 Attribute 是 Model 的一部分?
  • 我的项目::型号
  • MyProject::ModelClass
  • MyProject::ModelRelation
  • MyProject::ModelAttribute

  • 我的问题 :在组合方面,目前认为模块组织和命名的最佳实践是什么?

    Cross-posted at Perlmonks

    最佳答案

    你的担心是正确的。通常,包通过包含或继承来命名。我要编一个更现实的例子。假设我们正在建立一个在线商店。

    包含

    您首先为您的项目选择一个命名空间。在商业世界中,您经常会首先看到带有公司名称的命名空间,以区分专有模块和 CPAN 模块。所以项目的命名空间可能是:

    OurCompany::Shop

    那么可能应用程序的主类或模块被称为相同,所以我们有一个
    OurCompany/Shop.pm

    我们将有一堆东西,我们需要做一个网上商店。如果我们的项目是 MCV,就会有 Controller 和模型之类的东西。所以我们可能有这些东西:
    OurCompany::Shop::Controller::ProductSearch
    OurCompany::Shop::Controller::Cart
    OurCompany::Shop::Controller::Checkout
    OurCompany::Shop::Model::Database

    所有这些都直接映射到模块。
    OurCompany/Shop/Controller/ProductSearch.pm
    OurCompany/Shop/Controller/Cart.pm
    OurCompany/Shop/Controller/Checkout.pm
    OurCompany/Shop/Model/Database.pm

    但是没有 OurCompany::Controller作为基类。该名称只是将事物分类的 namespace 。

    然后有一些东西就在那里,被OurCompany::Shop使用,比如Session引擎。
    OurCompany::Shop::Session

    除非它们非常具体,否则这些在项目之后的第一级。

    当然, session 系统背后有某种引擎。假设我们很喜欢并在我们的 session 中使用 Redis。如果我们自己实现通信(我们不会这样做,因为 CPAN 已经这样做了),我们会坚持这个实现
    OurCompany::Shop::Session::Engine::Redis

    唯一使用这个模块的是OurCompany::Shop::Session。主应用程序甚至不知道使用什么引擎。也许您的开发机器上没有 Redis,所以您使用的是纯文件。
    OurCompany::Shop::Session::Engine::File

    它们都在那里,它们属于::Session,但它们不会被系统的任何其他部分使用,所以我们将它们归档到它们所属的地方。

    继承

    我们还将有 Products1。基本产品类别可能是这个。
    OurCompany::Shop::Product

    并且有一个文件。
    OurCompany/Shop/Product.pm

    只是这个基础产品永远不会被商店直接使用,除了检查某些东西必须在其继承树中具有::Product (这是一个 isa 检查)。所以这与直接使用的::Session 不同。

    当然,我们卖的东西不同,它们有不同的属性。它们都有价格,但鞋子有尺寸,硬盘有容量。所以我们创建子类。
    OurCompany::Shop::Product::Shoe
    OurCompany::Shop::Product::HardDrive

    那些有自己的文件。
    OurCompany/Shop/Product/Shoe.pm
    OurCompany/Shop/Product/HardDrive.pm

    我们还可以区分机械硬盘驱动器和 SSD,因此我们创建了::SSD 子类。
    OurCompany::Shop::Product::HardDrive::SSD

    OurCompany/Shop/Product/HardDrive/SSD.pm

    所以基本上,如果它们属于彼此,它们就会放在同一个命名空间中。这是我们的库的 TreeView 。
    .
    └── OurCompany
    ├── Shop
    │   ├── Controller
    │   │   ├── Cart.pm
    │   │   ├── Checkout.pm
    │   │   └── ProductSearch.pm
    │   ├── Model
    │   │   └── Database.pm
    │   ├── Product
    │   │   ├── HardDrive
    │   │   │   └── SSD.pm
    │   │   ├── HardDrive.pm
    │   │   └── Shoe.pm
    | ├── Product.pm
    │   └── Session.pm
    │   │   └── Engine.pm
    │   │   ├── File.pm
    │   │   └── Redis.pm
    └── Shop.pm

    总结一下:
  • 对于您的主模块,文件名是项目包名的最后一部分。其他一切都在那里。
  • 属于一起的东西被分组在一个命名空间下。
  • 从某事物继承的东西位于该事物的命名空间下。
  • 仅被一个特定事物使用的东西属于该事物。

  • 永远不要将诸如 MyProject::AB 之类的东西附加在一起以表明它属于 MyProject::A。始终使用 namespace 分隔符来组织您的 namespace 。考虑一下,这看起来完全是错误的:
    OurCompany::ShopProductShoe

    1) 可能我们还有一个后台应用程序,它也使用相同的产品类别。在这种情况下,我们可能将它们作为 OurCompany::Product,它们被两个不同的项目使用,OurCompany::Shop 和 OurCompany::BackOffice。

    关于Perl 模块层次结构和组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41503829/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com