ควรใช้คลาสที่คงที่เทียบกับอินสแตนซ์


170

PHP เป็นภาษาโปรแกรมแรกของฉัน ฉันไม่สามารถคาดศีรษะได้เมื่อใช้คลาสที่คงที่และวัตถุที่สร้างอินสแตนซ์

ฉันรู้ว่าคุณสามารถทำซ้ำและคัดลอกวัตถุ อย่างไรก็ตามในทุกเวลาของฉันโดยใช้ php วัตถุหรือฟังก์ชั่นใด ๆ มักจะจบลงด้วยการกลับมาเป็นค่าเดียว (อาร์เรย์, สตริง, int) หรือโมฆะ

ฉันเข้าใจแนวคิดในหนังสือเช่นคลาสของตัวละครในวิดีโอเกม ทำสำเนาวัตถุรถยนต์และสร้างใหม่ให้เป็นสีแดงซึ่งทั้งหมดนั้นสมเหตุสมผล แต่สิ่งที่ไม่มีในแอปพลิเคชันใน php และเว็บแอป

ตัวอย่างง่ายๆ บล็อก. วัตถุใดของบล็อกที่จะใช้งานได้ดีที่สุดเป็นวัตถุแบบสแตติกหรืออินสแตนซ์ คลาส DB? ทำไมไม่ยกตัวอย่างวัตถุ db ในขอบเขตส่วนกลาง? ทำไมไม่ทำให้ทุกวัตถุคงที่แทน? แล้วประสิทธิภาพล่ะ

มันเป็นแค่สไตล์หรือไม่? มีวิธีที่เหมาะสมในการทำสิ่งนี้หรือไม่?

คำตอบ:


123

นี่เป็นคำถามที่น่าสนใจทีเดียวและคำตอบก็น่าสนใจเช่นกัน ^^

วิธีที่ง่ายที่สุดในการพิจารณาสิ่งต่าง ๆ อาจเป็น:

  • ใช้คลาส instanciated ที่แต่ละวัตถุมีข้อมูลด้วยตัวเอง (เช่นผู้ใช้มีชื่อ)
  • ใช้คลาสแบบสแตติกเมื่อเป็นเพียงเครื่องมือที่ทำงานกับสิ่งอื่น ๆ (เช่นตัวแปลงไวยากรณ์สำหรับรหัส BB เป็น HTML แต่ไม่มีชีวิตด้วยตนเอง)

(ใช่ฉันยอมรับจริงๆง่ายเกินไปจริงๆ ... )

สิ่งหนึ่งที่เกี่ยวกับวิธีการ / คลาสคงที่คือพวกเขาไม่ได้อำนวยความสะดวกในการทดสอบหน่วย (อย่างน้อยใน PHP แต่อาจเป็นภาษาอื่นด้วย)

อีกสิ่งหนึ่งที่เกี่ยวกับข้อมูลแบบคงที่คือมีอินสแตนซ์เดียวเท่านั้นที่มีอยู่ในโปรแกรมของคุณ: หากคุณตั้งค่า MyClass :: $ myData เป็นค่าบางค่ามันจะมีค่านี้และจะมีเฉพาะค่านี้เท่านั้น คุณจะสามารถมีผู้ใช้เพียงคนเดียว - ซึ่งไม่มากใช่ไหม?

สำหรับระบบบล็อกฉันจะพูดอะไรดี มีไม่มากที่ฉันจะเขียนเป็นคงที่จริง ๆ แล้วฉันคิดว่า; อาจเป็นคลาส DB-access แต่ท้ายที่สุดก็อาจจะไม่ได้ ^^


ดังนั้นโดยทั่วไปจะใช้วัตถุเมื่อทำงานกับสิ่งที่ไม่เหมือนใครเช่นภาพถ่ายผู้ใช้โพสต์ ฯลฯ และใช้สแตติกเมื่อมีความหมายสำหรับสิ่งทั่วไป
Robert Rocha

1
ถ้าพูดถึงผู้ใช้คุณมีผู้ใช้ที่ใช้งานเพียงคนเดียวในแต่ละคำขอ ดังนั้นการที่ผู้ใช้ที่ใช้งานของคำขอคงที่จะทำให้เข้าใจ
My1

69

สองเหตุผลหลักที่ต่อต้านการใช้วิธีการแบบคงที่คือ:

  • รหัสโดยใช้วิธีการคงที่ยากที่จะทดสอบ
  • รหัสโดยใช้วิธีการคงที่เป็นการยากที่จะขยาย

