Tôi đang cân nhắc một trong hai cách khác nhau để triển khai mẫu nhà máy trong PHP. Tôi không biết liệu những biến thể này có tên riêng hay không, bây giờ tôi sẽ gọi chúng là nhà máy nội bộ và nhà máy bên ngoài.Nhà máy bên trong và bên ngoài
nhà máy nội bộ: Các phương pháp nhà máy được thực hiện trong các lớp chính nó như là một phương pháp public static
<?php
class Foo
{
protected
$loadedProps = false;
public static factory ($id)
{
$class = get_called_class();
$item = new $class ($id);
if ($item -> loadedProps())
{
return ($item);
}
}
public function loadedProps()
{
return ($this -> loadedProps);
}
protected function loadPropsFromDB ($id)
{
// Some SQL logic goes here
}
protected function __construct ($id)
{
$this -> loadedProps = $this -> loadPropsFromDB ($id);
}
}
?>
nhà máy bên ngoài: Các nhà máy và các mục nó khởi được thực hiện như những thực thể riêng biệt
<?php
class Foo
{
protected
$loadedProps = false;
public function loadedProps()
{
return ($this -> loadedProps);
}
protected function loadPropsFromDB ($id)
{
// Some SQL logic goes here
}
public function __construct ($id)
{
$this -> loadedProps = $this -> loadPropsFromDB ($id);
}
}
abstract class FooFactory
{
public static factory ($id)
{
$item = new Foo ($id);
if ($item -> loadedProps())
{
return ($item);
}
}
}
?>
Bây giờ có vẻ như với tôi rằng mỗi người đều có giá trị của nó.
Trước đây cho phép bạn ẩn công cụ xây dựng khỏi thế giới bên ngoài. Điều này có nghĩa là cách duy nhất bạn có thể tạo đối tượng Foo là thông qua nhà máy. Nếu trạng thái của mục không thể được nạp từ DB thì nhà máy sẽ trả về NULL mà bạn có thể kiểm tra dễ dàng trong mã.
if ($item = Foo::factory ($id))
{
// ...
}
else
{
// The item failed to load. Handle error here
}
Nhà máy cũng có thể tạo đối tượng của bất kỳ phân lớp Foo nào mà không sửa đổi.
Tuy nhiên, dường như có một số hạn chế. Đầu tiên, lớp học phải thực hiện nhà máy, có thể đặt trách nhiệm vào lớp thực sự thuộc về nơi khác. Phiên bản nhà máy nội bộ chắc chắn dẫn đến một lớp lớn hơn so với phiên bản nhà máy bên ngoài.
Đối với nhà máy bên ngoài, nó sạch hơn vì nhà máy không nằm trong chính lớp và tôi không phải lo lắng về việc lớp học chịu trách nhiệm nhiều hơn mức cần thiết. Nhà máy bên ngoài cũng có thể phù hợp hơn với tiêm phụ thuộc.
Tuy nhiên, nó có tập hợp các hạn chế riêng. Đầu tiên và quan trọng nhất, hàm tạo của mục được xây dựng trong nhà máy phải được công khai vì PHP không có khái niệm về các gói và không có mức bảo vệ 'gói' cho các thành viên lớp. Điều này có nghĩa là không có gì ngăn chặn một coder từ chỉ làm mới Foo() và bỏ qua các nhà máy (Điều này có thể làm cho đơn vị thử nghiệm dễ dàng hơn, mặc dù).
Vấn đề khác là FooFactory chỉ có thể tạo đối tượng Foo, không phải bất kỳ lớp con nào của nó. Điều này có thể có xung quanh bằng cách thêm một tham số khác vào FooFactory để chỉ định tên lớp, nhưng sau đó nhà máy sẽ phải kiểm tra nội bộ mà lớp đối tượng đã chỉ định thực tế là hậu duệ của Foo.
Vì vậy, về cơ bản, giá trị tương đối của hai cách tiếp cận là gì và bạn sẽ đề xuất điều gì?
Ngoài ra, nếu chúng có tên riêng hơn nhà máy bên trong hoặc bên ngoài, tôi muốn biết chúng.
'Off-topic:' Trên một lưu ý ngẫu nhiên tôi thấy nó hài hước mà cả hai bạn đang nói về cùng một điều khi bạn cũng có cùng tên người dùng. Trong một giây, tôi nghĩ bạn đang nói chuyện với chính mình. – Tek
@Tek yeah, Gordon trả lời Gordon. Nhưng tôi là Gordon ™ :) – Gordon