romaricdrigon / orchestra-bundle
基于Symfony2构建的裸对象框架
Requires
- php: ~5.4
- doctrine/doctrine-bundle: ~1.2
- doctrine/orm: ~2.2,>=2.2.3
- knplabs/knp-menu-bundle: ~2.0
- symfony/assetic-bundle: ~2.3
- symfony/class-loader: ~2.4
- symfony/expression-language: ~2.4
- symfony/filesystem: ~2.4
- symfony/form: ~2.4
- symfony/framework-bundle: ~2.4
- symfony/security-bundle: ~2.4
- twig/extensions: ~1.0.
Requires (Dev)
- phake/phake: ~1.0
- phpunit/phpunit: ~4.2
This package is auto-updated.
Last update: 2024-09-08 22:03:22 UTC
README
Orchestra是一个基于Symfony2的裸对象实现,可作为Symfony2包使用
为什么选择Orchestra?
裸对象是一种强大的模式,最早由Richard Pawson提出。
它指出,如果业务对象被正确建模,则足以创建一个应用程序,技术代码足够通用,可以自动生成。
Orchestra旨在成为一个这样的管理生成器:一个库,帮助您正确建模域,并为您完成所有“无聊的代码”。
也许您还想进一步个性化它,那就没问题了,Orchestra不是限制您,而是帮助您快速创建一个启动应用程序,它可以作为原型、概念验证或与业务专家讨论……请注意,Orchestra应用程序旨在生产就绪,安全使用,并具有良好的性能。所有操作都是通过反射(最终缓存)完成的,这里没有直接的代码生成。
路线图 / 版本
路线图
- 0.8(当前):功能齐全但仍然是 beta 版本。使用是可以的,但扩展可能会改变
- 0.9:生产就绪。需要几个代码优化
- 1.0:第一个稳定版本。在2.0版本之前必须进行一些重构,但不能在2.0版本之后进行。
安装
使用composer安装包: composer require romaricdrigon/orchestra-bundle
在app/AppKernel.php
中注册包和使用的供应商
class AppKernel extends Kernel { public function registerBundles() { $bundles = array( // ... new RomaricDrigon\OrchestraBundle\RomaricDrigonOrchestraBundle(), new Knp\Bundle\MenuBundle\KnpMenuBundle(), );
导入我们的路由(XML和我们的自定义类型)
# app/config/routing.yml orchestra_routing: resource: '@RomaricDrigonOrchestraBundle/Resources/config/routing.xml' prefix: /admin orchestra_generated: prefix: /admin resource: . type: orchestra
入门
使用Orchestra管理生成器,您只需关注两个对象:实体
和存储库
。所有这些对象都必须放在有效的Symfony2包中。
TL;DR:您可以在Orchestra-example中找到一个工作示例
实体
实体
是您应用程序的基本域对象。尽管我们稍后会看到它们可以被持久化,但它们可能与Doctrine实体不同。
基本实体
根据约定,将这些放在您包的Entity
文件夹中。
它们必须实现RomaricDrigon\OrchestraBundle\Domain\Entity\EntityInterface
:Orchestra必须能够为每个实体实例获取一个唯一的ID。
use RomaricDrigon\OrchestraBundle\Domain\Entity\EntityInterface; class SomeEntity implements EntityInterface { public function getId() { return ...
裸对象遵循DDD思维模式。我们尽量避免有贫血域模型。一些指导方针和建议
- 实体属性是私有或受保护的,不是公共的,遵守封装原则
- 实体必须为将要在视图中公开的属性提供公共getter,例如
- 它们公开与对象上的操作相对应的方法,导致其内部状态发生变化,但没有公共setter
- 您可能想添加私有setter,以实现自我封装,这取决于您
在列表中显示实体
如果您想使实体在默认列表页面上显示,则必须实现ListableEntityInterface
use RomaricDrigon\OrchestraBundle\Domain\Entity\EntityInterface; use RomaricDrigon\OrchestraBundle\Domain\Entity\ListableEntityInterface; class SomeEntity implements EntityInterface, ListableEntityInterface { public function viewListing() { return ['some data', 'some more', '...']; }
viewListing
返回的数据将在每个列表行中以相同的顺序显示。它可以是数组或一个 QueryInterface
对象。您将在下一节中了解更多关于查询的信息。
命令和查询
实体应用了 命令-查询分离原则。
查询
任何实体方法都可以返回一个数组(更简单,更受欢迎)或实现 QueryInterface
的对象。Orchestra 将根据它生成一个动作,一个显示返回对象数据的网页。
注意:QueryInterface
扩展了 \Traversable
。这意味着查询必须扩展 \Iterator
或 IteratorAggregate
。请注意,自 PHP 5.4.30 以来,接口实现顺序是有效的,您必须在实现 QueryInterface
之前实现这两个接口之一。
命令
任何实体方法都可以接受一个实现 CommandInterface
的对象。此类方法将被转换成一个包含表单的网页。
一个 Command
通常是一个简单的数据容器,具有公共属性。这些公共属性将被映射到 Orchestra 生成的表单。
注意:可以通过调用其构造函数(在这种情况下不应传递任何参数)或指定实体上的工厂方法来调用命令。在这种情况下,在您的命令类上使用 CommandFactory
注解。
持久化
通常,它们会被持久化。Orchestra 通过其 Symfony2 代理支持 Doctrine ORM。您将必须使用 Doctrine 注解、YAML(建议)或 XML 来进行映射。有关这部分内容,请参阅 Symfony 文档。
事件
事件是实现 EventInterface
的对象。实体可以发出事件。
发出事件的方必须返回一个事件或 null
(在这种情况下不会发生任何事情)。该事件将被传递到相应的存储库 receive
方法(它必须实现 ReceiveEventInterface
)。然后您可以决定做什么。
存储库
这些不是 Doctrine 存储库!我们坚持原始的存储库模式(Fowler,2002),“用于访问域对象的集合-like 接口”。
它们的名称将是 Entity
的名称后跟 Repository
,但您可以自由地这样做。
每个 Repository
都必须有一个相应的 Entity
,具有相同的 slug(不带后缀的小写名称):对于 FooBar
实体,您必须有一个 FoobarRepository
、FooBarRepository
或 FooBar
(尽管这最后一个更难以阅读)。
基本存储库
我们建议您根据约定,在您的包中将其放置在 Repository
文件夹中。
它们必须实现 RomaricDrigon\OrchestraBundle\Domain\Repository\RepositoryInterface
use RomaricDrigon\OrchestraBundle\Domain\Repository\RepositoryInterface; use RomaricDrigon\OrchestraBundle\Annotation\Name; class MyRepository implements RepositoryInterface {
它们必须作为服务声明,带有 orchestra.repository
标签,并且 指示相应的实体类
<!-- your bundle services.xml --> <?xml version="1.0" ?> <container xmlns="https://symfony.ac.cn/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://symfony.ac.cn/schema/dic/services https://symfony.ac.cn/schema/dic/services/services-1.0.xsd"> <services> <service id="romaric_drigon_example.my_repository" class="My\Repository\Class\Path"> <tag name="orchestra.repository" entityClass="Acme\Demo\Entity\SomeEntity" /> </service> ...
获取 Doctrine 存储库
Orchestra 存储库是 Symfony2 服务,因此您可以注入其依赖项。
Orchestra 可以自动解析并注入到您的服务中相应的 Doctrine 存储库。它们还将收到 Orchestra ObjectManager
的副本。为了从中受益,只需实现 RomaricDrigon\OrchestraBundle\Domain\Doctrine\DoctrineAwareInterface
。
为了简化,您可以扩展提供的 BaseRepository
类。然后您将能够访问相应的 Doctrine 存储库,我们提供了一个通用的 listing
方法。
use RomaricDrigon\OrchestraBundle\Domain\Doctrine\BaseRepository; use RomaricDrigon\OrchestraBundle\Annotation\Name; class MyRepository implements BaseRepository { public function someMethod() { $objectManager = $this->objectManager; $doctrineRepository = $this->doctrineRepository; ...
自定义显示名称
存储库显示的名称可以自动从类名称生成,或者可以使用 @Name
注解进行个性化。
use RomaricDrigon\OrchestraBundle\Domain\Repository\RepositoryInterface; use RomaricDrigon\OrchestraBundle\Annotation as Orchestra; /** * @Orchestra\Name("CustomName") */ class MyRepository implements RepositoryInterface {
隐藏方法
您可以通过添加 @Hidden
注解来从菜单中添加实体或存储库方法。
use RomaricDrigon\OrchestraBundle\Domain\Repository\RepositoryInterface; use RomaricDrigon\OrchestraBundle\Annotation as Orchestra; class MyRepository implements RepositoryInterface { /** * @Orchestra\Hidden */ public function hiddenMethod() {
注意这仅适用于接口的子类,不适用于接口本身。
安全性
Orchestra完全集成了Symfony2安全组件,不会试图干扰它。
为了方便,您可以将@Security
注解添加到Entity或Repository方法中,以限制对相应页面的访问。这个注解的内容是有效的Symfony2表达式,与SensioFrameworkExtraBundle中使用的表达式相同。
此外,您还可以访问Orchestra对象,例如repository
、entity
,以及可能的当前EntityInterface
对象(但不能直接访问Request
对象)。
配置
您可以通过在您的config.yml
文件中添加以下设置来配置Bundle。
# app/config/config.yml romaric_drigon_orchestra: app_title: Orchestra # default. Will be used as title (prefix) for pages
杂项
提供的模板不支持IE8。Twitter Bootstrap缺少其JS polyfills,我们正在使用jQuery 2.0。
感谢
Twitter Bootstrap集成是使用来自Braincrafted Bootstrap bundle的模板实现的。
安全注解的支持方式与SensioFrameworkExtraBundle非常相似。