2012-06-23 36 views
12

Tôi cần tạo khoảng. 5-7 lớp, mỗi lớp sẽ chứa rất nhiều thành viên (chúng ta hãy nói mỗi lớp sẽ chứa 20 thành viên). Tôi có thể tạo chúng bằng cách sử dụng quyền truy cập công cộng, như:PHP OOP rất nhiều người định cư, getters

class A { 
    public $myPropertyOne = ''; 
    public $myPropertyTwo = ''; 
    ... 
} 

Cách ưa thích của khóa học để làm cho các thành viên này riêng tư và tạo phương thức get/set cho từng thuộc tính. I E.

class A { 
    private $myPropertyOne = ''; 
    private $myPropertyTwo = ''; 

    public function getMyPropertyOne() { 
      return $this->myPropertyOne; 
    } 

    public function setMyPropertyOne($myPropertyOne) { 
      $this->myPropertyOne = $myPropertyOne; 
    } 

    public function getMyPropertyTwo() { 
      return $this->myPropertyTwo; 
    } 

    public function setMyPropertyTwo($myPropertyTwo) { 
      $this->myPropertyTwo = $myPropertyTwo; 
    } 
} 

Nhưng xem xét một lớp học sẽ có 20 thuộc tính, tôi sẽ bổ sung thêm 40 phương pháp này. Và mối quan tâm của tôi ở đây là làm thế nào điều này sẽ làm chậm kịch bản và bộ nhớ nhiều hơn nữa điều này sẽ yêu cầu (nhớ tôi sẽ có một số lớp học như thế này).

Một giải pháp khác có thể là sử dụng các hàm ma thuật __set, __get nhưng tôi không muốn, vì việc hoàn thành mã trong phát triển IDE sẽ không đề xuất các thuộc tính quan trọng đối với tôi.

Nếu đây là ngôn ngữ biên dịch (như C++), tôi sẽ không có câu hỏi và sử dụng giải pháp với getters, setters nhưng vì ngôn ngữ PHP được hiểu là tôi quan tâm đến kịch bản của mình sử dụng ít RAM hơn nhanh nhất có thể.

Xin cảm ơn trước, mọi suy nghĩ về câu hỏi này sẽ được nhiều người đánh giá cao!


Ý kiến ​​của tôi

Cảm ơn tất cả các bạn cho câu trả lời của bạn, tôi chỉ muốn chia sẻ ý kiến ​​của tôi trong trường hợp ai đó sẽ tìm kiếm một câu trả lời cho câu hỏi này.

Tôi hoàn toàn không đồng ý với những người nói rằng bạn không nên quan tâm đến hiệu suất vì đây là nhiệm vụ của trình tối ưu hóa, tôi nghĩ đây là yếu tố quan trọng (ít nhất là đối với tôi), khi chúng tôi đang xử lý ngôn ngữ thông dịch như PHP chúng ta sẽ luôn phải suy nghĩ về bộ nhớ và tốc độ (tất cả điều này nhắc nhở tôi về thời gian khi tôi đang phát triển các ứng dụng hệ thống cho DOS, heh :) và bạn luôn bị giới hạn với CPU và kilobyte của RAM, vì vậy bạn sẽ vui nếu bạn có thể lưu thêm một byte), trong PHP phát triển bạn có cùng một hình ảnh như bất kể có bao nhiêu máy chủ bạn thêm, số người dùng sẽ luôn cao hơn để bạn luôn phải quyết định xem bạn có muốn theo phương thức cổ điển/an toàn/thích hợp hay không để tránh điều này và tăng tốc độ hoặc bộ nhớ. Vì vậy, .... ý kiến ​​của tôi là cách tốt nhất ở đây là sử dụng truy cập công cộng cho tất cả thành viên và tránh getters/setters cho tất cả các thuộc tính và sử dụng truy cập riêng với get/set phương pháp cho các thuộc tính yêu cầu xác thực dữ liệu hoặc khởi tạo trước khi giá trị được đặt.

Ví dụ:

