ฉันจำได้ว่ามีข้อโต้แย้งที่คล้ายกันกับอาจารย์ของฉันเมื่อเรียนรู้ C ++ ที่มหาวิทยาลัย ฉันไม่เห็นจุดใช้ getters และ setters เมื่อฉันสามารถทำให้ตัวแปรเป็นแบบสาธารณะได้ ตอนนี้ฉันเข้าใจดีขึ้นด้วยประสบการณ์หลายปีและฉันได้เรียนรู้เหตุผลที่ดีกว่าเพียงแค่พูดว่า "เพื่อรักษาความห่อหุ้ม"
โดยการกำหนดตัวรับและตัวตั้งค่าคุณจะมีอินเทอร์เฟซที่สอดคล้องกันดังนั้นหากคุณต้องการเปลี่ยนการใช้งานของคุณคุณจะมีโอกาสน้อยที่จะทำลายรหัสที่ขึ้นต่อกัน นี่เป็นสิ่งสำคัญอย่างยิ่งเมื่อคุณเรียนผ่าน API และใช้ในแอพอื่นหรือโดยบุคคลที่สาม ดังนั้นสิ่งที่เกี่ยวกับสิ่งที่เข้าไปในทะเยอทะยานหรือสุนัขเซทเทอร์?
โดยทั่วไปแล้ว Getters จะถูกนำไปใช้เป็น passthrough แบบ dumbed-down แบบง่าย ๆ เพื่อเข้าถึงค่าเพราะสิ่งนี้ทำให้พฤติกรรมของพวกเขาสามารถคาดเดาได้ ฉันพูดโดยทั่วไปเพราะฉันเห็นกรณีที่ getters ถูกใช้เพื่อเข้าถึงค่าที่จัดการโดยการคำนวณหรือแม้กระทั่งโดยรหัสตามเงื่อนไข โดยทั่วไปแล้วไม่ค่อยดีนักหากคุณกำลังสร้างส่วนประกอบภาพเพื่อใช้งานในเวลาออกแบบ แต่ดูเหมือนจะมีประโยชน์ในขณะใช้งาน ไม่มีความแตกต่างกันระหว่างวิธีนี้กับการใช้วิธีง่าย ๆ ยกเว้นว่าเมื่อคุณใช้วิธีการโดยทั่วไปแล้วคุณมักจะตั้งชื่อวิธีที่เหมาะสมกว่าเพื่อให้การทำงานของ "getter" ชัดเจนยิ่งขึ้นเมื่ออ่านรหัส
เปรียบเทียบสิ่งต่อไปนี้:
int aValue = MyClass.Value;
และ
int aValue = MyClass.CalculateValue();
ตัวเลือกที่สองทำให้ชัดเจนว่ามีการคำนวณค่าในขณะที่ตัวอย่างแรกบอกคุณว่าคุณเพียงแค่คืนค่าโดยไม่ต้องรู้อะไรเกี่ยวกับค่าตัวเอง
คุณอาจโต้แย้งว่าสิ่งต่อไปนี้จะชัดเจนขึ้น:
int aValue = MyClass.CalculatedValue;
อย่างไรก็ตามปัญหาคือคุณสมมติว่าค่านั้นได้รับการจัดการที่อื่นแล้ว ดังนั้นในกรณีของผู้ทะเยอทะยานในขณะที่คุณอาจคิดว่ามีสิ่งอื่นที่อาจเกิดขึ้นเมื่อคุณคืนค่ามันเป็นการยากที่จะทำให้สิ่งต่าง ๆ ชัดเจนในบริบทของทรัพย์สินและชื่อคุณสมบัติไม่ควรมีคำกริยา ไม่เช่นนั้นจะทำให้ยากที่จะเข้าใจได้อย่างรวดเร็วว่าชื่อที่ใช้ควรตกแต่งด้วยวงเล็บหรือไม่เมื่อเข้าถึง
ผู้ตั้งถิ่นฐานเป็นกรณีที่แตกต่างกันเล็กน้อย เป็นความเหมาะสมอย่างยิ่งที่ setter จัดเตรียมการประมวลผลเพิ่มเติมบางอย่างเพื่อตรวจสอบความถูกต้องของข้อมูลที่ส่งไปยังสถานที่ให้บริการโดยมีข้อยกเว้นหากการตั้งค่าจะเป็นการละเมิดขอบเขตที่กำหนดไว้ของทรัพย์สิน ปัญหาที่นักพัฒนาบางคนมีกับการเพิ่มการประมวลผลไปยังตัวตั้งค่าก็คือมีสิ่งล่อใจที่จะให้ตัวตั้งค่าทำอีกเล็กน้อยเช่นทำการคำนวณหรือจัดการข้อมูลในบางลักษณะ นี่คือที่ที่คุณสามารถได้รับผลข้างเคียงที่ในบางกรณีอาจคาดเดาไม่ได้หรือไม่พึงประสงค์
ในกรณีของ setters ฉันมักจะใช้กฎง่ายๆที่จะทำข้อมูลให้น้อยที่สุด ตัวอย่างเช่นฉันมักจะอนุญาตให้ทำการทดสอบขอบเขตและปัดเศษเพื่อให้ฉันสามารถยกข้อยกเว้นตามความเหมาะสมหรือหลีกเลี่ยงข้อยกเว้นที่ไม่จำเป็นซึ่งสามารถหลีกเลี่ยงได้อย่างสมเหตุสมผล คุณสมบัติจุดลอยตัวเป็นตัวอย่างที่ดีที่คุณอาจต้องการปัดเศษทศนิยมที่มากเกินไปเพื่อหลีกเลี่ยงการยกข้อยกเว้นในขณะที่ยังอนุญาตให้ป้อนค่าช่วงด้วยทศนิยมเพิ่มเติมอีกสองสามรายการ
หากคุณใช้การจัดการอินพุต setter บางประเภทคุณมีปัญหาเช่นเดียวกับผู้บุกรุกซึ่งเป็นเรื่องยากที่จะอนุญาตให้ผู้อื่นทราบว่า setter กำลังทำอะไรโดยเพียงแค่ตั้งชื่อ ตัวอย่างเช่น:
MyClass.Value = 12345;
สิ่งนี้บอกอะไรคุณเกี่ยวกับสิ่งที่จะเกิดขึ้นกับค่าเมื่อมันถูกมอบให้กับผู้ตั้งค่าหรือไม่?
เกี่ยวกับ:
MyClass.RoundValueToNearestThousand(12345);
ตัวอย่างที่สองจะบอกคุณอย่างชัดเจนว่าเกิดอะไรขึ้นกับข้อมูลของคุณในขณะที่ตัวอย่างแรกจะไม่แจ้งให้คุณทราบว่ามูลค่าของคุณจะได้รับการแก้ไขโดยพลการหรือไม่ เมื่ออ่านโค้ดตัวอย่างที่สองจะมีความชัดเจนมากขึ้นในวัตถุประสงค์และฟังก์ชั่น
ฉันถูกต้องไหมที่สิ่งนี้จะเอาชนะจุดประสงค์ของการมีผู้ได้รับและผู้ตั้งถิ่นฐานในตอนแรกและการตรวจสอบความถูกต้องและตรรกะอื่น ๆ (โดยไม่มีผลข้างเคียงที่แปลกประหลาดของหลักสูตร) ควรได้รับอนุญาตหรือไม่
การมี getters และ setters ไม่ได้เกี่ยวกับการห่อหุ้มเพื่อประโยชน์ของ "ความบริสุทธิ์" แต่เกี่ยวกับการห่อหุ้มเพื่อให้สามารถปรับเปลี่ยนรหัสได้อย่างง่ายดายโดยไม่เสี่ยงต่อการเปลี่ยนแปลงส่วนต่อประสานของชั้นเรียน การตรวจสอบความถูกต้องเหมาะสมอย่างสมบูรณ์ในตัวตั้งค่าอย่างไรก็ตามมีความเสี่ยงเล็กน้อยที่การเปลี่ยนแปลงการตรวจสอบอาจทำลายความเข้ากันได้กับรหัสการโทรหากรหัสการโทรขึ้นอยู่กับการตรวจสอบที่เกิดขึ้นในวิธีการเฉพาะ นี่เป็นสถานการณ์โดยทั่วไปที่หายากและค่อนข้างมีความเสี่ยงต่ำ แต่ควรสังเกตเพื่อความสมบูรณ์
การตรวจสอบควรเกิดขึ้นเมื่อใด
การตรวจสอบควรเกิดขึ้นภายในบริบทของตัวตั้งค่าก่อนที่จะตั้งค่าจริง สิ่งนี้ช่วยให้มั่นใจได้ว่าหากมีข้อผิดพลาดเกิดขึ้นสถานะของวัตถุของคุณจะไม่เปลี่ยนแปลงและอาจทำให้ข้อมูลใช้ไม่ได้ ฉันมักจะพบว่าดีกว่าที่จะมอบหมายการตรวจสอบความถูกต้องให้กับวิธีการแยกต่างหากซึ่งจะเป็นสิ่งแรกที่เรียกว่าภายในตัวตั้งค่าเพื่อให้รหัสตัวตั้งค่าค่อนข้างกระจัดกระจาย
setter ได้รับอนุญาตให้เปลี่ยนค่าหรือไม่ (อาจแปลงค่าที่ถูกต้องเป็นตัวแทนภายในที่ยอมรับได้)
ในกรณีที่หายากมากอาจจะ โดยทั่วไปแล้วก็น่าจะดีกว่านะคะ นี่เป็นวิธีที่ดีที่สุดในการใช้วิธีอื่น