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.com.cn/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://symfony.com.cn/schema/dic/services https://symfony.com.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非常相似。