class B { 
    public $myPropertyOne = ''; 
    public $myPropertyTwo = ''; 
    private $myPropertyThree = array(); 


    public function getMyPropertyThree() { 
     return $this->myPropertyThree; 
    } 

    public function setMyPropertyThree($val) { 
     if(!is_array($val)) { 
      return; 
     } 

     $this->myPropertyThree = $val; 
    } 
} 

Cảm ơn bạn đã dành thời gian vào câu hỏi của tôi!

+14

đây là tối ưu hóa vi mô, và bạn nên * không bao giờ * lo lắng về nó. –

+0

Vâng, vâng, một viễn cảnh để thêm 280 phương pháp (cho 7 lớp học, 20 thành viên riêng) chỉ cho điều này một chút sợ tôi từ bộ nhớ/tốc độ standpoint.Và hãy nói hệ thống phát triển và tôi sẽ mở rộng các lớp học với số lượng 15 .. sau đó tôi sẽ nhận được 600 phương pháp. phía bên kia tôi nhận ra rằng các phương thức get/set này sẽ được thực thi chỉ khi cần nhưng đồng thời tôi giả định rằng khi PHP phân tích mã nguồn, nó sẽ xây dựng một bảng các phương thức trong bộ nhớ, sẽ thực hiện phân tích cú pháp và tất cả điều này có thể làm chậm công việc của kịch bản rất nhiều, là giả định của tôi phải không? – user1476490

+1

Bộ nhớ là tương đối rẻ và phương thức chi phí trên mỗi lớp (không phải cho mỗi trường hợp). PHP cũng thực hiện các thủ thuật như xử lý nhiều yêu cầu trong cùng một quá trình (qua mod_php, vv) để thời gian tải ban đầu (tầm thường như nó có thể) có thể bị bỏ qua hoàn toàn ... trong mọi trường hợp, * điểm chuẩn đầu tiên * (trong điều kiện thực tế) để xem phần "chậm" của hệ thống là gì. (FWIW, giả định rằng có 600 phương pháp, và mỗi phương pháp "lãng phí" 1kb. Một whopping 600kb là "lãng phí". Không thực sự nhiều trong kế hoạch của sự vật ... đặc biệt là xem xét bao nhiêu * mỗi biến * trong PHP đã " chất thải ";-) –

Trả lời

5

thử nghiệm đơn giản cho thấy trường hợp mất cùng một lượng bộ nhớ, không bị ảnh hưởng bởi số lượng các phương pháp trong một lớp học:

Lớp không có phương pháp:

class Test1 { } 

Class với 20 phương pháp:

class Test2 { 

    function test1() { return true; } 
    function test2() { return true; } 
    function test3() { return true; } 
    function test4() { return true; } 
    function test5() { return true; } 
    function test6() { return true; } 
    function test7() { return true; } 
    function test8() { return true; } 
    function test9() { return true; } 
    function test10() { return true; } 
    function test11() { return true; } 
    function test12() { return true; } 
    function test13() { return true; } 
    function test14() { return true; } 
    function test15() { return true; } 
    function test16() { return true; } 
    function test17() { return true; } 
    function test18() { return true; } 
    function test19() { return true; } 
    function test20() { return true; } 

} 

Vòng lặp kiểm tra, giống nhau cho cả hai thử nghiệm:

$test = array(); 
$base = memory_get_usage(); 
for ($i = 0; $i < 10000; $i++) { 
    $test[] = new ClassToBeTested(); 
} 
$used = memory_get_usage() - $base; 
print("used: $used\n"); 

Kết quả cho lớp Test1 (không có phương pháp):

used: 3157408 

Kết quả cho lớp Test2 (20 phương pháp):

used: 3157408 

Tôi đã chạy nó trong hai kịch bản riêng biệt, vì chạy hai bài kiểm tra trong một kịch bản đơn lẻ đã cho thấy một số phân bổ nội bộ PHP, và thử nghiệm thứ hai tiêu thụ ít bộ nhớ hơn so với lần đầu tiên, không có vấn đề cái nào là đầu tiên hoặc thứ hai.

