【问题标题】:Is this good practice for encapsulation in PHP?这是在 PHP 中封装的好习惯吗?
【发布时间】:2017-03-16 02:55:11
【问题描述】:

例如,我有一个运行 MySQL 查询的类,我想封装这个类。

class SqlQuery {

  private $database_connection_obj;

  public function __construct($dbh) {
     $this->$database_connection_obj = $dbh;
  }

  public function runQuery($query, $params) {

     //run query implementation...

  }

}

封装和信息隐藏意味着我想关闭对类方法的直接访问,因此函数 runQuery() 不应该是公共的,所以我将其设为私有并添加方法 exacuteQuery(),其唯一目的是将数据传递给私有函数 runQuery() .

这样做的实际用途是什么,因为最终它的工作方式与上面的代码完全相同。 在将输入数据传递给私有方法之前,是否应该在公共方法中对输入数据进行一些清理,或者为什么要编写这个额外的代码?

class SqlQuery {

  private $database_connection_obj;

  public function __construct($dbh) {
     $this->$database_connection_obj = $dbh;
  }

  public function exacuteQuery($external_query, $external_params) {
     $this->runQuery($external_query, $external_params);
  }    

  private function runQuery($query, $params) {

     //run query implementation...

  }

}

【问题讨论】:

  • 我看不出有任何理由将runQuery() 包装在给定的代码中。为什么你认为你需要用这种包装器使你的代码复杂化? =)
  • 什么是封装,你能举个例子吗?

标签: php class oop encapsulation


【解决方案1】:

主要思想是让类看起来像black boxes,这意味着外部人员(即另一个类或持有该类实例的函数)不知道它在内部是如何工作的。这对他们来说是抽象的

查询的内部工作对持有查询和调用->run()的类无关紧要,它只关心查询的运行,不一定关心它的运行方式或运行位置。

请注意,查询是非常低级的抽象,它相对接近于直接调用标准库函数/对象。但是考虑到低级别的抽象,您可以进行更高级别的抽象。

例如,UserStore,它在内部使用SqlQuery 对象来获取User 对象并将其设置到数据库中。使用UserStore 的类并不知道UserStore 在内部使用SqlQuery 对象,它只知道这是一个可以保存和检索User 对象的对象。

这种“隐藏”和“封装”实际上给了你很大的力量,因为现在类可以使用其他类而不依赖于具体的实现细节。如果明天您想更改存储Users 的方式,只需更改UserStore 类,只要它具有相同的公共API,其余的应用程序甚至不会意识到发生了什么变化。

【讨论】:

  • 我得到了理论,我的问题更多的是关于 PHP 中的实现,你会说应该使用我提供的第一个或第二个代码示例吗?为什么。
  • 哦,抱歉。具体来说,创建一个仅委托给具有相同签名的私有函数的公共函数没有任何好处。您可以使用对私有函数的委托从多个方法中抽象出类似的功能(例如,select()update() 我拥有的一个共同功能是需要准备查询,这可以是一个私有函数公众打电话,从那里获得一些服务。
【解决方案2】:

给出的细节没有区别,但这取决于工作。当我必须制作一个无法直接访问但只能通过其使用方法访问的功能时,我会多次使用它。它优化代码并拒绝代码外的访问。否则任何人都可以更改可能有害的参数。

【讨论】:

  • 请提供示例。
  • 我经常用它来发邮件,这是一种私有方法,只有在一定条件下才可以通过其他方法发送。这是一个例子
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-27
  • 1970-01-01
  • 2021-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多