การมีวิธีการแบบสแตติกเรียกใช้ในวิธีอื่นนั้นจริง ๆ แล้วแย่กว่าการนำเข้าตัวแปรส่วนกลาง ใน PHP คลาสเป็นสัญลักษณ์สากลดังนั้นทุกครั้งที่คุณเรียกใช้เมธอดสแตติกคุณต้องพึ่งพาสัญลักษณ์สากล (ชื่อคลาส) นี่เป็นกรณีที่โลกกำลังชั่วร้าย ฉันมีปัญหากับวิธีการนี้กับส่วนประกอบบางส่วนของ Zend Framework มีคลาสที่ใช้การเรียกเมธอดแบบคงที่ (โรงงาน) เพื่อสร้างวัตถุ เป็นไปไม่ได้ที่ฉันจะจัดหาโรงงานอื่นให้กับอินสแตนซ์นั้นเพื่อให้ได้รับวัตถุแบบกำหนดเองคืนมา การแก้ปัญหานี้คือการใช้อินสแตนซ์และวิธีการอินสแตนซ์เท่านั้นและบังคับใช้ซิงเกิลตันและไลค์ในตอนเริ่มต้นของโปรแกรม

Miško Heveryผู้ทำงานในฐานะ Agile Coach ที่ Google มีทฤษฎีที่น่าสนใจหรือแนะนำว่าเราควรแยกเวลาการสร้างวัตถุออกจากเวลาที่เราใช้วัตถุนั้น ดังนั้นวงจรชีวิตของโปรแกรมจะแบ่งออกเป็นสอง ส่วนแรก ( main()วิธีที่เราจะพูด) ซึ่งดูแลการเดินสายวัตถุทั้งหมดในแอปพลิเคชันของคุณและส่วนที่ใช้งานได้จริง

ดังนั้นแทนที่จะมี:

class HttpClient
{
    public function request()
    {
        return HttpResponse::build();
    }
}

เราควรทำ:

class HttpClient
{
    private $httpResponseFactory;

    public function __construct($httpResponseFactory)
    {
        $this->httpResponseFactory = $httpResponseFactory;
    }

    public function request()
    {
        return $this->httpResponseFactory->build();
    }
}

จากนั้นในหน้าดัชนี / หลักเราจะทำ (นี่คือขั้นตอนการเดินสายวัตถุหรือเวลาในการสร้างกราฟของอินสแตนซ์ที่โปรแกรมจะใช้):

$httpResponseFactory = new HttpResponseFactory;
$httpClient          = new HttpClient($httpResponseFactory);
$httpResponse        = $httpClient->request();

แนวคิดหลักคือการแยกการพึ่งพาจากชั้นเรียนของคุณ วิธีนี้โค้ดสามารถขยายได้มากขึ้นและส่วนที่สำคัญที่สุดสำหรับฉันสามารถทดสอบได้ ทำไมการทดสอบจึงสำคัญกว่า เนื่องจากฉันไม่ได้เขียนรหัสห้องสมุดเสมอไปดังนั้นความสามารถในการขยายจึงไม่สำคัญ แต่ความสามารถในการทดสอบมีความสำคัญเมื่อฉันทำการปรับโครงสร้างใหม่ อย่างไรก็ตามรหัสที่ทดสอบได้มักจะให้รหัสที่ขยายได้ดังนั้นจึงไม่ใช่สถานการณ์จริงหรืออย่างใดอย่างหนึ่ง

Miško Hevery ยังสร้างความแตกต่างที่ชัดเจนระหว่างซิงเกิลและซิงเกิล (ที่มีหรือไม่มีทุน S) ความแตกต่างนั้นง่ายมาก ซิงเกิลที่มีตัวพิมพ์เล็ก "s" ถูกบังคับใช้โดยการเดินสายในดัชนี / main คุณสร้างอินสแตนซ์ของคลาสที่ไม่ใช้รูปแบบซิงเกิลและดูแลว่าคุณส่งอินสแตนซ์นั้นไปยังอินสแตนซ์อื่นที่ต้องการเท่านั้น ในทางกลับกันซิงเกิลที่มีตัวอักษร "S" เป็นการนำรูปแบบคลาสสิก (ต่อต้าน -) โดยทั่วไปทั่วโลกในการปลอมตัวซึ่งไม่ได้ใช้มากในโลก PHP ฉันยังไม่เห็นจุดใดจุดหนึ่ง ถ้าคุณต้องการให้การเชื่อมต่อฐานข้อมูลเดียวใช้โดยคลาสทั้งหมดของคุณจะดีกว่าที่จะทำเช่นนี้

