我看到您提供的有限代码存在几个问题。
您的House
类有一个公共成员type
,这意味着在对象(House
s 的实例)生命周期的任何时候,您都可以更改type
. 这使您的代码不仅难以测试,而且难以维护。因为 type 的值不能真正被信任(因为它可以随时更改)。所以我要做的第一件事就是创建该属性private
。并使用类的构造函数设置属性。
我注意到的第二件事是isResources
显然对数据库做某事的方法。但是我没有看到任何数据库连接被传入。无论是在构造函数中还是在方法中。这是非常可疑的,因为这意味着数据库连接可以通过以下方式访问:
- 在方法内创建新连接
- 在您的方法中使用某种形式的全局变量
两者都有问题:
在方法内创建新连接
这意味着您将数据库连接与House
类紧密耦合,而没有简单(和理智)的方式来对您的House
. 因为没有办法将数据库连接与其他连接交换。甚至是某种完全其他形式的存储。或者也许是一些模拟存储。
此外,此方法意味着您将在整个应用程序中拥有大量数据库连接,因为您将在每个需要它的类/方法中创建一个新连接。
此外,您无法通过查看您实际在其中使用数据库连接的方法签名来查看。这称为隐藏依赖项,应尽可能避免。
在你的方法中使用一些全局的
这在大多数情况下提出了与上述方法完全相同的问题。应该不惜一切代价避免全局变量和全局状态。无论您是global
直接使用关键字、访问$_GLOBALS
数组还是使用单例模式。在维护和可测试性方面,它们都有相同的问题。
前段时间我已经在另一篇文章中写下了原因、缺点和解决方案:在类中使用全局变量
我在该方法中注意到的另一件事isResources
是,它根据评论检查可用资源。现在让我们把这个例子带到现实生活中。当你要在现实生活中建造房子时,你真的会问(或检查)房子本身是否有足够的资源来建造房子吗?不,你没有。这违反了单一责任原则,而且没有多大意义(询问房子是否有资源来建造房子)。
我看到你的类也有一个buildHouse
方法,这也很奇怪。使用构造函数构造(构建)对象。这种方法没有理由存在。您应该将所有信息(房屋的元素)传递给构造函数。
根据我上面提供的信息(我可能还有更多信息可以告诉你),你最终会得到如下信息:
<?php
class Factory
{
private $resources;
public function __construct(Resources $resources)
{
$this->resources = $resources;
}
public function build($type, array $coordinates)
{
if (!$this->resources->areAvailable()) {
throw new \UnavailableResourcesException('Not enough resources to build the house');
}
return new House($type, array $coordinates);
}
}
class Resources
{
private $dbConnection;
public function __construct(\PDO $dbConnection)
{
$this->dbConnection = $dbConnection;
}
public function areAvailable()
{
// check database for resources
return true;
}
}
class House
{
private $type;
private $coordinates;
public function __construct($type, array $coordinates)
{
$this->type = $type;
$this->coordinates = $coordinates;
}
}
$dbConnection = new PDO('mysql:dbname=yourdatabase;host=127.0.0.1;charset=utf8', 'user', 'pass');
$dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$resources = new Resources($dbConnection);
$factory = new Factory($resources);
$myHouse = $factory->build('tipi', array(22, 13));
请注意,在我上面的示例代码中仍然可以进行足够的改进,但这只是为了给您一个入门的想法。
另请注意,Stack Overflowers 同事给你的关于调查 Yii、Cake 或 CI 的建议是可怕的恕我直言。因为这些框架根本没有教授好的 OOP 实践。例如,Yii 充满了static
方法,这基本上意味着您的应用程序充满了全局状态。从任何定义来看,Cake 都不是 OOP。还要注意(再次恕我直言)Yii、CI 和 Cake 是目前最流行的三个框架。