Vla*_*ban 9 php domain-driven-design symfony
我正在考虑一个广告网站,用户可以登录,发布新的列表和搜索现有的列表.我将完全遵循DDD原则,这是我的第一个项目.我之前从未在Symfony做过任何DDD.
以下是我对此的看法.你能否告诉我这是否正确,并建议更好的方法?
我可以看到两个域:用户和列表
搜索/显示/发布功能将存在于清单域中.在用户域中登录/注销.
SF3目录的示例结构是
app/
ListingBundle/
src/
Listing.php
SearchService.php
ListingRepositoryInterface.php
Controller/
public/
ListingController.php
protected/
ListingController.php
Resource/
view/
public/
detail.twig.html
protected/
edit.twig.html
UserBundle/
src/
User.php
AuthService.php
UserRepositoryInterface.php
Controller/
public/
UserController.php
protected/
UserController.php
Resource/
view/
public/
login.twig.html
protected/
dashboard.twig.html
PersistenceBundle
src/
UserRepository.php
ListingRepository.php
Run Code Online (Sandbox Code Playgroud)
我的主要问题是:
Tho*_*och 18
你在这里做了一个错误的假设,即"我将使用Symfony框架以DDD-ish方式实现我的应用程序".
不要这样做,框架只是一个实现细节,并为您的应用程序提供一种(更多)交付方法.我的意思是在六角形建筑的背景下应用.
如果从我们的某个上下文中查看以下示例,您会看到我们的ApiClient上下文包含三个层(顶级目录结构).应用程序(包含用例服务),域(包含模型和行为)和基础结构(包含基础架构问题,如持久性和交付).我专注于Symfony集成和持久性,因为这是OP的原始问题:
src/ApiClient
??? Application
? ??? ApiClient
? ? ??? CreateApiClient
? ? ??? DisableApiClient
? ? ??? EnableApiClient
? ? ??? GetApiClient
? ? ??? ListApiClient
? ? ??? RemoveApiClient
? ? ??? ChangeApiClientDetails
? ??? ClientIpAddress
? ? ??? BlackListClientIpAddress
? ? ??? CreateClientIpAddress
? ? ??? ListByApiClientId
? ? ??? ListClientIpAddresses
? ? ??? WhiteListClientIpAddress
? ??? InternalContactPerson
? ??? CreateInternalContactPerson
? ??? GetInternalContactPerson
? ??? GetByApiClientId
? ??? ListContacts
? ??? ReassignApiClient
? ??? Remove
??? Domain
? ??? Model
? ??? ApiClient
? ??? ClientIpAddress
? ??? InternalContactPerson
??? Infrastructure
??? Delivery
? ??? Http
? ??? SymfonyBundle
? ??? Controller
? ? ??? ApiClientController.php
? ? ??? InternalContactController.php
? ? ??? IpAddressController.php
? ??? DependencyInjection
? ? ??? Compiler
? ? ? ??? EntityManagerPass.php
? ? ? ??? RouterPass.php
? ? ??? Configuration.php
? ? ??? MetadataLoader
? ? ? ??? Adapter
? ? ? ? ??? HateoasSerializerAdapter.php
? ? ? ? ??? JMSSerializerBuilderAdapter.php
? ? ? ??? Exception
? ? ? ? ??? AmbiguousNamespacePathException.php
? ? ? ? ??? EmptyMetadataDirectoryException.php
? ? ? ? ??? FileException.php
? ? ? ? ??? MalformedNamespaceException.php
? ? ? ? ??? MetadataLoadException.php
? ? ? ??? FileMetadataLoader.php
? ? ? ??? MetadataAware.php
? ? ? ??? MetadataLoaderInterface.php
? ? ??? MFBApiClientExtension.php
? ??? DTO
? ? ??? ApiClient
? ? ??? ChangeInternalContact
? ? ??? ChangeInternalContactRequest.php
? ? ??? ChangeInternalContactResponse.php
? ??? MFBApiClientBundle.php
? ??? Resources
? ? ??? config
? ? ? ??? domain_services.yml
? ? ? ??? metadata_loader.yml
? ? ? ??? routing.yml
? ? ? ??? services.yml
? ? ??? hateoas
? ? ? ??? ApiClient
? ? ? ??? Application
? ? ? ? ??? ApiClient
? ? ? ? ? ??? CreateApiClient
? ? ? ? ? ? ??? CreateApiClientResponse.yml
? ? ? ? ? ??? ListApiClient
? ? ? ? ? ??? ListApiClientResponse.yml
? ? ? ? ??? ClientIpAddress
? ? ? ? ? ??? CreateClientIpAddress
? ? ? ? ? ? ??? CreateClientIpAddressResponse.yml
? ? ? ? ? ??? ListByApiClientId
? ? ? ? ? ? ??? ListByApiClientIdResponse.yml
? ? ? ? ? ??? ListClientIpAddresses
? ? ? ? ? ??? ListClientIpAddressesResponse.yml
? ? ? ? ??? InternalContactPerson
? ? ? ? ??? Create
? ? ? ? ? ??? CreateResponse.yml
? ? ? ? ??? List
? ? ? ? ??? ListResponse.yml
? ? ? ??? Domain
? ? ? ??? ApiClient
? ? ? ? ??? ApiClient.yml
? ? ? ??? ClientIpAddress
? ? ? ? ??? ClientIpAddress.yml
? ? ? ??? InternalContactPerson
? ? ? ??? InternalContactPerson.yml
? ? ??? serializer
? ? ??? ApiClient
? ? ? ??? Application
? ? ? ? ??? ApiClient
? ? ? ? ? ??? CreateApiClient
? ? ? ? ? ? ??? ContactPersonRequest.yml
? ? ? ? ? ? ??? CreateApiClientRequest.yml
? ? ? ? ? ? ??? CreateApiClientResponse.yml
? ? ? ? ? ??? GetApiClient
? ? ? ? ? ??? GetApiClientResponse.yml
? ? ? ? ??? ClientIpAddress
? ? ? ? ? ??? CreateClientIpAddress
? ? ? ? ? ??? CreateClientIpAddressRequest.yml
? ? ? ? ? ??? CreateClientIpAddressResponse.yml
? ? ? ? ??? InternalContactPerson
? ? ? ? ??? Create
? ? ? ? ? ??? CreateRequest.yml
? ? ? ? ? ??? CreateResponse.yml
? ? ? ? ??? Get
? ? ? ? ? ??? GetResponse.yml
? ? ? ? ??? List
? ? ? ? ? ??? ListResponse.yml
? ? ? ? ??? ReassignApiClient
? ? ? ? ??? ReassignApiClientRequest.yml
? ? ? ??? Domain
? ? ? ??? ApiClient
? ? ? ? ??? ApiClient.yml
? ? ? ? ??? ContactPerson.yml
? ? ? ??? ClientIpAddress
? ? ? ? ??? ClientIpAddress.yml
? ? ? ??? InternalContactPerson
? ? ? ??? InternalContactPerson.yml
? ? ??? Bundle
? ? ??? DTO
? ? ??? ApiClient
? ? ??? ChangeInternalContact
? ? ??? ChangeInternalContactRequest.yml
? ??? Service
? ??? Hateoas
? ??? UrlGenerator.php
??? Persistence
??? Doctrine
? ??? ApiClient
? ? ??? ApiClientRepository.php
? ? ??? mapping
? ? ??? ApiClientId.orm.yml
? ? ??? ApiClient.orm.yml
? ? ??? CompanyName.orm.yml
? ? ??? ContactEmail.orm.yml
? ? ??? ContactList.orm.yml
? ? ??? ContactName.orm.yml
? ? ??? ContactPerson.orm.yml
? ? ??? ContactPhone.orm.yml
? ? ??? ContractReference.orm.yml
? ??? ClientIpAddress
? ? ??? ClientIpAddressRepository.php
? ? ??? mapping
? ? ??? ClientIpAddressId.orm.yml
? ? ??? ClientIpAddress.orm.yml
? ? ??? IpAddress.orm.yml
? ??? InternalContactPerson
? ??? InternalContactPersonRepository.php
? ??? mapping
? ??? InternalContactPersonId.orm.yml
? ??? InternalContactPerson.orm.yml
??? InMemory
??? ApiClient
? ??? ApiClientRepository.php
??? ClientIpAddress
? ??? ClientIpAddressRepository.php
??? InternalContactPerson
??? InternalContactPersonRepository.php
94 directories, 145 files
Run Code Online (Sandbox Code Playgroud)
相当多的文件!
您可以看到我正在使用捆绑软件作为应用程序的端口(命名虽然有点,但它不应该是Http交付,因为严格意义上的六边形体系结构它是一个应用程序到应用程序端口) .我强烈建议你阅读PHP书中的DDD,其中所有这些概念都是用PHP中的表达实例来解释的(假设你已经阅读了蓝皮书和红皮书,尽管这本书作为一个单独的工作,同时仍然提供参考).
使用 Symfony 构建的 DDD 应用程序的文件夹结构
我支持 tPl0ch 的回答,但我想提出一个文件夹结构的轻微变体,这在我参与的 Symfony 的几个项目中很有用。 对于您的特定域,文件夹结构可能如下所示:
app
Listing
Domain
Model
Listing.php
Repository
ListingRepository.php
Service
SearchService.php
Infrastructure
Repository
DoctrineListingRepository.php // or some other implementation
Resources
// symfony & doctrine config etc.
Service
ElasticSearchService.php // or some other implementation
ListingInfrastructureBundle.php
Presentation
Controller
ViewListingController.php // assuming this is the "public" part
EditListingController.php // assuming this is the "protected" part
Forms
ListingForm.php
Resources
// symfony config & views etc.
ListingPresentationBundle.php
User
// ...
Infrastructure
Service
AuthService.php
// ...
Run Code Online (Sandbox Code Playgroud)
使用此文件夹结构,您可以将洋葱架构的不同层分开。不同的文件夹清楚地传达了层之间的边界和允许的依赖关系。我写了一篇关于使用 Symfony 的 DDD 文件夹结构的博客文章,其中详细描述了该方法。
其他资源:
除此之外,我还建议您查看以下资源:
我从理解 Sylius 代码库中学到了很多东西——这是一个真实世界的项目,而且相当庞大。他们进行了各种测试,并为交付高质量的代码付出了很多努力。
| 归档时间: |
|
| 查看次数: |
7335 次 |
| 最近记录: |