2013-01-20 51 views
8

Bạn nên tạo các đối tượng không thể thay đổi trong PHP?Các đối tượng không thể thay đổi trong PHP?

Ví dụ một đối tượng ngày có phương thức setter, nhưng chúng sẽ luôn trả về một thể hiện mới của đối tượng (với ngày sửa đổi).

Các đối tượng này có gây nhầm lẫn cho người khác sử dụng lớp không, vì trong PHP bạn thường mong đợi đối tượng thay đổi?

Ví dụ

$obj = new Object(2); 

$x = $obj->add(5); // 7 
$y = $obj->add(2); // 4 
+0

Bạn có thấy bất kỳ lợi ích trong có lớp học mà làm điều này? Tôi có thể xem xét một cách tiếp cận tốt hơn sẽ chỉ đơn giản là từ chối * settability * (có tôi đã làm điều đó lên) vào tài sản bạn không muốn thay đổi, buộc họ phải tạo một trường hợp mới nếu cần thiết. EDIT: Yea, những gì ThiefMaster nói :) –

+0

http: // stackoverflow.com/questions/7317037/php-immutable-public-member-fields ví dụ này có thể giúp bạn hiểu rõ hơn –

Trả lời

5

Một đối tượng không thể thay đổi không thể thay đổi sau khi tạo ban đầu của nó để có phương pháp setter không có ý nghĩa khi nó đi ngược lại nguyên tắc cơ sở đó.

Bạn có thể thực hiện một số giải pháp để mô phỏng tính bất biến trong PHP bằng cách thao tác hiển thị thành viên lớp và ghi đè phương thức magic __set() nhưng không đảm bảo bất biến như tính bất biến không phải là tính năng của ngôn ngữ. Tôi tin rằng ai đó đã từng viết một phần mở rộng để cung cấp một loại giá trị bất biến trong PHP mặc dù vậy bạn có thể google cho điều đó.

+2

PHP RFC: Các lớp và thuộc tính không thể thay đổi https://wiki.php.net/rfc/immutability –

+0

Về "có các phương thức setter không có ý nghĩa": phương thức 'add' (giống như phương thức được đề cập trong câu hỏi) có thể có ý nghĩa một đối tượng bất biến bằng cách trả về một đối tượng mới với trạng thái đã sửa đổi. –

17

đối tượng Immutable không có phương pháp setter. Giai đoạn.

Mọi người sẽ mong đợi phương thức setXyz() để có loại trả lại khoảng trống (hoặc không trả lại gì bằng các ngôn ngữ được nhập sai). Nếu bạn thêm các phương thức setter vào đối tượng bất biến của bạn, nó sẽ gây nhầm lẫn cho mọi người và dẫn đến các lỗi xấu xí.

+1

cũng không được gọi là set(), nhưng tôi không biết cách gọi chúng. phương pháp addetter? :) – Elfy

+0

Mặc dù một số trong số những "Mọi người" sẽ không ngạc nhiên khi nhận được một thể hiện của đối tượng của setter, để cho phép phương pháp chuỗi ;-) –

+4

@Elfy Gọi chúng là "với" phương pháp. '$ obj-> withMyProp ($ x)' trả về một cá thể mới * với * "MyProp" được đặt thành '$ x'. – mpen

8

Trong các đối tượng ý kiến ​​của tôi nên không thay đổi đối với các đối tượng giá trị. Khác hơn là nó không có nhiều lợi ích trừ khi bạn đang chia sẻ đối tượng của bạn trên toàn bộ ứng dụng của bạn.

Có một số câu trả lời sai ở đây, đối tượng không thay đổi có thể có bộ định vị. Dưới đây là một số thực hiện các đối tượng bất biến trong PHP.

Ví dụ số 1.

class ImmutableValueObject 
{ 
    private $val1; 
    private $val2; 

    public function __construct($val1, $val2) 
    { 
     $this->val1 = $val1; 
     $this->val2 = $val2; 
    } 

    public function getVal1() 
    { 
     return $this->val1; 
    } 

    public function getVal2() 
    { 
     return $this->val2; 
    } 
} 

Như bạn có thể thấy ngay khi bạn không thể thay đổi bất kỳ giá trị nào.

Ví dụ 2: với setters:

class ImmutableValueObject 
{ 
    private $val1; 
    private $val2; 

    public function __construct($val1, $val2) 
    { 
     $this->val1 = $val1; 
     $this->val2 = $val2; 
    } 

    public function getVal1() 
    { 
     return $this->val1; 
    } 

    public function withVal1($val1) 
    { 
     $copy = clone $this; 
     $copy->val1 = $val1; 

     return $copy; // here's the trick: you return a new instance! 
    } 

    public function getVal2() 
    { 
     return $this->val2; 
    } 

    public function withVal2($val2) 
    { 
     $copy = clone $this; 
     $copy->val2 = $val2; 

     return $copy; 
    } 
} 

Có nhiều thi thể và điều này là không phải là một danh sách độc quyền. Và hãy nhớ rằng với Reflection luôn luôn có một cách để có được xung quanh đó trong PHP, vì vậy bất biến là tất cả trong đầu của bạn cuối cùng!

Nó cũng thường là thực hành tốt để đặt các đối tượng bất biến là cuối cùng.

EDIT:

  • thay đổi setX cho withX
  • thêm nhận xét về thức
+0

Nên 'trả về $ this;' thực sự trả về '$ copy'? –

+0

Cố định lỗi cảm ơn cho rằng –

+0

"Trong khoa học máy tính, một phương pháp mutator là một phương pháp được sử dụng để kiểm soát thay đổi cho một biến. Họ cũng được biết đến rộng rãi như là phương pháp setter" .__ Một đối tượng bất biến không thể có setters__. Phương pháp của anh ta không thay đổi trạng thái bên trong của đối tượng. __Họ chỉ tạo một cá thể mới__. Đó là một sự khác biệt lớn. –

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