ทำไมตัวสร้างควรเป็นคลาสภายในแทนที่จะเป็นไฟล์คลาสของตัวเอง


24

Builder Patternตัวอย่างมากมายทำให้Builderคลาสภายในของวัตถุที่สร้างขึ้น

ทำให้รู้สึกบางอย่างเพราะมันบ่งบอกถึงสิ่งที่Builderสร้าง อย่างไรก็ตามในภาษาที่พิมพ์แบบคงที่เรารู้ว่าสิ่งที่Builderสร้าง

ในทางตรงกันข้ามถ้าBuilderเป็นระดับชั้นที่คุณควรจะรู้ว่าสิ่งที่ชั้นสร้างโดยไม่ได้มองภายในของBuilderBuilder

นอกจากนี้การมีตัวสร้างเป็นคลาสภายในจะลดจำนวนของการนำเข้าเนื่องจากสามารถอ้างอิงโดยคลาสภายนอก - หากคุณสนใจสิ่งนั้น

แล้วมีตัวอย่างการปฏิบัติที่Builderอยู่ในแพคเกจเดียวกัน StringBuilderแต่ไม่ได้เป็นระดับชั้นเช่น คุณรู้ว่าBuilder ควรสร้างStringเพราะมันมีชื่อดังนั้น

ที่ถูกกล่าวว่าเหตุผลที่ดีเท่านั้นที่ฉันสามารถคิดในการสร้างBuilderชั้นในคือคุณรู้ว่าสิ่งที่ชั้น ' Builderคือโดยไม่ทราบชื่อของมันหรืออาศัยการประชุมการตั้งชื่อ ตัวอย่างเช่นถ้าStringBuilderเป็นชั้นในของStringฉันอาจจะรู้ว่ามันมีอยู่เร็วกว่าที่ฉันทำ (เก็งกำไร)

มีเหตุผลอื่นที่จะทำให้Builderชั้นในหรือไม่เพียงแค่ลงไปที่การตั้งค่าและพิธีกรรม?

คำตอบ:


30

ฉันคิดว่าเหตุผลในการทำเช่นนี้คือเพื่อให้ชนชั้นภายใน (ผู้สร้าง) สามารถเข้าถึงสมาชิกส่วนตัวของชั้นเรียนที่กำลังสร้าง

จากhttp://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

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

...

พิจารณาคลาสระดับบนสุดสองคลาสคือ A และ B โดยที่ B ต้องการเข้าถึงสมาชิกของ A ที่จะถูกประกาศเป็นส่วนตัว โดยการซ่อนคลาส B ภายในคลาส A สมาชิกของ A สามารถถูกประกาศเป็นส่วนตัวและ B สามารถเข้าถึงพวกเขาได้

...

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

นี่คือรหัสเพื่อพยายามแสดงสิ่งนี้:

class Example {

    private int x;

    public int getX() { return this.x; }

    public static class Builder {

        public Example Create() {
            Example instance = new Example();
            instance.x = 5; // Builder can access Example's private member variable
            return instance;
        }
    }
}

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


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

1
@Nathanial ไม่ได้ทั้งหมดตัวแปรเช่นภาคเอกชนยังสามารถเข้าถึง: ideone.com/7DyjDR
อมร

1
@ นาธาเนียล: ใช่ แต่ผู้สร้างไม่ได้จัดการชั้นเรียน; มันกำลังจัดการกับวัตถุของคลาสที่ตัวสร้างมีอินสแตนซ์
Robert Harvey

@ มอนฉันเห็นสิ่งที่คุณทำที่นั่น ขอบคุณสำหรับคำอธิบาย!
ธาเนียล

โดยเฉพาะมันช่วยให้ผู้สร้างเข้าถึงการสร้างส่วนตัวสำหรับชั้นเรียนที่ถูกสร้างขึ้นช่วยให้ชั้นที่จะไม่เปลี่ยนรูป (ทุกสาขาสุดท้าย) และสามารถใช้งานได้ทันทีผ่านการสร้าง
Matthew McPeak

1

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


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