ทำไมเราต้องมีตัวแปรส่วนตัว


210

ทำไมเราต้องการตัวแปรส่วนตัวในคลาส?

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

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

  1. ตัวแปรส่วนตัวช่วยป้องกันอะไรได้บ้าง

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

  3. ควรกำหนดให้มีตัวแปรสาธารณะในสถานการณ์ใด


9
คำถามของคุณฟังดูเหมือนผู้ไม่เชื่อเรื่องภาษา แต่คุณติดแท็กเป็น java และ c ++ หากคุณสนใจในมุมมองจากนอกทั้งสองภาษาคุณควรพูดเช่นนั้น
James

8
สำหรับบันทึกการสร้างวิธีการส่วนตัวไม่เพิ่ม "ความปลอดภัย" ส่วนอื่น ๆ ของแอปพลิเคชันของคุณยังสามารถเข้าถึงสมาชิกส่วนตัวโดยใช้การสะท้อน
kba

3
การใช้งานและความแตกต่างของตัวแปรส่วนตัวและสาธารณะและทำไมเรามีพวกเขาสามารถเข้าใจได้ในบริบทของหลักการเชิงวัตถุทั่วไป ไม่สามารถแยกเข้าใจได้ คุณอาจต้องมองจากมุมมองนั้นสิ่งต่าง ๆ อาจชัดเจนขึ้น
Nazar Merza

1
ความเป็นไปได้ที่ซ้ำกันของGetters and Setters Justified
Tulains Córdova

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

คำตอบ:


307

มันไม่ใช่เรื่องของความไว้วางใจ แต่เป็นเรื่องของการจัดการความซับซ้อน

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

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

ข้อดีอีกประการคือเกี่ยวข้องกับแนวคิดของ 'การแต่งงานกัน' สมาชิกสาธารณะmของชั้นAที่ถูกใช้โดยชั้นอื่นBแนะนำพึ่งพา: ถ้าคุณเปลี่ยนmในAคุณยังมีการตรวจสอบการใช้งานของในm Bที่แย่ไปกว่านั้นยังไม่มีสิ่งใดในชั้นเรียนที่Aจะบอกคุณว่าmกำลังใช้งานอยู่ที่ไหนดังนั้นคุณต้องค้นหาจาก codebase ทั้งหมดอีกครั้ง หากเป็นห้องสมุดที่คุณกำลังเขียนคุณต้องทำให้แน่ใจว่ามีรหัสภายนอกโครงการของคุณไม่พังเพราะการเปลี่ยนแปลงของคุณ ในทางปฏิบัติห้องสมุดมักจะยึดติดกับลายเซ็นต์วิธีดั้งเดิมของพวกเขาให้นานที่สุดเท่าที่จะเป็นไปได้ไม่ว่าจะเจ็บปวดเพียงใด ตรงกันข้ามกับสมาชิกส่วนตัวคุณสามารถแยกการพึ่งพาได้ทันที - พวกเขาไม่สามารถเข้าถึงได้จากภายนอกดังนั้นการพึ่งพาทั้งหมดจึงอยู่ในชั้นเรียน

ในบริบทนี้ "โปรแกรมเมอร์อื่น ๆ " รวมถึงอนาคตและองค์ประกอบที่ผ่านมาของคุณ ตอนนี้คุณรู้แล้วว่าคุณไม่ควรทำสิ่งนี้กับตัวแปร Y ของคุณ แต่คุณต้องลืมไปสามเดือนแล้วเมื่อลูกค้าต้องการให้คุณใช้คุณสมบัติบางอย่างอย่างเร่งด่วนและคุณสงสัยว่าทำไมการแบ่ง X Y ในรูปแบบที่คลุมเครือ

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


24
+1 สำหรับการเข้าถึงหัวใจของปัญหาแม้ว่าฉันพบว่ารหัสของฉันง่ายต่อการรักษาเมื่อฉันหยุดผ่านการวนรอบเพียงเพื่อให้แน่ใจว่าตัวแปรที่ใช้บ่อยอยู่ส่วนตัว ตรวจสอบว่ามีข้อผิดพลาดที่อาจเกิดขึ้นในอนาคต แต่ก็ 60 สายน้อยของรหัสที่จะลอดผ่านและตัวแปรน้อยลงและฟังก์ชั่นในการบูต;)
เจฟฟรีย์สวีนีย์