$db = new DbConnection;

$users    = new UserCollection($db);
$posts    = new PostCollection($db);
$comments = new CommentsCollection($db);

โดยการทำข้างต้นเป็นที่ชัดเจนว่าเรามีซิงเกิลตันและเรามีวิธีที่ดีในการฉีดจำลองหรือต้นขั้วในการทดสอบของเรา มันน่าประหลาดใจที่การทดสอบหน่วยนำไปสู่การออกแบบที่ดีขึ้น แต่มันสมเหตุสมผลดีเมื่อคุณคิดว่าการทดสอบบังคับให้คุณคิดเกี่ยวกับวิธีที่คุณใช้รหัสนั้น

/**
 * An example of a test using PHPUnit. The point is to see how easy it is to
 * pass the UserCollection constructor an alternative implementation of
 * DbCollection.
 */
class UserCollection extends PHPUnit_Framework_TestCase
{
    public function testGetAllComments()
    {
        $mockedMethods = array('query');
        $dbMock = $this->getMock('DbConnection', $mockedMethods);
        $dbMock->expects($this->any())
               ->method('query')
               ->will($this->returnValue(array('John', 'George')));

        $userCollection = new UserCollection($dbMock);
        $allUsers       = $userCollection->getAll();

        $this->assertEquals(array('John', 'George'), $allUsers);
    }
}

สถานการณ์เดียวที่ฉันใช้ (และฉันใช้เพื่อเลียนแบบวัตถุต้นแบบ JavaScript ใน PHP 5.3) สมาชิกแบบคงที่คือเมื่อฉันรู้ว่าฟิลด์ที่เกี่ยวข้องจะมีค่าข้ามอินสแตนซ์เดียวกัน ณ จุดนี้คุณสามารถใช้คุณสมบัติคงที่และอาจเป็นวิธีการ getter / setter คู่คงที่ อย่างไรก็ตามอย่าลืมเพิ่มความเป็นไปได้สำหรับการแทนที่สมาชิกแบบคงที่ด้วยสมาชิกอินสแตนซ์ ยกตัวอย่างเช่น Zend Framework ถูกใช้คุณสมบัติคงที่เพื่อที่จะระบุชื่อของคลาสอะแดปเตอร์ DB Zend_Db_Tableที่ใช้ในกรณีของ มันใช้เวลาไม่นานเพราะฉันใช้มันดังนั้นมันอาจจะไม่เกี่ยวข้องอีกต่อไป แต่นั่นเป็นวิธีที่ฉันจำได้

วิธีสแตติกที่ไม่ได้จัดการกับคุณสมบัติสแตติกควรเป็นฟังก์ชัน PHP มีฟังก์ชั่นและเราควรใช้มัน


1
@Ionut ฉันไม่สงสัยเลยแม้แต่นิดเดียว ฉันตระหนักว่ามีคุณค่าในตำแหน่ง / บทบาทเช่นกัน อย่างไรก็ตามเช่นเดียวกับทุกอย่างที่เกี่ยวข้องกับ XP / Agile มันมีชื่อที่สกปรกมาก
jason

2
"การพึ่งพาการฉีด" ฉันเชื่อว่าเป็นคำที่ฟังดูซับซ้อนเกินไปสำหรับเรื่องนี้ จำนวนมากและจำนวนมากของการอ่านบนมันทั่ว SO และ google-land ตราบใดที่ "singletons" ดำเนินต่อไปนี่คือสิ่งที่ทำให้ฉันคิดว่า: slideshare.net/go_oh/ ......การพูดคุยเกี่ยวกับสาเหตุที่ PHP singletons ไม่เข้าท่า หวังก่อนี้เล็ก ๆ น้อย ๆ ให้กับคำถามเดิม :)
dudewad

22

ดังนั้นใน PHP แบบคงที่สามารถนำไปใช้กับฟังก์ชั่นหรือตัวแปร ตัวแปรแบบไม่คงที่ถูกเชื่อมโยงกับอินสแตนซ์เฉพาะของคลาส วิธีการไม่คงที่ทำหน้าที่ในอินสแตนซ์ของคลาส BlogPostดังนั้นขอให้ถึงระดับที่เรียกว่า

