สิ่งที่ควรได้รับอนุญาตภายในตัวต่อและผู้ตั้งค่า?


45

ฉันได้ข้อโต้แย้งอินเทอร์เน็ตที่น่าสนใจเกี่ยวกับวิธี getter และ setter และการห่อหุ้ม บางคนบอกว่าสิ่งที่พวกเขาควรทำคือมอบหมาย (setters) หรือตัวแปร access (getters) เพื่อให้พวกเขา "บริสุทธิ์" และทำให้แน่ใจว่าการห่อหุ้ม

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

18
สิ่งที่ดีที่สุดเกี่ยวกับ getters และ setters คือความสามารถที่จะไม่มีพวกมันเช่นออกจาก setter และคุณมีคุณสมบัติแบบอ่านอย่างเดียวออกจาก getter และคุณมีตัวเลือก config ที่มีมูลค่าปัจจุบันเป็นธุรกิจของใคร
Michael Borgwardt

7
@MichaelBorgwardt ปล่อยให้ทั้งคู่มีอินเทอร์เฟซ“ บอกอย่าถาม” ที่สะอาด สรรพคุณ = กลิ่นรหัสที่อาจเกิดขึ้น
Konrad Rudolph


2
Setters นอกจากนี้ยังสามารถใช้สำหรับการยกเหตุการณ์
John Isaiah Carmona

@ KonradRudolph ฉันเห็นด้วยกับคำสั่งของคุณแม้ว่าฉันต้องการเน้นคำว่า "ศักยภาพ" จริงๆ
ฟิล

คำตอบ:


37

ฉันจำได้ว่ามีข้อโต้แย้งที่คล้ายกันกับอาจารย์ของฉันเมื่อเรียนรู้ 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 ได้รับอนุญาตให้เปลี่ยนค่าหรือไม่ (อาจแปลงค่าที่ถูกต้องเป็นตัวแทนภายในที่ยอมรับได้)

ในกรณีที่หายากมากอาจจะ โดยทั่วไปแล้วก็น่าจะดีกว่านะคะ นี่เป็นวิธีที่ดีที่สุดในการใช้วิธีอื่น


Re: เปลี่ยนค่าก็อาจจะมีเหตุผลที่จะตั้งค่าให้ -1 ธงหรือโมฆะบาง token ถ้าหมาถูกส่งผ่านค่าที่ผิดกฎหมาย
มาร์ติน Beckett

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

ใช่หนึ่งในเหตุผลของ setter คือมันควรจะกลับจริง / เท็จหากค่าสามารถตั้งค่าได้
Martin Beckett

1
"คุณสมบัติจุดลอยตัวเป็นตัวอย่างที่ดีที่คุณอาจต้องการปัดเศษทศนิยมมากเกินไปเพื่อหลีกเลี่ยงการยกเว้น" ในกรณีใดที่มีตำแหน่งทศนิยมมากเกินไปยกข้อยกเว้น
Mark Byers

2
ฉันเห็นการเปลี่ยนค่าเป็นการรับรองแบบบัญญัติซึ่งเป็นรูปแบบการตรวจสอบ การกำหนดค่าเริ่มต้นที่ขาดหายไป (เช่นวันที่ปัจจุบันหากการประทับเวลามีเพียงเวลา) หรือการปรับค่า (.93275 -> 93.28%) เพื่อให้แน่ใจว่าความสอดคล้องภายในควรจะตกลง แต่การจัดการดังกล่าวควรถูกเรียกออกมาอย่างชัดเจนในเอกสาร API โดยเฉพาะอย่างยิ่งหากพวกเขาเป็นสำนวนที่ผิดปกติภายใน API
TMN

20

หากผู้ทะเยอทะยาน / setter เพียงสะท้อนคุณค่าแล้วไม่มีจุดในการมีพวกเขาหรือในการทำให้ค่าส่วนตัว ไม่มีอะไรผิดปกติที่จะทำให้ตัวแปรสมาชิกบางส่วนปรากฏต่อสาธารณะหากคุณมีเหตุผลที่ดี หากคุณกำลังเขียนคลาสพอยต์แบบ 3 มิติจากนั้นให้มี. x, .y, .z เป็นแบบสาธารณะ

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

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

เหตุผลปกติสำหรับพวกเขาว่าพวกเขาซ่อนโครงสร้างภายในโดยทั่วไปมีประโยชน์น้อยที่สุด เช่น. ฉันมีจุดเหล่านี้เก็บเป็น 3 ลอยฉันอาจตัดสินใจที่จะเก็บไว้เป็นสตริงในฐานข้อมูลระยะไกลดังนั้นฉันจะให้ getters / setters เพื่อซ่อนพวกเขาราวกับว่าคุณสามารถทำได้โดยไม่ต้องมีผลกระทบอื่น ๆ ในรหัสของผู้โทร