48
จอกศักดิ์สิทธิ์ของคอมพิวเตอร์สมัยใหม่กำลังลดความซับซ้อนลง

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

2
ตรงนั้น เมื่อผู้คนได้ยิน "การซ่อนข้อมูล" พวกเขาคิดว่าพวกเขาควรใช้ตัวแปรส่วนตัวสำหรับสิ่งต่าง ๆ เช่นคีย์การเข้ารหัสข้อมูลประจำตัวของฐานข้อมูล ฯลฯ
Wayne Werner

2
@AdamZerner เห็น "บอกอย่าถาม" ( martinfowler.com/bliki/TellDontAsk.html ) เกี่ยวกับการมี getters / setters ในตอนแรก - แต่อย่างอื่นใช่เพราะคุณควรเปลี่ยนการเป็นตัวแทนของค่าภายในได้ตลอดเวลา ที่คุณต้องการ. และเช่นเคยมีข้อยกเว้น ... (เช่น DTOs)
doubleYou

111

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

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

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


24
IMO เกี่ยวกับการสื่อสารระหว่างผู้เขียน lib และผู้บริโภค lib อินเตอร์เฟซที่สาธารณะเช่น "ใช้นี้" และไพร่พลเป็นเหมือน "ไม่ได้ใช้ว่า" ยกเว้นว่าใน Java คุณจริงๆไม่สามารถใช้มันโดยบังเอิญถ้าทำให้มันส่วนตัวดังนั้นจึงเป็นเรื่องที่ปลอดภัยและชัดเจนวิธีการที่
chakrit

5
@ จักรกฤษณ์และคนอื่น ๆ : โปรดทราบว่าผู้ที่ใช้งานฟิลด์และวิธีการส่วนตัวของคุณสามารถทำได้ (ผ่านการสะท้อนกลับ) privateน้อยกว่า "ไม่ได้มีจุดประสงค์เพื่อความปลอดภัยเป็นหลัก" แต่ก็ไม่ได้ให้ "ความปลอดภัย" ในการพูดถึง มันเป็นเพียงคำใบ้ที่แข็งแกร่ง (ส่งผ่านคอมไพเลอร์) ไม่ให้เข้าถึง

@delnan บันทึกวลี "โดยบังเอิญ" ใช่บางทีฉันควรจะชัดเจนกว่านี้
chakrit

@ จักรกฤษใช่ฉันไม่ได้ตั้งใจจะบอกว่าคุณผิด ฉันแค่อยากจะโปรโมตประเด็นนั้น

1
@delnan: ฟิลด์ส่วนตัวมีความปลอดภัยในบางภาษา ตัวอย่างเช่นดูคำตอบของ Eric Lippert สำหรับระดับการเข้าถึงและตัวดัดแปลง (ส่วนตัวปิดผนึก ฯลฯ ) เพื่อจุดประสงค์ด้านความปลอดภัยใน C # หรือไม่ .
Brian

25

คำหลักที่นี่คือEncapsulation ใน OOP คุณต้องการใช้ตัวแปรส่วนตัวเพื่อบังคับใช้การห่อหุ้มที่เหมาะสมของวัตถุ / คลาสของคุณ

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

  1. ดังนั้นตัวแปรส่วนตัวทำให้แน่ใจว่าตัวแปรที่เกี่ยวข้องยังคงอยู่ในคลาสที่กำหนดเท่านั้น หากคุณต้องการเปลี่ยนการเปลี่ยนแปลงนั้นเป็นแบบโลคัลสำหรับคลาสเอง

  2. ใน lanugages แบบดั้งเดิมเช่น C ++ หรือ Java คุณมักจะทำให้ทุกอย่างเป็นส่วนตัวและเข้าถึงได้โดย getters และ setters ที่เกี่ยวข้องเท่านั้น ไม่จำเป็นต้องตัดสินใจมากนัก

  3. บางครั้ง f.ex ในโครงสร้าง C ++ คุณต้องมีคลาสเป็นวิธีการจัดกลุ่มสิ่งต่าง ๆ เข้าด้วยกันเท่านั้น ตัวอย่างเช่นพิจารณาคลาส Vector ที่มีxและyแอตทริบิวต์เท่านั้น ในกรณีดังกล่าวคุณอาจอนุญาตให้เข้าถึงคุณลักษณะเหล่านี้โดยตรงโดยประกาศให้เป็นสาธารณะ โดยเฉพาะอย่างยิ่งคุณไม่ต้องสนใจว่าโค้ดบางส่วนนอกปรับเปลี่ยนวัตถุของคลาสของคุณโดยการเขียนค่าใหม่โดยตรงในหรือxy

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

