使用空实例是好事还是坏事?
有“产品”类,以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 :(得分: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 */);
答案 1 :(得分:3)
两者都可以是良好做法。也许你对第二个的实现并不是那么好。
实际上,第二个是工厂模式的简单实现。检查此链接,您会更好地理解:
也许事情是工厂方法应该在像ProductFactory这样的类中,所以,ProductFactory->new(...)
将是拥有伟大工厂的最佳方式!
答案 2 :(得分:2)
理想情况下,对象的状态应始终为valid。这通常更多的是内部状态而不是外部可见状态,但您可以在此处应用此概念。如果具有空名称或数据,或者ID为0无效(如果ID为0是“持久存储中不存在”的标记,则它是有效的),那么这不是最佳实践。坚持代码的原因是保持对象有效而不是程序员,否则依赖程序员阅读类的文档。当有人在他们的电子商务网站上使用您的课程时,您会收到投诉,告知他们收到的订单中有空白项目,您会看到这种方法的智慧。
要实现始终在PHP中保持有效状态的最佳实践,您可以使用工厂模式,如Matías所述,或者只是在product
上使用静态方法来创建产品(这比工厂模式;这些方法在技术上只是构造函数)。或者,您可以使用func_get_args
手动实现构造函数重载(检查参数并根据它们的不同采取不同的操作)。这将在运行时而不是编译时捕获调用错误,并且这种方式不如其他方法。
当然,在脚本执行期间,产品缺少某些属性可能完全有效,但对于存储对象缺少的属性无效。如果是这种情况,存储/检索product
的代码将强制执行非空属性。
答案 3 :(得分:0)
糟糕的形式。基本上你给了一个带有令人困惑的名字的setter方法。
此外,您正在将构造函数初始化与setter初始化混合。选择一个或另一个,但不是两个。