最大实体原则

Since PHP 5.4.0, PHP supports a pretty way to reuse code called “Traits” – a set of methods that you can include within another class in order not to repeat yourself. You can read more about traits in previously published SitePoint posts: here, here and here.

从PHP 5.4.0开始,PHP支持一种漂亮的方法来重用代码,即“特质”(Traits)-可以在另一个类中包含的一组方法,以免重复。 您可以在以前发布的SitePoint帖子中( 此处 , 此处和此处)阅读有关特征的更多信息。

Today, I am going to show you how they can be used with Doctrine ORM in a Symfony Environment.

今天,我将向您展示如何在Symfony环境中将它们与Doctrine ORM一起使用。

特质基础 (Trait Basics)

<?php
trait ExampleTrait {
public function sayHello() {
echo "Hello";
}
}
class A {
use ExampleTrait;
}
class B {
use ExampleTrait;
}
$one = new A();
$one->sayHello();    /* return `Hello` */
$two = new B();
$two->sayHello();    /* return `Hello`, too */

As we can see, a basic method sayHello() is declared inside a Trait that is implemented by both A and B classes with a use statement. Easy, right? This example is really short but it should give you the basic knowledge to work with Traits.

如我们所见,基本方法sayHello()在Trait中声明,该Trait由ABuse语句实现。 容易吧? 这个例子确实很简短,但是它应该为您提供使用Traits的基本知识。

If you are interested in Traits, I recommend you read the official documentation and previously published SitePoint posts here, here and here, to fully grasp the concept. Allow me to warn you about the fact that many people tend not to see a difference between Traits and Interfaces. Here is a pragmatic explanation:

如果您对特质感兴趣,我建议您在此处 , 此处和此处阅读官方文档和以前发布的SitePoint帖子,以全面了解该概念。 请允许我警告您以下事实:许多人往往不会看到“特性”和“ 接口”之间的差异。 这是一个务实的解释:

An interface is a contract that says “this object is able to do this thing”, whereas a Trait is giving the object the ability to do the thing.

界面是一个契约,上面写着“该对象能够执行此操作”,而“特性”则赋予该对象执行该操作的能力。

For a more in-depth explanation, feel free to take a look at this insightful post by Philip Brown, which the previous quote comes from.

要获得更深入的解释,请随时阅读Philip Brown的这篇富有洞察力的文章 ,该文章先前的引用来自此。

When it comes to organizing one’s database architecture, it is not uncommon to face code duplication. As an example, suppose we have to develop the usual blog application. At some point, it is likely that we are going to create a basic Article entity and probably a Comment entity as well.

在组织数据库架构时,面对代码重复并不少见。 例如,假设我们必须开发通常的博客应用程序。 在某个时候,我们可能会创建一个基本的Article实体,也可能会创建一个Comment实体。

Both entities would benefit from having created_at and updated_at fields (so we can sort results on those columns later). But before digging into traits, let’s see how we could build those entities in Doctrine without them.

这两个实体都将从具有created_atupdated_at字段中受益(因此我们以后可以在这些列上对结果进行排序)。 但是在深入研究特征之前,让我们先看看如何在没有这些特征的情况下在教义中建立这些实体。

步骤1:建立实体 (Step 1: create the entities)

文章实体 (Article entity)

<?php
namespace Blog\AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table(name="article")
* @ORM\Entity(repositoryClass="Blog\AppBundle\Entity\ArticleRepository")
*/
class Article
{
/**
* @ORM\Column(name="idArticle" type="integer")
* @ORM\Id()
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/* Other properties you need in your entity: $title, $content, $author...  */
/** @ORM\Column(name="created_at" type="datetime") */
private $createdAt;
/** @ORM\Column(name="updated_at" type="datetime") */
private $updatedAt;
/* Getters & Setters */
}

评论实体 (Comment entity)

<?php
namespace Blog\AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table(name="comment")
* @ORM\Entity(repositoryClass="Blog\AppBundle\Entity\CommentRepository")
*/
class Comment
{
/**
* @ORM\Column(name="idComment" type="integer")
* @ORM\Id()
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/* Other properties you need in your entity */
/** @ORM\Column(name="created_at" type="datetime") */
private $createdAt;
/** @ORM\Column(name="updated_at" type="datetime") */
private $updatedAt;
/* Getters & Setters */
}

The same properties $createdAt and $updatedAt are included in both classes. This is far from DRY. Would Traits be able to help us clean this code up?

两个类都包含相同的属性$createdAt $updatedAt$updatedAt 。 这远不是DRY。 特性可以帮助我们清理此代码吗?

步骤2:建立特质 (Step 2: create the Trait)