ในภาษาเหล่านั้นคุณจะได้รับสิ่งที่เรียกว่าหลักการเข้าถึงแบบเดียวกันโดยที่ deliberatly หนึ่งไม่แยกแยะวิธีการเช่น getters และ setters แต่ให้การเข้าถึงตัวแปร / ฟังก์ชั่นโดยตรง ดังนั้นคุณอาจบอกว่าการประกาศส่วนตัวค่อนข้างเป็นที่นิยมมากในสถานการณ์เชิงวัตถุ

สิ่งนี้ยังแสดงให้เห็นว่าการขยายความรู้ของคุณเพื่อรวมเขตข้อมูลอื่นทำให้คุณดูแนวคิดที่มีอยู่ในวิธีการใหม่ทั้งหมด


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

7

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

ตัวอย่างเช่นภาษาต้นแบบเช่น Javascript สามารถอนุญาตให้ผู้ใช้พลาสเตอร์กับตัวแปรตามที่พวกเขาเห็นว่าเหมาะสม:

function SomeObject() {
    this.a = 2; //Public (well, actually protected) variable

    this.showA = function() {
        alert(this.a);
    }
}

//Some lines down...

var obj = new SomeObject();
obj.a = 3;
obj.showA(); //Will alert 3. Uh oh!

หากตัวแปรนั้นเป็นแบบส่วนตัวก็จะไม่สามารถเปลี่ยนจากภายนอกได้:

function SomeObject() {
    var a = 2; //Private variable

    this.showA = function() {
        alert(a);
    }
}

//Some lines down...

var obj = new SomeObject();
obj.a = 3;
obj.showA(); //Will alert 2

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

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

ควรใช้ตัวแปรสาธารณะเมื่อวัตถุ / ฟังก์ชั่นเข้าถึงวัตถุ / ฟังก์ชั่นอื่น ๆ เนื่องจากตามกฎแล้วตัวแปรส่วนตัวไม่สามารถทำได้ คุณอาจมีตัวแปรสาธารณะไม่กี่ถึงหลายตัวแปรและมันก็ไม่ได้เลวร้ายถ้าใช้อย่างถูกต้อง


ไม่ชัดเจนว่าทำไมการแจ้งเตือน 3 จึงเป็น "uh oh!" ในกรณีนี้. บางทีนั่นอาจเป็นสิ่งที่โปรแกรมเมอร์ต้องการ
immibis

@immibis บางทีและบางทีฉันควรจะอธิบายเพิ่มเติมในคำตอบ แต่การเข้าถึงคุณสมบัติสามารถเปิดประตูสำหรับการละเมิดหลักการ OOP เช่นหลักการเปิดปิดหรือ LoD เนื่องจากคุณอาจเปิดเผยรายละเอียดการใช้งาน 'ถึงจุดของคุณมันขึ้นอยู่กับสิ่งที่เป็นคุณสมบัติ ภาษาส่วนใหญ่ใช้อ็อบเจกต์เป็นข้อมูลอ้างอิงและเมื่อการอ้างอิงของออบเจ็กต์ผ่านไปมาและเพื่อน ๆ ของ devs เปลี่ยนคุณสมบัติอย่างเงียบ ๆ IMO ง่ายขึ้นและสามารถขยายได้มากขึ้นถ้าคุณมีอินสแตนซ์ของคลาส
เจฟฟรีย์สวีนีย์

7

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

