2011-02-04 79 views
1

使用空实例是好习惯还是坏习惯?面向对象练习“空”对象

有“产品”类,与ID启动:

class product 
{ 
    __construct($id = 0) 
    { 
     // populate class, there is no product with id = 0 
    } 

    function new($name, $data) 
      ... 
} 


$product = new Product(123); // normal using 

但我也需要创建新的产品,所以没有初始对象,我创建空单:

$product = new Product(); 
$product->new($name, $data); 

是好还是坏?
可能是我应该创建通常的函数new_product(),产品类外,因为它不使用它的实例,只是创建空的。
这个问题的最佳做法是什么?

+0

等等,所以,你正在使用一个实例来创建一个实例,什么? – BoltClock 2011-02-04 08:05:06

回答

3

两者都可能是良好的做法。也许你的第二个实施不太好。

其实第二个是工厂模式的简单实现。检查这个环节,你会更好地理解:

也许就是工厂方法应该是像ProductFactory一些类,所以,ProductFactory->new(...)将有你的伟大的最佳方式厂!

0

坏形式。基本上你已经给了一个令人困惑的名字的setter方法。

另外你还将构造函数初始化和setter初始化混合在一起。选择一个或另一个,但不是两个。

4

如果我正确地理解了你并且正确地遵循了你的方法论,你很可能会想要这样的东西。这样您就不需要创建Product类的实例来创建新产品。

class Product { 
    public function __construct($id = 0) { 
     // Load the data for existing product with Id > 0 
    } 

    public static function create($name, $data) { 
     // Create a new product from scratch 
     $obj = new self(); 
     $obj->Name = $name; 
     // Do something with data 
     return $obj; 
    } 
} 

// Load a product 
$product = new Product(123); 

// Creating a product 
$product = Product::Create('My new product', /* Data? Possible an array */); 
2

理想情况下,对象的状态应始终为valid。这通常更多的是内部状态而不是外部可见状态,但是你可以在这里应用这个概念。如果有一个空的名字或数据,或者ID为0是无效的(如果ID为0是“在持久性存储中不存在”的标记,那么它是有效的),那么这不是最佳实践。坚持代码的原因是保持对象有效,而不是程序员,否则依赖于程序员阅读类的文档。当有人在他们的电子商务网站上使用你的班级发送电子邮件给你,他们收到的订单中有空白项目的投诉,你会看到这种方法的智慧。为了实现在PHP中始终保持有效状态的最佳做法,可以使用工厂模式,如Matías提到的那样,或者简单地在product上使用静态方法来创建产品(这比工厂模式稍简单一些;这些方法在技术上只是构造函数)。或者,您可以使用func_get_args来手动实现构造函数重载(检查参数并根据它们执行不同的操作)。这将在运行时而不是编译时捕获调用错误,并且在这方面不如其他方法。

当然,对于产品在脚本执行过程中缺少某些属性可能完全有效,但对存储对象缺少的属性无效。如果是这种情况,那么存储/检索product的代码将强制执行非空属性。