titleจะเป็นสมาชิกที่ไม่คงที่ มันมีชื่อของโพสต์บล็อกนั้น find_related()นอกจากนี้เรายังอาจจะมีวิธีการที่เรียกว่า มันไม่คงที่เพราะต้องการข้อมูลจากอินสแตนซ์เฉพาะของคลาสโพสต์บล็อก

คลาสนี้จะมีลักษณะดังนี้:

class blog_post {
    public $title;
    public $my_dao;

    public function find_related() {
        $this->my_dao->find_all_with_title_words($this->title);
    }
}

ในทางตรงกันข้ามการใช้ฟังก์ชั่นแบบคงที่คุณอาจเขียนคลาสดังนี้:

class blog_post_helper {
    public static function find_related($blog_post) {
         // Do stuff.
    }
}

ในกรณีนี้เนื่องจากฟังก์ชั่นเป็นแบบคงที่และไม่ได้ทำหน้าที่ในบล็อกโพสต์ใด ๆ คุณจะต้องผ่านการโพสต์บล็อกเป็นอาร์กิวเมนต์

นี่เป็นคำถามเกี่ยวกับการออกแบบเชิงวัตถุ ชั้นเรียนของคุณเป็นคำนามในระบบของคุณและฟังก์ชั่นที่ทำหน้าที่เป็นคำกริยา ฟังก์ชั่นแบบคงที่เป็นขั้นตอน คุณส่งผ่านวัตถุของฟังก์ชันเป็นอาร์กิวเมนต์


อัปเดต: ฉันต้องการเพิ่มด้วยว่าการตัดสินใจนั้นไม่ค่อยเกิดขึ้นระหว่างวิธีการแบบอินสแตนซ์และวิธีแบบสแตติกและอีกมากระหว่างการใช้คลาสและการใช้อาร์เรย์แบบเชื่อมโยง ตัวอย่างเช่นในแอปบล็อกคุณอ่านโพสต์บล็อกจากฐานข้อมูลและแปลงเป็นวัตถุหรือคุณปล่อยไว้ในชุดผลลัพธ์และถือว่าเป็นอาร์เรย์เชื่อมโยง จากนั้นคุณเขียนฟังก์ชันที่ใช้อาเรย์แบบเชื่อมโยงหรือรายการอาเรย์แบบเชื่อมโยงเป็นอาร์กิวเมนต์

ในสถานการณ์ OO คุณเขียนวิธีการในBlogPostชั้นเรียนของคุณที่ดำเนินการกับแต่ละโพสต์และคุณเขียนวิธีการคงที่ที่ดำเนินการกับคอลเลกชันของโพสต์


4
คำตอบนี้ค่อนข้างดีโดยเฉพาะอย่างยิ่งกับการอัปเดตที่คุณทำเพราะนั่นคือเหตุผลที่ฉันลงเอยกับคำถามนี้ ฉันเข้าใจการทำงานของ "::" เทียบกับ "$ this" แต่เมื่อคุณเพิ่มลงในบัญชีตัวอย่างที่คุณได้รับจากการแยกโพสต์บล็อกจากฐานข้อมูลในอาเรย์แบบเชื่อมโยง .. มันเพิ่มมิติใหม่ทั้งหมดนั่นคือ ในน้ำเสียงพื้นฐานของคำถามนี้
Gerben Jacobs

นี่เป็นหนึ่งในคำตอบที่ดีที่สุดในทางปฏิบัติ (เมื่อเทียบกับทางทฤษฎี) สำหรับคำถาม PHP ที่ถูกถามมากนี้ภาคผนวกมีประโยชน์มาก ฉันคิดว่านี่เป็นคำตอบที่โปรแกรมเมอร์ PHP จำนวนมากกำลังมองหา upvoted!
ajmedway

14

มันเป็นแค่สไตล์หรือไม่?

ทางยาวใช่ คุณสามารถเขียนโปรแกรมเชิงวัตถุที่ดีได้อย่างสมบูรณ์แบบโดยไม่ต้องใช้สมาชิกแบบคงที่ ในความเป็นจริงบางคนจะยืนยันว่าสมาชิกคงเป็นมลทินในสถานที่แรก ฉันขอแนะนำว่า - เป็นผู้เริ่มต้นใน oop - คุณพยายามหลีกเลี่ยงสมาชิกแบบคงที่ทั้งหมดเข้าด้วยกัน มันจะบังคับให้คุณไปในทิศทางของการเขียนในวัตถุที่มุ่งเน้นมากกว่ารูปแบบขั้นตอน