Mặc dù bạn chắc chắn có nhiều bộ nhớ hơn cho định nghĩa lớp thực tế, rõ ràng chi phí này chỉ phát sinh một lần cho mỗi lớp, không phải cho mỗi trường hợp. Bạn không phải lo lắng về việc sử dụng bộ nhớ.

+0

Rất tiếc, tôi không thể dán nhiều mã ở đây nhưng đây là những gì tôi đã làm. Tôi đã tạo test1.php với một lớp duy nhất trong đó, sau đó test2.php với một lớp và một phương thức duy nhất, và sau đó test3.php với lớp, 20 thuộc tính riêng và sau đó 40 phương thức get/set công khai (với tất cả các trả về, v.v.). Và tổng sản lượng sử dụng RAM ở cuối, vì vậy đây là những gì tôi nhận: 'test1.php - 653,97 Kbytes' ' test2.php - 654,73 Kbytes' 'test3.php - 718,16 Kbytes' Đây là thô nhưng về cơ bản tôi giả sử mỗi phương pháp/biến không đếm dữ liệu mà nó nắm giữ, ăn ~ 1kb. – user1476490

5

Nhưng xem xét một lớp sẽ có 20 thuộc tính

Có nhiều tài sản này thường là một chỉ báo về thông tin đặt không đúng chỗ. Kiểm tra xem bạn có thể nhóm một số người đó thành các lớp học của riêng họ hay không.

tôi sẽ có thêm vào tiện ích này 40 phương pháp.

Không hề. Trừ khi các lớp này là cấu trúc dữ liệu câm, bạn không muốn bất kỳ Getters and Setters nào trên chúng vì chúng phá vỡ đóng gói. Đặt các phương thức trong API công khai mà bạn yêu cầu các đối tượng làm việc.

Và mối quan tâm của tôi ở đây là như thế nào sẽ làm chậm kịch bản và nhiều hơn nữa bộ nhớ này này sẽ đòi hỏi (nhớ tôi sẽ có một vài các lớp như thế này).

Đây không phải là vấn đề.

Một giải pháp khác có thể được sử dụng chức năng kỳ diệu __set, __get nhưng tôi không muốn, bởi vì hoàn thành mã trong phát triển IDE sẽ không đề nghị đặc tính đó là rất quan trọng đối với tôi .

IDE hiện đại có thể tự động hoàn tất trên các phương pháp ma thuật.

Tuy nhiên, nếu bạn đã quan tâm đến biểu diễn tại microlevel, sau đó bạn không muốn phương pháp kỳ diệu bởi vì đó là chắc chắn chậm hơn.

Ngoài ra, Magic Phương pháp không phải là sản phẩm thay thế cho getter và setter nhưng xử lý lỗi mà có được kích hoạt khi một tài sản không thể tiếp cận hay phương pháp được gọi.

Ngoài ra, phương pháp kỳ diệu là unobvious và làm cho khó đọc API.

+0

Cảm ơn bạn đã phản hồi chi tiết. – user1476490

0

Hãy nhớ rằng mã của tôi cho rằng tên đặc tính đã được khai báo trong chữ thường ...

<?php 

    class Modelo { 
     var $attr1 = "default"; 
     var $attr2 = 0; 


     public function __call($name, $arguments) 
     { 
      if (method_exists($this, ($method = $name))){ 
       return $this->$method(); 
      } 
      else{  
       $attribute = split("get",$name); 
       if(count($attribute)==2){ 
        $attribute = strtolower($attribute[1]); 
        if(isset($this->$attribute)){ 
         return ($this->$attribute); 
        } 
       }else{ 
        $attribute = split("set",$name); 
        if(count($attribute)==2){ 
         $attribute = strtolower($attribute[1]); 
         if(isset($this->$attribute) && count($arguments)==1){ 
          $this->$attribute=$arguments[0]; 
         }else{ 
          die("$name number of arguments error: ".join($arguments,",")); 
         } 
        }else{ 
         die("$name doesn't exist!"); 
        }    
       }   
      } 
     } 


    } 

    echo "<pre>"; 
    $m = new Modelo(); 
    print_r(
     array(
      "objetct"=>$m 
      ,"getAttr1"=>$m->getAttr1() 
      ,"getAttr2"=>$m->getAttr2() 
     ) 
    ); 
    echo "setAttr1\n"; 
    $m->setAttr1("by set method"); 
    print_r(
     array(
      "objetct"=>$m 
      ,"getAttr1"=>$m->getAttr1() 
      ,"getAttr2"=>$m->getAttr2() 
     ) 
    ); 

    ?> 
