越来越多地了解Perl,我对如何在当前项目中组织模块表示怀疑。
我有一个主命名空间 - 让我们称之为" MyProject"。
在此项目中,基础数据是每个对象都有一个类的图形。对象与关系相关联。对象和关系都可以具有属性。
项目的一部分我使用模型来验证这些图表。 所以我有一个Model类,它由Class,Relation和Attribute类的对象组成。
类类,关系和属性仅由类Model使用,因此我按如下方式组织模块是有意义的:
但我开始认为只有在我敢于在CPAN中重新部分我的项目时才会对我有意义。我认为人们会相信Class,Relation和Attribute是继承Model而不是组成它。
所以:我应该用这种方式重新组织我的模块:
或者可以通过附加名称来表明Class,Relation和Attribute是Model的一部分吗?
我的问题:当谈到合成时,模块组织和命名的最佳实践目前是什么?
答案 0 :(得分:9)
您的担忧是正确的。通常,包由包含或继承命名。我要编写一个更现实的例子。我们假设我们正在建立一个在线商店。
<强>夹杂物强>
首先为项目选择一个命名空间。在商业世界中,您经常首先看到具有公司名称的命名空间,以区分专有模块和CPAN模块。所以项目的命名空间可以是:
OurCompany::Shop
那么应用程序的主类或模块可能被称为相同,所以我们有一个
OurCompany/Shop.pm
我们将拥有制作网上商店所需的一系列东西。如果我们的项目是MCV,那么有控制器和模型以及类似的东西。所以我们可能有这些东西:
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
作为基类。该名称只是用于对事物进行排序的命名空间。
然后有些东西就在那里,并被OurCompany :: Shop使用,就像会话引擎一样。
OurCompany::Shop::Session
那些在项目结束后进入第一级,除非它们非常具体。
当然,会话系统背后有某种引擎。让我们说我们很喜欢并使用Redis参加我们的会议。如果我们自己实施通信(我们不会因为CPAN已经这样做了),我们会坚持实施
OurCompany::Shop::Session::Engine::Redis
唯一使用此模块的是引擎盖下的OurCompany :: Shop :: Session。主要应用甚至不知道使用什么引擎。也许你的开发机器上没有Redis,所以你使用普通文件。
OurCompany::Shop::Session::Engine::File
它们都在那里,它们属于:: Session,但它们不会被系统的任何其他部分使用,所以我们将它们归档到它们所属的位置。
<强>继承强>
我们还将有产品 1 。基础产品类可以是这个。
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
我们也可能区分机械HardDrive和SSD,因此我们制作了:: SSD子类。
OurCompany::Shop::Product::HardDrive::SSD
OurCompany/Shop/Product/HardDrive/SSD.pm
所以基本上,如果它们彼此属于同一个命名空间,那么它们就会放在同一个命这是我们的lib的树视图。
.
└── 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。始终使用命名空间分隔符来组织命名空间。考虑一下这看起来很简单:
OurCompany::ShopProductShoe
1)可能我们还有一个后台应用程序也使用相同的产品类。在这种情况下,我们可能将它们作为OurCompany :: Product,它们被两个不同的项目使用,OurCompany :: Shop和OurCompany :: BackOffice。