特质,我如何使用它们来改进我的代码 (PHP)

特质,我如何使用它们来改进我的代码 (PHP)

用这 5 个技巧变得很棒

Photo by 朱迪库克 on 不飞溅

嗨,我是尼科,

我是伦敦(英国)一家票务经纪公司的高级工程师。

您正在从办公室阅读!

这是一个每天(几乎)发布的例程,我在其中记录我在办公室的日常生活中所从事的技术。

这篇文章是给谁看的?

在这篇文章中,您将了解 Traits、面向对象编程和继承。

如果你还没有到那里,不用担心,你可以从这个开始:

[

面向对象编程的完整指南

学习面向对象编程是 Web 开发人员可以学习的最有价值的技能之一。例如…

anastasionico.uk

](https://anastasionico.uk/blog/the-complete-guide-to-object-oriented-programming)

如果您想挑战自己的技能,请点击此处

[

领域驱动设计最快

让我对你做一点猜测,你来到这个网站并正在阅读这句话的原因是……

anastasionico.uk

](https://anastasionico.uk/blog/domain-driven-design-quickest-the-basics)

问题

如果您已经编写过面向对象的编程代码,那么您肯定会遇到诸如继承和接口之类的世界。

PHP 中的类不支持多重继承 , 接口帮助你处理这个问题。

给定一个类只能扩展一个父类,您被迫使用和实现尽可能多的接口来创建复杂的系统。

但,

如果您需要跨继承层次共享实现怎么办?

这就是特征出现的原因,现在我将向您解释如何使用它们。

考虑像抽象类这样的特征,它具有非常相似的结构,并且不能自行实例化。但是你可以将它合并到一个具体的类中。

特征定义的任何方法在使用它的类中自动可用。

实际上,

您应该将特征视为 INCLUDE,但对于类。

特质解决了什么问题?

作为一个高效的人,我喜欢记录我每天可以写多少字。

让我们想象一下,我开发了一个小应用程序,它可以为我计算它们并告诉我我是否做得很好,或者我是否必须更加努力。

假设我目前正在写这篇关于编程的文章和一本关于兽人、巫师和诸如此类的奇幻书。

我的项目有 2 节课:一门用于书本:

 类图书写作  
 { ... 公共函数 addWordsCount(int $todaysWords)  
 {  
 返回 $this->wordsCount += $todaysWords; }  
      
 公共函数 getHeroName(){...} ... }

和一个博客。

 类文章写作  
 { ... 公共函数 addWordsCount(int $todaysWords)  
 {  
 返回 $this->wordsCount += $todaysWords; }  
      
 公共函数 PostCategory(){...} ... }

你可以看到我的项目的代码库有一个很大的问题,

两种方法,看起来相同,做同样的事情,在两个类中,尽管相似,但彼此无关。

“重复可能是软件中万恶之源。”
—— Robert C. Martin,干净的代码集合

为什么是特质?

好吧,Traits 为这个问题提供了一个快速可靠(注意我没有说完美或优雅)的解决方案。

特质的目的是 封装该特定行为并使其可用于多个类 当他们需要的时候。

 特质 CountWordsUtilityTrait  
 {  
 公共函数 addWordsCount(int $todaysWords)  
 {  
 返回 $this->wordsCount += $todaysWords;  
 }  
 }

此方法现在可以使用了。

 类图书写作  
 {  
 使用 CountWordsUtilityTrait;  
 } 类文章写作  
 {  
 使用 CountWordsUtilityTrait;  
 }

两个类都可以使用 addWordsCount() 方法和以前一样,但现在它只在一个地方。

如果我们需要在 1 个月后更新代码,这是一个巨大的优势。

提示与技巧

Trait Tips & Tricks

Photo by 艾哈迈德·谢拉兹 on 不飞溅

使用多个特征

正如我们所说,我们拥有特征的原因之一是解决语言的单继承约束。

这意味着如果我们需要它,我们可以使用更多的特性。

 PaginatorTrait  
 {  
 公共函数 getPageNumber(): int  
 {  
 返回 $this->pageNumber;  
 }  
 } 类图书写作  
 {  
 使用 CountWordsUtilityTrait、PaginatorTrait;  
 }

现在 写书 类可以访问 addWordsCount() 方法和 获取页码() 方法。

特征和接口

没人说 当一个类也实现了一个接口时,我们不能使用特征。

PHP 的限制只是针对我们要继承的类。

这意味着您实际上可以这样做:

 类 ArticleWriting 实现 Commentable  
 {  
 使用 CountWordsUtilityTrait;  
 }

代替关键字

我已经在上面展示了我们可以在一个类中组合 2 个或更多特征,这很好,远离主域的功能更多。

当这些特征具有以相同方式调用的方法时,可能会出现一个问题。

我们的类或 PHP 引擎如何理解在每种情况下使用哪种方法?

对我来说,这尖叫着可能的错误。

出色地,

并不真地。

作为一名 PHP 开发人员,您可能已经遇到过该函数 实例 , 该语言还提供了另一个关键字,称为 代替 .

这个关键字让我们指定类应该如何在 trait 的方法之间进行选择。

下面是它的工作原理:

 PaginatorTrait  
 {  
 公共函数 getPageNumber(): int  
 {  
 返回 $this->pageNumber;  
 }  
 } 特征 PublishedDataTrait  
 {  
 公共函数 getPageNumber(): int  
 {  
 返回 $this->publisher->getNumberOfPage();  
 }  
 } 类图书写作  
 {  
 使用 PaginatorTrait、PublishedDataTrait;  
 }

这将导致 PHP 致命错误,因为解释器不知道哪个 获取页码() 使用。

 类图书写作  
 {  
 使用 PaginatorTrait, PublishedDataTrait {  
 PublishedDataTrait::getPageNumber instreadof PaginatorTrait;  
 }  
 }

有了那条线,您基本上是在说要使用 获取页码() 的方法 PublishedDataTrait 而不是 PaginatorTrait 的同名方法。

别名方法

如果你仔细阅读它,你现在可能会想出一个问题。

如果我们也想使用 PaginatorTrait::getPageNumber 怎么办?

记住,目标 插入 不是使用一种方法而不是另一种方法,

目标是避免冲突,从而避免我们代码中的致命错误。

解决方案非常简单。

我们所做的只是为剩余的函数创建一个别名。

 类图书写作  
 {  
 使用 PaginatorTrait, PublishedDataTrait {  
 PublishedDataTrait::getPageNumber instreadof PaginatorTrait;  
 PaginatorTrait::getPageNumber 作为 getPaginatorPage  
 }  
 } $book = new BookWriting();  
 回声 $book->getPageNumber(); // 这指的是 PublishedDataTrait  
 echo $book->getPaginatorPage(); // 这是指 PaginatorTrait

请注意,给一个或另一个特征的方法起别名是不够的。

您需要首先指明优先级 代替。

准备好迎接当天的最后一个小技巧了吗?

使用别名更改访问修饰符

您已经了解了别名的工作原理,现在应该很清楚了。

别名也可以具有其他特殊功能。

它可以即时更改特征的访问修饰符。

让我们看看它是如何以及为什么重要的。

 特征 PublishedDataTrait  
 {  
 公共函数 getPublisherId(): 字符串  
 {  
 返回 $this->publisher->getId();  
 }  
 } 类图书服务  
 {  
 使用 PublishedDataTrait {  
 PublishedDataTrait::getPublisherId 为私有  
 } 公共函数 getPublisherData()  
 {  
 返回 $this->getPublisherId()  
 }  
 } $book = new BookService();  
 回声 $book->getPublisherData(); // 这将返回 ID  
 回声 $book->getPublisherId(); // 这是一个错误:调用私有方法

特征被许多类使用,不仅相同的类处于同一级别。

其中一些可能会直接与控制器通信并提供诸如 ID 之类的合理详细信息。

通过指定访问修饰符(公共、受保护和私有之一),使用该特征的方法的类可以修改其行为。

为什么这很重要?

OOP 的开闭原则说对象应该对扩展开放但对修改关闭。换句话说,您应该能够在不更改模块的情况下更改模块的功能。在 OO 中,当您保持要扩展的代码不被修改时,可以最好地实现可扩展性。 — 鲍伯叔叔

不必担心在哪里调用一个类,因为它被设置为私有的,让我们的生活更轻松,让我们晚上睡得香

你怎么看?

你如何找到特质?

它是您经常使用的功能吗?

在下面的评论中写下您的想法。

结论

我已经做了将近十年的网络开发人员。

与位于伦敦市中心的世界级企业和屡获殊荣的营销机构合作。

此外,我还在博客和在线社区上撰写文章和教程。

单击此处阅读我的 100 多篇博文

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明

本文链接:https://www.qanswer.top/10922/28240208

posted @ 2022-09-02 08:30  哈哈哈来了啊啊啊  阅读(21)  评论(0编辑  收藏  举报