<?php
// src/Blog/AppBundle/Entity/Traits/TimestampableTrait.php
namespace Blog\AppBundle\Entity\Traits;
use Doctrine\ORM\Mapping as ORM;
trait TimestampableTrait
{
/**
* @var datetime $createdAt
*
* @ORM\Column(name="created_at", type="datetime")
*/
private $createdAt;
/**
* @var datetime $updatedAt
*
* @ORM\Column(name="updated_at", type="datetime")
*/
private $updatedAt;
/**
* Get createdAt
*
* @return datetime
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* Set createdAt
*
* @param datetime $createdAt
*/
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
return $this;
}
/**
* Get updatedAt
*
* @return datetime
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}
/**
* Set updatedAt
*
* @param datetime $updatedAt
*/
public function setUpdatedAt($updatedAt)
{
$this->updatedAt = $updatedAt;
return $this;
}
}

Here is a pretty trait file into which we have moved the initial duplicated code. Both $createdAt and $updatedAt as well as all the associated methods are now separated from the entities. As a result, it will be much easier to use them somewhere else. Remember the introduction section with the keyword use.

这是一个漂亮的特征文件,我们将初始重复的代码移入其中。 无论$createdAt$updatedAt以及所有相关的方法现在从实体分离。 结果,在其他地方使用它们会容易得多。 记住带有关键字use的介绍部分。

步骤3:重构实体 (Step 3: refactor the entities)

文章实体 (Article entity)

<?php
// src/Blog/AppBundle/Entity/Article.php
namespace Blog\AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Blog\AppBundle\Entity\Traits\TimestampableTrait;
class Article
{
use TimestampableTrait;
/**
* @ORM\Column(name="idArticle" type="integer")
* @ORM\Id()
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/* Other properties you need in your entity */
/* Getters & Setters */
}

评论实体 (Comment entity)

<?php
// src/Blog/AppBundle/Entity/Comment.php
namespace Blog\AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Blog\AppBundle\Entity\Traits\TimestampableTrait;
/**
* @ORM\Table(name="comment")
* @ORM\Entity(repositoryClass="Blog\AppBundle\Entity\CommentRepository")
*/
class Comment
{
use TimestampableTrait;
/**
* @ORM\Column(name="idComment" type="integer")
* @ORM\Id()
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/* Other properties you need in your entity */
/* Getters & Setters */
}

Done! Let’s play with the command line. First, let’s create the entities in our database:

做完了! 让我们玩命令行。 首先,让我们在数据库中创建实体:

php app/console doctrine:schema:create

This command would yield:

该命令将产生:

`Article Entity`
| idArticle | *All our other fields...* | created_at | updated_at |
|-----------|---------------------------|------------|------------|
`Comment Entity`
| idComment | *All our other fields...* | created_at | updated_at |
|-----------|---------------------------|------------|------------|

Now, if you want to create new objects from these classes, you would find that they both have the common methods available:

现在,如果您想从这些类中创建新对象,则会发现它们都有可用的通用方法:

<?php
$article = new Article();
$article->setUpdatedAt(new \Datetime('now'));
$comment = new Comment();
$comment->setUpdatedAt(new \Datetime('now'));
?>

Obviously, we are now ready to persist the data.

显然,我们现在可以保留数据了。

更进一步 (Going further)

Currently, in the Symfony sphere, many bundles and extensions tend to stick to this way of doing things. The DoctrineBehaviors library from KNPLabs provides a great collection of Traits for entities and repositories. In the same state of mind, I recommend you have an in-depth look at the well known DoctrineExtensions bundle and especially everything about the Timestampable behavior extension.

当前,在Symfony领域中,许多捆绑包和扩展都倾向于坚持这种做事方式。 KNPLabs的DoctrineBehaviors库为实体和存储库提供了大量特性集。 出于同样的考虑,我建议您深入了解著名的DoctrineExtensions捆绑包,尤其是有关Timestampable行为扩展的一切。

最后的想法 (Final Thoughts)

Traits are not difficult to absorb. They are an excellent way to produce lighter and more flexible code. Be careful not to abuse them: sometimes, it is better to construct a unique class implementation. I can’t stress enough how crucial it is to take enough time in order to properly design your app. Give them a go if you think they could help you. Create yours, test them and tell us how you used them!

性状不难吸收。 它们是产生更轻便,更灵活的代码的绝佳方法。 注意不要滥用它们:有时,最好构造一个独特的类实现。 我无法强调足够的时间来正确设计您的应用程序是多么关键。 如果您认为他们可以帮助您,请给他们一个机会。 创建您的产品,对其进行测试,并告诉我们您的使用方式!

翻译自: https://www.sitepoint.com/using-traits-doctrine-entities/

最大实体原则