ไม่ใช่ว่าภาษาที่ไม่มีความเป็นส่วนตัวทำให้การออกแบบเป็นไปไม่ได้ แต่มีโอกาสน้อยกว่า แทนที่จะถูกพร้อมท์ให้เขียนสิ่งที่ต้องการfoo.getBar()คนมีแนวโน้มที่จะคิดทะเยอทะยานไม่จำเป็นเพราะมันง่ายต่อการเขียนแต่แล้วก็ตัดสินใจที่ไม่ได้มาเยือนเมื่อคุณภายหลังจบลงด้วยการก่ออีกต่อไปเช่นfoo.bar obj.container[baz].foo.barโปรแกรมเมอร์ที่ไม่เคยทำงานด้วยภาษาที่เข้มงวดอาจไม่เห็นว่ามีอะไรผิดปกติ

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


3

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

ตัวแปรส่วนใหญ่จัดเตรียมสถานะของวัตถุและตัวแปรส่วนตัวป้องกันผู้อื่นไม่ให้เข้าไปในและเปลี่ยนสถานะของวัตถุ


5
มุมมองที่แคบเกินไปของหัวเรื่อง มีหลายกรณีที่มีการรับประกันการเข้าถึงข้อมูลสาธารณะแม้จะเป็นที่ต้องการมากกว่าก็ตาม
Roland Tepp

มีใครสามารถออกแบบวัตถุที่รัฐไม่สามารถเปลี่ยนแปลงได้ (วัตถุที่ไม่เปลี่ยนรูป) แต่นี่ไม่ใช่กฎทั่วไปที่ใช้กับทุกคลาส จากประสบการณ์ของฉันวัตถุส่วนใหญ่ทำให้ผู้อื่นสามารถเปลี่ยนสถานะของวัตถุได้ง่าย
David K

1
@DavidK บางทีสิ่งที่ bbb หมายถึงคือ "ตัวแปรส่วนตัวป้องกันไม่ให้ผู้อื่นเข้ามาและเปลี่ยนแปลงสถานะของวัตถุอย่างไม่เจาะจง " วิธีการสาธารณะอาจเปลี่ยนสถานะส่วนตัวของวัตถุ แต่เฉพาะในวิธีที่จำเป็นและสอดคล้องกับการทำงานของวัตถุ
Max Nanasy

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

2
  • ตัวแปรส่วนตัวช่วยป้องกันอะไรได้บ้าง

มันเกี่ยวกับการทำให้มันชัดเจนว่าคุณสมบัติและวิธีการที่มีอินเตอร์เฟซและสิ่งที่เป็นฟังก์ชั่นหลักที่แท้จริง วิธีการ / คุณสมบัติสาธารณะเป็นเรื่องเกี่ยวกับรหัสอื่น ๆ มักจะรหัสของนักพัฒนาอื่น ๆ โดยใช้วัตถุของคุณ ฉันไม่เคยทำงานกับทีมงานมากกว่า 100+ คนในโครงการเดียวกัน แต่จากประสบการณ์ของฉันอาจมีทีมงาน 3-5 คนที่มีนักพัฒนาคนอื่น ๆ ถึง 20 คนที่ใช้สิ่งที่ฉันเขียนความกังวลอื่น ๆ ดูเหมือนจะโง่

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

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

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

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

  • ควรกำหนดให้มีตัวแปรสาธารณะในสถานการณ์ใด

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


IMHO ไม่มีอะไรผิดปกติโดยเฉพาะอย่างยิ่งเมื่อมีชั้นเรียนสาธารณะที่มีวัตถุประสงค์เพียงอย่างเดียวคือการเปิดเผยตัวแปรสาธารณะ อันที่จริง JVM มีจำนวนของตัวในชั้นเรียนเพื่อวัตถุประสงค์ที่: int[], double[], Object[]ฯลฯ หนึ่งควร แต่ต้องระวังให้มากเกี่ยวกับวิธีการหนึ่งที่ exposes อินสแตนซ์ของชั้นดังกล่าว ความหมายของvoid CopyLocationTo(Point p);[การยอมรับPointจากผู้โทร] เป็นที่ชัดเจนกว่าPoint location()เพราะมันไม่ชัดเจนสิ่งที่มีผลจะมีเกี่ยวกับสถานที่ตั้งของPoint pt = foo.location(); pt.x ++; foo
supercat

