2009-06-29 38 views
7

Tôi có một lớp học với một chức năng nhà máy-pattern trong đó:lớp con instantiating từ lớp cha (PHP)

abstract class ParentObj { 
    public function __construct(){ ... } 
    public static function factory(){ 
     //returns new instance 
    } 
} 

Tôi cần em để có thể gọi hàm nhà máy và trả về một thể hiện của sự kêu gọi class: $child = Child::factory(); và tốt nhất là không ghi đè hàm nhà máy trong lớp con.

Tôi đã thử nhiều cách khác nhau để đạt được điều này không có kết quả. Tôi muốn tránh xa các giải pháp sử dụng phản chiếu, như __CLASS__.

(Tôi đang sử dụng PHP 5.2.5 nếu vấn đề)

Trả lời

10

Nếu bạn có thể nâng cấp lên PHP 5.3 (released 30-Jun-2009), hãy kiểm tra late static binding, mà có thể cung cấp một giải pháp:

abstract class ParentObj { 
    public function __construct(){} 
    public static function factory(){ 

     //use php5.3 late static binding features: 
     $class=get_called_class(); 
     return new $class; 
    } 
} 


class ChildObj extends ParentObj{ 

    function foo(){ 
     echo "Hello world\n"; 
    } 

} 


$child=ChildObj::factory(); 
$child->foo(); 
+0

Tôi đang chơi với RC4 vào phút vì vậy tôi sẽ cố gắng một số mã trong thời gian ngắn nếu không có ai khác bước lên trong khi chờ đợi ... –

+0

LSB dường là giải pháp tốt nhất mà tôi có thể tự tìm thấy. Cho đến khi tôi nâng cấp, tốt nhất tôi có thể đưa ra là chuyển tên con cho nhà máy() hoặc xác định tên là tài sản và lấy tên từ nhà máy() –

+0

Theo hướng dẫn sử dụng PHP, có một hàm gọi là ' get_called_class() 'hoạt động giống như' __CLASS__' http://us.php.net/manual/en/function.get-called-class.php –

0

Trong tôi ý kiến ​​khiêm tốn những gì bạn đang cố gắng làm không có ý nghĩa.

Một mô hình nhà máy sẽ làm việc như thế này:

abstract class Human {} 

class Child extends Human {} 
class Fool extends Human {} 

class HumanFactory 
{ 
    public static function get($token) 
    { 
     switch ($token) 
     { 
      case 'Kid' : return new Child(); 
      case 'King': return new Fool(); 
      default : throw new Exception('Not supported'); 
     } 
    } 
} 

$child = HumanFactory::get('Kid'); 
+0

Vâng, đó là một mô hình nhà máy toàn diện. Tôi chỉ đơn giản là một phương pháp tĩnh để bỏ qua toán tử 'new' và cung cấp khả năng đọc và chuỗi cho các lớp con. –

+0

tại sao bạn muốn bỏ qua toán tử mới? –

+1

để sử dụng ví dụ của bạn, Child mới() -> foo() không hoạt động. bằng cách thêm phương thức "factory" (như tôi sử dụng nó), bạn có thể làm Child :: factory() -> foo() -> bar(), dễ đọc hơn (IMHO) hơn là chia nhỏ nó thành một vài dòng. Tôi đoán đó là vấn đề về ý kiến ​​và công bằng, việc bạn triển khai nhà máy là một công cụ hữu ích. Chỉ cần không cho những gì tôi đang tìm kiếm. –

Các vấn đề liên quan