最大实体原则_在原则实体中使用特征相关推荐

  1. 举例说明层次分析的三大原则_公差原则

    首先讲一下零件的几何要素,显而易见我们所见到的各种零件其实都是由各种各样的几何要素组成,比如说点.线.面等,这些几何要素包括零件的轮廓线,平面等实际存在的,也包括像轴线,对称平面这样我们认为假想出来的 ...

  2. 代码设计的基础原则_设计原则:良好设计的基础

    代码设计的基础原则 As designers, it's our goal to pass information in the most pleasing way possible. Startin ...

  3. java依赖倒转原则_设计原则之--依赖倒转原则

    [各位博友晚上好,又到了晚上的这个时间,感谢大家一直对Darren博客的支持,希望这篇文章对你有所帮助: 这几天一直在看设计模式:简单工厂模式,策略模式,单一职责原则,开放 [依赖倒转原则又称依赖倒置 ...

  4. 举例说明层次分析的三大原则_《原则》一书精华解析:作者桥水基金创始人瑞.达利欧...

    <原则> 作者:瑞.达利欧 桥水基金创始人 人生原则 人一生最重要的事情,就是在纷繁复杂的世界中总结出自己的原则,来应对时刻变化的现实. 独立思考,是构建自我原则最重要的起点. 如何总结出 ...

  5. 机器学习如何计算特征的重要性_干货 :机器学习中的特征工程总结

    结构总览 特征工程 传统编程的关注点是代码.在机器学习项目中,关注点变成了特征表示.也就是说,开发者通过添加和改善特征来调整模型."Garbage in, garbage out" ...

  6. java object数组转实体类_详解Java中String JSONObject JSONArray List实体类转换

    JSON使用阿里的fastJson为依赖包 gradle依赖管理如下: compile group: "com.alibaba", name: "fastjson&quo ...

  7. mysql中建立索引的原则_在SQL数据库中设定索引的原则是什么?(注意是设定不是创建)...

    其实索引的好坏还和你的查询语句有关系,就是where后边的列有关.如果两者协调不好的话,同样应用索引也得不到什么好处.下边的文章希望对你有益: 索引的设计 A:尽量避免表扫描检查你的查询语句的wher ...

  8. liskov替换原则_坚实原则:Liskov替代原则

    liskov替换原则 以前,我们深入研究了坚实的原则,包括单一责任和开放/封闭原则. Liskov替代原则(LSP)是子类型关系的一种特殊定义,称为(强)行为子类型, 假设对象S是对象T的子类型,则可 ...

  9. 依赖倒置原则_设计模式原则之依赖倒置原则

    依赖倒置原则 Dependency Inversion Principle 高层次的类不应该依赖于低层次的类. 两者都应该依赖于抽象接口. 抽象接口不应依赖于具体实现. 具体实现应该依赖于抽象接口. ...

最新文章

  1. python setdefault,Python笔记setdefault用法
  2. vim入门教程(实践第一)
  3. PHP_crontab 漏洞,shopex 4.8.5.45144 \core\include_v5\crontab.php 远程shell写入漏洞
  4. 【转】C 编译器优化过程中的 Bug
  5. qtmessagebox对话框里自定义按钮文本_Word里表格都是这么来的 — 生成绘制表格有技巧...
  6. P1459 三值的排序 Sorting a Three-Valued
  7. 前端学习(564):margin计算规则
  8. 《大数据》2015年第2期“前沿”——大数据技术发展的十个前沿方向(上)
  9. easyui中combotree只能选子选项,父级不被选中
  10. 越做越好的adobe acrobat
  11. BZOJ2431:[HAOI2009]逆序对数列(DP,差分)
  12. 《演讲之禅》迷你书免费下载 每小时30000美元的秘诀
  13. 如何轻松破解windows密码(运行即可,免重启)
  14. Mac修改redis密码
  15. 27、一个扒网站软件——teleport ultra(静态页面)
  16. TCP connection succeeded but Erlang distribution failed
  17. spark学习系列——6 Historyserver配置
  18. python2.7实现简单日记本,兼容windows和linux
  19. Ubuntu Qt无法使用搜狗输入法
  20. Reasoning with Sarcasm by Reading In-between

热门文章

  1. VC6风格转XP风格界面的两种方法
  2. linux组权限管理,Linux组管理和权限管理
  3. RFID原理及应用期末复习笔记 | 1.RFID概述【完结✿✿ヽ(°▽°)ノ✿】
  4. 软考高级,考网规还是考项管?
  5. 【状语从句练习题】连词 + 过去分词
  6. pc控制iphone的软件_评论:苹果M1芯片版MacBook和Mac Mini将颠覆整个PC行业?
  7. 全网通报:数模国赛作弊的后果
  8. PyFlink 教程(三):PyFlink DataStream API - state timer
  9. 我最希望成最没成的屏幕情侣....
  10. linux后缀asok是什么意思,Pwn In Kernel(一):基础知识