2

ดูโพสต์ของฉันนี้เพื่อคำถามที่เกี่ยวข้องในดังนั้น

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

การกำหนดขอบเขตสมาชิกที่เหมาะสมจึงเป็นกุญแจสำคัญในรหัสการทำเอกสารด้วยตนเอง


2

ฉันจะพูดถึงคุณค่าของการห่อหุ้มจากมุมมองที่แตกต่างกันโดยใช้ตัวอย่างจริง ค่อนข้างนานมาแล้ว (80 ต้น) เกมที่เขียนขึ้นสำหรับ Radio Shack Color Computer เรียกว่า Dungeons of Daggorath เมื่อหลายปีก่อน Richard Hunerlach นำส่งจากรายการแอสเซมเบลอร์กระดาษไปยัง C / C ++ ( http://mspencer.net/daggorath/dodpcp.html ) ในเวลาต่อมาฉันได้รับรหัสและเริ่มคิดใหม่เพื่อให้ encapsulation ดีขึ้น ( http://dbp-consulting.com/stuff/ )

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

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

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

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


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

น่าเสียดายที่เวอร์ชันที่ได้รับการ
รีโหลด

2

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

พิจารณาค่าคงที่แบบส่วนตัว - พวกเขาไม่ควรมีค่าความลับ (ที่ควรเก็บไว้ที่อื่น) พวกเขาไม่สามารถเปลี่ยนแปลงได้พวกเขาไม่จำเป็นต้องผ่านเข้าเรียนของคุณ (ไม่เช่นนั้นพวกเขาจะต้องเปิดเผยต่อสาธารณะ) การใช้งานที่เป็นไปได้เท่านั้นสำหรับพวกเขาคือค่าคงที่ในคลาสอื่น ๆ แต่ถ้าคุณทำอย่างนั้นชั้นเรียนเหล่านั้นตอนนี้ขึ้นอยู่กับชั้นเรียนของคุณเพื่อทำงานที่ไม่เกี่ยวข้องกับชั้นเรียนของคุณ ถ้าคุณเปลี่ยนค่าคงที่คลาสอื่นอาจแตก ไม่ดีจากทั้งสองฝ่าย - ในฐานะผู้เขียนชั้นเรียนของคุณคุณต้องการอิสระในการเปลี่ยนแปลงมากที่สุดและไม่ต้องการกังวลเกี่ยวกับสิ่งต่าง ๆ ที่อยู่นอกเหนือการควบคุมของคุณ ผู้บริโภคในชั้นเรียนของคุณต้องการที่จะขึ้นอยู่กับรายละเอียดที่เปิดเผยของชั้นเรียนของคุณโดยไม่ต้องกังวลเกี่ยวกับการเปลี่ยนแปลงและทำลายรหัสของพวกเขา

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


1

แนวคิด OOP มีการสืบทอดมีหนึ่งในคุณลักษณะ (Java หรือ C ++) ดังนั้นถ้าเราจะสืบทอด (หมายถึงเรากำลังจะเข้าถึงตัวแปรของคลาสที่สืบทอด) มีความเป็นไปได้ที่จะมีผลกระทบต่อตัวแปรเหล่านั้น ดังนั้นเราต้องตัดสินใจว่าตัวแปรสามารถเปลี่ยนแปลงได้หรือไม่

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

ดังที่เราทราบการป้องกันหมายถึงมันสามารถเข้าถึงได้โดยชั้นเรียนที่จะสืบทอด

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


1

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

แต่ในทางกลับกันสิ่งที่คนอื่น ๆ ส่วนใหญ่ไม่สนใจเป็นเรื่องเกี่ยวกับเขตข้อมูลที่มีการป้องกัน

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

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

แต่ในทางกลับกันฟิลด์ส่วนตัวลดความยืดหยุ่นของรหัสของคุณให้กับผู้ใช้รายอื่น

ความยืดหยุ่นกับปัญหาข้อดีข้อเสีย:

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

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

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

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

ดังนั้นความสมดุลที่ดีระหว่างส่วนบุคคลที่ได้รับการปกป้องและที่สาธารณะคือสิ่งที่สำคัญจริงๆ

ตอนนี้การตัดสินใจระหว่างส่วนตัวกับการป้องกันเป็นปัญหาที่แท้จริง

ควรใช้การป้องกันเมื่อใด

ทุกครั้งที่คุณเข้าใจว่าเขตข้อมูลนั้นมีความยืดหยุ่นสูงรหัสนั้นควรได้รับการป้องกัน ความยืดหยุ่นนั่นคือ: กลายเป็นโมฆะ (โดยที่โมฆะจะถูกตรวจสอบและรับรู้เสมอว่าเป็นสถานะที่ถูกต้องไม่ส่งข้อยกเว้น) ไปจนถึงการมีข้อ จำกัด ก่อนที่จะถูกใช้โดยคลาสของคุณ > = 0, <100 ฯลฯ และได้รับการแก้ไขโดยอัตโนมัติสำหรับค่าสูง / ต่ำ - ไหลโดยมีข้อความเตือนเป็นจำนวนมาก

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


-1

imo @tdammers ไม่ถูกต้องและทำให้เข้าใจผิดจริงๆ

มีตัวแปรส่วนตัวเพื่อซ่อนรายละเอียดการใช้งาน ชั้นเรียนของคุณAอาจใช้arrayคะแนนเพื่อเก็บคะแนน พรุ่งนี้คุณอาจต้องการใช้treeหรือpriority queueแทน ผู้ใช้ทุกคนในชั้นเรียนของคุณต้องการวิธีป้อนคะแนนและชื่อaddScore()และวิธีการคิดออกว่าใครคือ 10 อันดับgetTop(n)แรก

พวกเขาไม่จำเป็นต้องเข้าถึงโครงสร้างข้อมูลพื้นฐาน ฟังดูดี? มีข้อแม้อยู่บ้าง

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

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


-1
  • การเข้าถึงตัวแปรหมายถึงการเข้าถึงค่าของมันเมื่อโปรแกรมทำงานทำให้ตัวแปรส่วนตัวปกป้องค่าของมันเมื่อโค้ดทำงาน
  • จุดที่เรียกว่า "data hiding" คือการซ่อนข้อมูลภายในจากคลาสอื่น ๆ ที่ใช้คลาส คลาสอื่น ๆ เหล่านั้นควรเข้าถึงพฤติกรรมโดยการเรียกใช้เมธอดบนคลาสไม่ใช่โดยการเปลี่ยนค่าของตัวแปรโดยตรง
  • ด้วยการทำให้ตัวแปรเป็นสมาชิกข้อมูลส่วนตัวคุณจะสามารถตรวจสอบให้แน่ใจได้ง่ายขึ้นว่าค่าไม่เคยเปลี่ยนแปลงหรือเปลี่ยนแปลง ในทางกลับกันหากตัวแปรเป็นแบบสาธารณะคลาสอื่นสามารถแก้ไขหรือเปลี่ยนแปลงค่าซึ่งอาจทำให้ส่วนอื่น ๆ ของรหัสขัดข้อง

1
สิ่งนี้ดูเหมือนจะไม่นำเสนอสิ่งใดเกินกว่าที่ทำและอธิบายไว้ในคำตอบก่อนหน้า 17 คำตอบ
ริ้น

-4

คุณควรเข้าใจแนวคิดของการเขียนโปรแกรมเชิงวัตถุ มันมีสิ่งที่เป็นนามธรรม, แค็ปซูล ฯลฯ

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

Encapsulation - คุณไม่สามารถเห็นการใช้งานขีดเส้นใต้ของวัตถุ มีเพียงคุณเท่านั้นที่เห็นส่วนต่อประสานสาธารณะของวัตถุ

ตอนนี้ในการใช้งานเฉพาะกับหนึ่งในโปรแกรมเชิงวัตถุเช่น C #, Java, C ++ คุณสามารถใช้แนวคิดเหล่านี้

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

สาธารณะ - นี่คืออินเทอร์เฟซที่หนึ่งสามารถใช้วัตถุของคุณ


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