+0

Cảm ơn bạn, nhưng làm thế nào mã hoàn thành chúng ta hãy nói trong nhật thực hoặc netbeans làm việc trong trường hợp này? – user1476490

0

Như đã trình bày trước đây, nó khá lạ mà lớp học của bạn nên có rất nhiều tài sản. Tuy nhiên, đôi khi nó có thể (khá hiếm khi xảy ra) xảy ra. Nhưng thông thường, các thuộc tính đó phải có một loại liên kết với nhau: vì vậy bạn có thể lưu trữ chúng trong một hashmap chứ không phải một thuộc tính. Sau đó, bạn chỉ cần neeed một phương pháp như là một getter.

Bây giờ, nó chắc chắn sẽ tốn nhiều tài nguyên hơn, đúng sự thật. Đối với autocompletion, sử dụng các hằng số: bạn sẽ chỉ cần gõ một cái gì đó như:

$my_class->getFromHashMap($parameter) 

Và khi gõ thông số của bạn, bạn sẽ sử dụng liên tục vì nó được lưu trữ trong các lớp: ở đây, autocomplete sẽ có thể giúp bạn.

+0

Vâng, tôi hiện đang giữ tất cả các thuộc tính trong mảng kết hợp nhưng điều này không rõ ràng đối với người dùng cuối (nhà phát triển) cách sử dụng tất cả, vì vậy tôi phải sử dụng hoàn thành mã và nhận xét doc cộng với tôi muốn cải thiện mã bằng cách xác thực dữ liệu khi người dùng đặt biến. Bản đồ băm là một giải pháp tốt nhưng điều này sẽ dẫn đến các vấn đề khác có thể xảy ra (nhà phát triển có thể nhập nhầm tên tham số, tôi sẽ không thể sử dụng tái cấu trúc nếu tôi muốn đổi tên tham số, v.v.Trừ – user1476490

+0

Ngoại trừ việc xác nhận dữ liệu, sử dụng hằng số làm khóa cho hashmap của bạn sẽ giải quyết hầu hết vấn đề bạn đang mô tả (và thậm chí bạn có thể ngăn chặn, trong trình cài đặt của bạn, sử dụng khóa không được xác định trong hằng số của bạn). – Raveline

0

Để làm cho tính chất của lớp học của bạn mà thực hiện bằng các phương pháp kỳ diệu để được highlited bởi IDE chỉ cần sử dụng @property PHPDoc @property thẻ, như thế này:

<?php 
/** 
* @property int id Blog post ID 
* @property string title Blog post Title 
*/ 
class Post { 

} 

Thông tin thêm về PHPDoc' @property đây: http://manual.phpdoc.org/HTMLSmartyConverter/PHP/phpDocumentor/tutorial_tags.property.pkg.html

Đối với các vấn đề khác được đặt câu hỏi - Karoly Horvath 'bình luận đầy đủ bao gồm những PHP OOP a lot of setters, getters.

0

Bạn có thể thử này:

đặc điểm get_set {

public function set($what, $value) 
{ 
    $this->{$what} = $value; 
} 

public function get($what) 
{ 
    return $this->{$what}; 
} 

}

Nó sẽ làm việc trên các biến công cộng và bảo vệ. Bạn có thể thêm nếu lỗi (! Isset ($ this -> {$ what})()

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