13

ฉันมีวิธีการที่แตกต่างกันสำหรับคำตอบส่วนใหญ่ที่นี่โดยเฉพาะเมื่อใช้ PHP ฉันคิดว่าคลาสทั้งหมดควรจะคงที่จนกว่าคุณจะมีเหตุผลที่ดีว่าทำไมไม่ เหตุผลบางประการ "ทำไมไม่" คือ:

  • คุณต้องมีหลายอินสแตนซ์ของคลาส
  • คลาสของคุณจะต้องขยายออกไป
  • บางส่วนของรหัสของคุณไม่สามารถแบ่งปันตัวแปรระดับกับส่วนอื่น ๆ

ขอยกตัวอย่างหนึ่ง เนื่องจากสคริปต์ PHP ทุกตัวสร้างโค้ด HTML กรอบงานของฉันจึงมีคลาส html writer สิ่งนี้ทำให้มั่นใจได้ว่าจะไม่มีคลาสอื่นใดที่จะพยายามเขียน HTML เนื่องจากเป็นงานเฉพาะที่ควรรวมอยู่ในคลาสเดียว

โดยปกติแล้วคุณจะใช้คลาส html ดังนี้:

html::set_attribute('class','myclass');
html::tag('div');
$str=html::get_buffer();

ทุกครั้งที่มีการเรียกใช้ get_buffer () มันจะรีเซ็ตทุกอย่างเพื่อให้คลาสถัดไปเพื่อใช้ตัวเขียน html เริ่มขึ้นในสถานะที่รู้จัก

คลาสสแตติกของฉันทั้งหมดมีฟังก์ชัน init () ซึ่งจำเป็นต้องเรียกใช้ก่อนที่จะใช้คลาสเป็นครั้งแรก นี่คือการประชุมมากกว่าความจำเป็น

ทางเลือกของคลาสสแตติกในกรณีนี้คือยุ่ง คุณไม่ต้องการให้ทุกคลาสที่ต้องเขียน html เล็กน้อยเพื่อจัดการอินสแตนซ์ของ html writer

ตอนนี้ฉันจะให้ตัวอย่างเมื่อไม่ใช้คลาสคงที่ คลาสฟอร์มของฉันจัดการรายการองค์ประกอบฟอร์มเช่นอินพุตข้อความรายการดร็อปดาวน์และอื่น ๆ โดยปกติจะใช้ดังนี้:

$form = new form(stuff here);
$form->add(new text(stuff here));
$form->add(new submit(stuff here));
$form->render(); // Creates the entire form using the html class

ไม่มีวิธีที่คุณสามารถทำได้กับคลาสแบบสแตติกโดยเฉพาะอย่างยิ่งเมื่อพิจารณาว่าตัวสร้างบางตัวของแต่ละคลาสที่เพิ่มเข้ามาทำงานหนักมาก นอกจากนี้ห่วงโซ่ของการสืบทอดสำหรับองค์ประกอบทั้งหมดนั้นค่อนข้างซับซ้อน ดังนั้นนี่เป็นตัวอย่างที่ชัดเจนที่ไม่ควรใช้คลาสแบบสแตติก

คลาสยูทิลิตี้ส่วนใหญ่เช่นสตริงการแปลง / การจัดรูปแบบเป็นตัวเลือกที่ดีสำหรับการเป็นคลาสสแตติก กฎของฉันนั้นง่าย: ทุกอย่างคงที่ใน PHP เว้นแต่จะมีเหตุผลหนึ่งว่าทำไมไม่ควร


คุณสามารถเขียนตัวอย่างของต่ำกว่าจุดที่เป็น "อะไหล่ของรหัสของคุณไม่สามารถใช้ร่วมตัวแปรชั้นเรียนกับชิ้นส่วนอื่น ๆ" #JG Estiot
khurshed alam

10

"การมีวิธีการสแตติกเรียกภายในวิธีอื่นนั้นแย่กว่าการนำเข้าตัวแปรทั่วโลก" (กำหนดว่า "แย่กว่า") ... และ "วิธีการคงที่ที่ไม่จัดการกับคุณสมบัติคงที่ควรเป็นฟังก์ชั่น"