1
ว้าวนักออกแบบของ Java เป็นพระเจ้า? </jk>

@delnan - เห็นได้ชัดว่าไม่ - หรือพวกเขาจะสัมผัสได้ดีกว่า ;-)
Martin Beckett

มันจะถูกต้องหรือไม่ที่จะสร้างจุด 3 มิติซึ่ง x, y, z ทั้งหมดเป็น Float.NAN
Andrew T Finnell

4
ฉันไม่เห็นด้วยกับจุดของคุณว่า "เหตุผลตามปกติ" (การซ่อนโครงสร้างภายใน) เป็นคุณสมบัติที่มีประโยชน์น้อยที่สุดของ getters และ setters ใน C # จะเป็นประโยชน์แน่นอนที่จะทำให้ทรัพย์สินที่มีอินเตอร์เฟซที่มีโครงสร้างพื้นฐานที่สามารถเปลี่ยนแปลงได้ - ยกตัวอย่างเช่นถ้าคุณเพียงต้องการทรัพย์สินใช้ได้สำหรับการนับมันมากดีกว่าที่จะบอกว่ากว่าบังคับให้มันบางอย่างเช่นIEnumerable<T> List<T>ตัวอย่างของคุณในการเข้าถึงฐานข้อมูลที่ฉันจะบอกว่าเป็นการละเมิดความรับผิดชอบเดียว - การผสมการนำเสนอของโมเดลด้วยวิธีที่มันยังคงอยู่
แบรนดอนลินตัน

@AndrewFinnell - มันอาจจะเป็นวิธีที่ดีของการตั้งค่าสถานะเป็นจุดเป็นไปไม่ได้ / ไม่ถูกต้อง / ถูกลบ ฯลฯ
มาร์ติน Beckett

8

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

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

วัตถุที่มีคุณค่าโครงสร้างที่เรียบง่ายไม่จำเป็นต้องมีสิ่งที่เป็นนามธรรม แต่ชั้นเรียนที่มีความสมบูรณ์นั้น


2

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

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

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

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

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


1

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


1

ไม่มีการจับคู่ 1-1 ระหว่างตัวเข้าถึงคุณสมบัติและ ivars ที่เก็บข้อมูลเสมอ

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


0

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


-4

ฉันมักจะเชื่อว่า setters และ getters นั้นชั่วร้ายและควรใช้ในคลาสที่จัดการโดยเฟรมเวิร์ก / คอนเทนเนอร์เท่านั้น การออกแบบระดับที่เหมาะสมไม่ควรให้ผลตอบแทนกับตัวตั้งและตัวตั้งค่า

แก้ไข: บทความที่เขียนดีเกี่ยวกับเรื่องนี้

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


1
ฉันคิดว่าคุณพลาดจุดของบทความซึ่งแนะนำให้ใช้ getters / setters เท่าที่จำเป็นและเพื่อหลีกเลี่ยงการเปิดเผยข้อมูลของชั้นเรียนเว้นแต่จำเป็น IMHO นี้เป็นหลักการออกแบบที่เหมาะสมซึ่งผู้พัฒนาควรใช้โดยเจตนา ในแง่ของการสร้างคุณสมบัติในคลาสคุณสามารถเปิดเผยตัวแปรได้ แต่สิ่งนี้ทำให้ยากที่จะให้การตรวจสอบความถูกต้องเมื่อตัวแปรถูกตั้งค่าหรือดึงค่าจากแหล่งทางเลือกเมื่อ "ได้รับ" โดยพื้นฐานแล้วเป็นการละเมิด encapsulation ล็อคคุณเข้าสู่การออกแบบอินเตอร์เฟสที่ยากต่อการดูแลรักษา
S.Robins

@ S.Robins ในความคิดของฉัน getters สาธารณะและ setters ผิด เขตข้อมูลสาธารณะมีความผิดพลาดมากกว่า (หากเทียบได้)
m3th0dman

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

@ S.Robins คิดถึงพื้นฐานของ OOP และการสร้างแบบจำลอง วัตถุควรจะคัดลอกเอนทิตีในชีวิตจริง มีเอนทิตีในชีวิตจริงที่มีการดำเนินการ / คุณสมบัติประเภทนี้เช่น getters / setters หรือไม่?
m3th0dman

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