เหล่านี้เป็นทั้งงบกวาดสวย ถ้าฉันมีชุดของฟังก์ชั่นที่เกี่ยวข้องกับหัวข้อ แต่ข้อมูลอินสแตนซ์นั้นไม่เหมาะสมโดยสิ้นเชิงฉันก็อยากให้พวกมันนิยามไว้ในคลาสและไม่ใช่แต่ละอันในเนมสเปซส่วนกลาง ฉันแค่ใช้กลไกที่มีอยู่ใน PHP5 เพื่อ

  • ให้ namespace ทั้งหมดแก่พวกเขา - หลีกเลี่ยงการปะทะกันของชื่อ
  • ทำให้พวกเขาอยู่ด้วยกันแทนที่จะกระจัดกระจายในโครงการผู้พัฒนารายอื่น ๆ สามารถค้นหาสิ่งที่มีอยู่แล้วได้ง่ายขึ้นและมีโอกาสน้อยที่จะคิดค้นล้อใหม่
  • ให้ฉันใช้คลาส consts แทนการกำหนดทั่วโลกสำหรับค่าเวทมนตร์ใด ๆ

เป็นเพียงวิธีที่สะดวกในการบังคับใช้การติดต่อกันที่สูงขึ้นและการมีเพศสัมพันธ์ต่ำ

และ FWIW - ไม่มีสิ่งนั้นอย่างน้อยใน PHP5 เป็น "คลาสคงที่"; วิธีการและคุณสมบัติสามารถคงที่ เพื่อป้องกันการสร้างอินสแตนซ์ของคลาสเราสามารถประกาศนามธรรมได้เช่นกัน


2
"เพื่อป้องกันไม่ให้เกิดการอินสแตนซ์ของคลาสเราสามารถประกาศนามธรรมได้เช่นกัน" - ฉันชอบมันมาก ก่อนหน้านี้ฉันเคยอ่านเกี่ยวกับคนที่สร้าง __construct () ฟังก์ชั่นส่วนตัว แต่ฉันคิดว่าถ้าฉันต้องการฉันก็น่าจะใช้ abstract
Kavi Siegel

7

ก่อนอื่นให้ถามตัวเองว่าวัตถุนี้จะนำเสนออะไร? อินสแตนซ์ของวัตถุนั้นดีสำหรับการทำงานกับชุดข้อมูลแบบไดนามิกแยกกัน

ตัวอย่างที่ดีคือ ORM หรือเลเยอร์ abstraction ฐานข้อมูล คุณอาจมีการเชื่อมต่อฐานข้อมูลหลายรายการ

$db1 = new Db(array('host' => $host1, 'username' => $username1, 'password' => $password1));
$db2 = new Db(array('host' => $host2, 'username' => $username2, 'password' => $password2));

การเชื่อมต่อทั้งสองตอนนี้สามารถทำงานได้อย่างอิสระ:

$someRecordsFromDb1 = $db1->getRows($selectStatement);
$someRecordsFromDb2 = $db2->getRows($selectStatement);

ขณะนี้ภายในแพ็คเกจ / ไลบรารีนี้อาจมีคลาสอื่นเช่น Db_Row เป็นต้นเพื่อแสดงแถวเฉพาะที่ส่งคืนจากคำสั่ง SELECT หากคลาส Db_Row นี้เป็นคลาสแบบสแตติกนั่นจะเป็นการสมมติว่าคุณมีข้อมูลแถวเดียวในฐานข้อมูลเดียวและเป็นไปไม่ได้ที่จะทำสิ่งที่อินสแตนซ์ของวัตถุทำได้ ด้วยอินสแตนซ์ตอนนี้คุณสามารถมีได้ไม่ จำกัด จำนวนแถวในตารางไม่ จำกัด จำนวนในฐานข้อมูลไม่ จำกัด จำนวน ข้อ จำกัด เพียงอย่างเดียวคือฮาร์ดแวร์ของเซิร์ฟเวอร์;)

ตัวอย่างเช่นถ้าเมธอด getRows บนอ็อบเจ็กต์ Db ส่งคืนอาร์เรย์ของออบเจ็กต์ Db_Row ตอนนี้คุณสามารถทำงานในแต่ละแถวโดยแยกจากกัน:

foreach ($someRecordsFromDb1 as $row) {
    // change some values
    $row->someFieldValue = 'I am the value for someFieldValue';
    $row->anotherDbField = 1;

    // now save that record/row
    $row->save();
}

foreach ($someRecordsFromDb2 as $row) {
    // delete a row
    $row->delete();
}

ตัวอย่างที่ดีของคลาสสแตติกจะเป็นสิ่งที่จัดการตัวแปรรีจิสตรีหรือตัวแปรเซสชันเนื่องจากจะมีเพียงหนึ่งรีจีสทรีหรือหนึ่งเซสชันต่อผู้ใช้

ในส่วนหนึ่งของใบสมัครของคุณ:

Session::set('someVar', 'toThisValue');

และในอีกส่วนหนึ่ง:

Session::get('someVar'); // returns 'toThisValue'

เนื่องจากมีเพียงผู้ใช้หนึ่งรายต่อเซสชันเท่านั้นจึงไม่มีประเด็นในการสร้างอินสแตนซ์สำหรับเซสชัน

ฉันหวังว่าสิ่งนี้จะช่วยได้พร้อมกับคำตอบอื่น ๆ เพื่อช่วยให้ชัดเจนขึ้น ในฐานะที่เป็นบันทึกด้านข้างให้ตรวจสอบ "การทำงานร่วมกัน " และ "การมีเพศสัมพันธ์ " พวกเขาร่างแนวทางปฏิบัติที่ดีและดีบางอย่างที่จะใช้เมื่อเขียนรหัสของคุณที่ใช้กับภาษาการเขียนโปรแกรมทั้งหมด


6

หากคลาสของคุณเป็นแบบคงที่หมายความว่าคุณไม่สามารถส่งวัตถุไปยังคลาสอื่น ๆ (เนื่องจากไม่มีตัวอย่างที่เป็นไปได้) ดังนั้นหมายความว่าคลาสทั้งหมดของคุณจะใช้คลาสแบบคงที่โดยตรงซึ่งหมายความว่าขณะนี้โค้ดของคุณอยู่คู่กับคลาสอย่างแน่นหนา .

การมีเพศสัมพันธ์อย่างแน่นหนาทำให้โค้ดของคุณสามารถนำกลับมาใช้ใหม่ได้น้อยบอบบางและมีแนวโน้มที่จะเกิดข้อบกพร่อง คุณต้องการหลีกเลี่ยงคลาสสแตติกเพื่อส่งผ่านอินสแตนซ์ของคลาสไปยังคลาสอื่น

และใช่นี่เป็นเพียงหนึ่งในเหตุผลอื่น ๆ ที่บางคนกล่าวถึงแล้ว


3

โดยทั่วไปคุณควรใช้ตัวแปรสมาชิกและฟังก์ชั่นสมาชิกเว้นแต่จะต้องมีการแชร์ระหว่างทุกกรณีหรือเว้นแต่คุณจะสร้างซิงเกิล การใช้ข้อมูลสมาชิกและฟังก์ชั่นสมาชิกช่วยให้คุณสามารถนำฟังก์ชั่นของคุณกลับมาใช้ซ้ำสำหรับข้อมูลที่แตกต่างกันหลายชิ้นในขณะที่คุณสามารถมีสำเนาของข้อมูลที่คุณใช้งานได้หากคุณใช้ข้อมูลและฟังก์ชันคงที่ นอกจากนี้แม้ว่าจะไม่สามารถใช้ได้กับ PHP ฟังก์ชั่นคงที่และข้อมูลนำไปสู่รหัสไม่ได้ reentrant ในขณะที่ข้อมูลระดับอำนวยความสะดวก reentrancy


3

ฉันอยากจะบอกว่ามีบางกรณีที่ฉันต้องการตัวแปรคงที่ - ในแอปพลิเคชันข้ามภาษา คุณสามารถมีคลาสที่คุณส่งผ่านภาษาไปยัง (เช่น $ _SESSION ['language']) และในทางกลับกันก็จะเข้าถึงคลาสอื่น ๆ ที่ได้รับการออกแบบโดย:

Srings.php //The main class to access
StringsENUS.php  //English/US 
StringsESAR.php  //Spanish/Argentina
//...etc

Using Strings :: getString ("somestring") เป็นวิธีที่ดีในการสรุปการใช้ภาษาของคุณจากแอปพลิเคชันของคุณ คุณสามารถทำมันได้ตามที่คุณต้องการ แต่ในกรณีนี้การที่แต่ละไฟล์สตริงมีค่าคงที่ที่มีค่าสตริงที่เข้าถึงได้โดยคลาส Strings ทำงานได้ค่อนข้างดี

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.