JavaRush /จาวาบล็อก /Random-TH /เก็ตเตอร์/เซ็ตเตอร์ ความชั่วร้าย. และระยะ
angelina
ระดับ

เก็ตเตอร์/เซ็ตเตอร์ ความชั่วร้าย. และระยะ

เผยแพร่ในกลุ่ม
บทความโดย Egor Bugaenko 19 กันยายน 2014 | โพสต์ใน: Core Java เก็ตเตอร์/เซ็ตเตอร์  ความชั่วร้าย.  และจุด - 1การอภิปรายเก่านี้เริ่มต้นโดย Allen Holub ในบทความที่มีชื่อเสียงของเขา ย้อนกลับไปในปี 2003 เหตุใดวิธีการ getter และ setter จึงชั่วร้าย - getters/setters เป็นรูปแบบที่ต่อต้านและเราควรหลีกเลี่ยงหรือเป็นสิ่งที่เรา ' จำเป็นต้องมีอีกครั้งในการเขียนโปรแกรมเชิงวัตถุ ฉันจะเพิ่มสองเซ็นต์ของฉันในการสนทนานี้ สาระสำคัญของข้อความด้านล่างนี้คือ: getters และ setters เป็นแนวทางปฏิบัติที่ไม่ดี ผู้ที่ใช้สิ่งเหล่านี้ไม่มีข้อแก้ตัว แต่อีกครั้ง เพื่อหลีกเลี่ยงความเข้าใจผิด ฉันไม่ได้แนะนำว่าควรหลีกเลี่ยงการใช้ get/set หากเป็นไปได้ เลขที่ ฉันกำลังบอกว่าคุณไม่ได้ปล่อยให้พวกเขาเข้าใกล้รหัสของคุณ เก็ตเตอร์/เซ็ตเตอร์  ความชั่วร้าย.  และจุด - 2คุณคิดอย่างไรกับข้อความนี้ คุ้มค่ากับความสนใจของคุณ? คุณใช้รูปแบบ get/set มาเป็นเวลา 15 ปีแล้ว และคุณเป็นสถาปนิก Java ที่น่าเชื่อถือหรือไม่? และคุณไม่อยากฟังเรื่องไร้สาระจากคนแปลกหน้าด้วยซ้ำ? ก็...ฉันเข้าใจความรู้สึกของคุณนะ ฉันรู้สึกแบบเดียวกันจนกระทั่งมาเจอหนังสือ "Object Thinking" ของ David West ซึ่งเป็นหนังสือเกี่ยวกับการเขียนโปรแกรมเชิงวัตถุที่ดีที่สุดที่ฉันเคยอ่านมา ได้โปรด. ใจเย็นๆ และพยายามทำความเข้าใจกับสิ่งที่ฉันพยายามจะอธิบาย หัวข้อของการโต้เถียง มีข้อโต้แย้งหลายประการกับ "accessors" (ชื่ออื่นสำหรับ getters และ setters) ในโลกเชิงวัตถุ และล้วนเป็นข้อโต้แย้งที่ถูกต้องมาก ลองมาดูพวกเขากันอย่างรวดเร็ว ถาม, อย่าบอก : Allen Holub พูดว่า "อย่าถามข้อมูลที่คุณต้องการในการทำงาน 'ถาม' หน่วยงานที่มีข้อมูลนั้นทำงานให้คุณ" หลักการห่อหุ้มที่ละเมิด : วัตถุสามารถแยกออกจากกันโดยวัตถุอื่นได้ เนื่องจากวัตถุเหล่านั้นสามารถฝังข้อมูลใด ๆ ลงในวัตถุได้ผ่านตัวตั้งค่า วัตถุไม่สามารถสรุปสถานะของตัวเองได้อย่างปลอดภัยเพียงพอ เนื่องจากใครๆ ก็สามารถเปลี่ยนแปลงสถานะนั้นได้ เปิดเผยรายละเอียดการใช้งาน : หากคุณสามารถรับออบเจ็กต์หนึ่งจากอีกออบเจ็กต์หนึ่ง แสดงว่าเราอาศัยรายละเอียดการใช้งานของออบเจ็กต์แรกมากเกินไป หากพรุ่งนี้มีการเปลี่ยนแปลง (เช่น ประเภทผลลัพธ์) เราจะต้องเปลี่ยนรหัส เหตุผลข้างต้นทั้งหมดสมเหตุสมผลอย่างแน่นอน แต่นี่พลาดจุดที่สำคัญที่สุดไป ความเข้าใจผิดขั้นพื้นฐาน โปรแกรมเมอร์ส่วนใหญ่เชื่อว่าวัตถุเป็นโครงสร้างข้อมูลที่มีวิธีการ ฉันอ้างอิงบทความโดย Bozhidar Bozhanov: Getters and Setters ไม่ใช่สิ่งชั่วร้าย. แต่อ็อบเจ็กต์ส่วนใหญ่ที่สร้าง getters และ setters มีเพียงข้อมูลเท่านั้น ความเข้าใจผิดนี้เป็นผลมาจากความเข้าใจผิดครั้งใหญ่! ออบเจ็กต์ไม่ได้ "แค่เก็บข้อมูล" วัตถุไม่ใช่โครงสร้างข้อมูลที่แนบวิธีการ แนวคิดของ "การจัดเก็บข้อมูล" นี้มาจากการเขียนโปรแกรมเชิงวัตถุและภาษาขั้นตอน โดยเฉพาะ C และ COBOL ฉันจะทำซ้ำอีกครั้ง: วัตถุไม่ได้เป็นเพียงชุดขององค์ประกอบข้อมูลและฟังก์ชันที่จัดการพวกมัน วัตถุไม่ใช่วัตถุข้อมูล แล้วไงล่ะ? Ball and Dog ในการเขียนโปรแกรมเชิงวัตถุอย่างแท้จริง วัตถุก็คือสิ่งมีชีวิต เช่นเดียวกับคุณและฉัน พวกมันเป็นสิ่งมีชีวิตที่มีพฤติกรรม คุณสมบัติ และวงจรชีวิตเป็นของตัวเอง สิ่งมีชีวิตสามารถมีตัวเซ็ตเตอร์ได้หรือไม่? คุณสามารถติด (“ตั้ง”) ลูกบอลกับสุนัขได้หรือไม่? อย่าคิดนะ. แต่นั่นคือสิ่งที่โค้ดด้านล่างทำ:
Dog dog = new Dog();
dog.setBall(new Ball());
แล้วคุณล่ะชอบมันแค่ไหน? คุณสามารถเอา (“รับ”) ลูกบอลออกจากสุนัขได้หรือไม่? สมมติว่าคุณทำได้ ในกรณีที่เธอกินมันแล้วคุณทำการผ่าตัดเธอ ในกรณีนี้ ใช่ คุณจะสามารถได้รับ (“รับ”) ลูกบอลจากสุนัขได้ นี่คือสิ่งที่ฉันกำลังพูดถึง:
Dog dog = new Dog();
Ball ball = dog.getBall();
หรือตัวอย่างที่ไร้สาระยิ่งกว่านั้น:
Dog dog = new Dog();
dog.setWeight("23kg");
คุณจินตนาการสิ่งนี้ในชีวิตจริงได้ไหม? ดูเหมือนคุณจะเขียนทุกวันใช่ไหม? ถ้าใช่ แสดงว่าคุณเป็นโปรแกรมเมอร์ขั้นตอน แค่ยอมรับมัน นี่คือสิ่งที่ David West พูดไว้ในหน้าที่ 30 ของหนังสือของเขา: ขั้นตอนแรกในการเปลี่ยนนักพัฒนาขั้นตอนที่ประสบความสำเร็จให้กลายเป็นนักพัฒนาตามวัตถุประสงค์ที่ประสบความสำเร็จคือการผ่าตัด lobotomy คุณจำเป็นต้องผ่าตัด lobotomy หรือไม่? ฉันต้องการมันอย่างแน่นอน และฉันได้มันมาในขณะที่อ่านหนังสือเรื่อง Object Thinking ของเวสต์ การคิดเชิงวัตถุประสงค์ เริ่มคิดเหมือนวัตถุแล้วคุณจะเปลี่ยนชื่อวิธีการเหล่านี้ทันที นี่คือสิ่งที่คุณอาจได้รับ:
Dog dog = new Dog();
dog.take(new Ball());
Ball ball = dog.give();
ตอนนี้เราถือว่าสุนัขเป็นสัตว์จริงๆ ที่สามารถแย่งลูกบอลไปจากเราได้และคืนให้ถ้าเราขอ ในกรณีที่ฉันทราบว่าสุนัขไม่สามารถคืนค่า NULL ได้ สุนัขไม่รู้ว่า NULL คืออะไร! การคิดอย่างมีวัตถุประสงค์ (การคิด) จะลบการอ้างอิง NULL ออก จากโค้ดของคุณ ทันทีเก็ตเตอร์/เซ็ตเตอร์  ความชั่วร้าย.  และจุด - 3
ปลาที่เรียกว่าแวนด้า (1988) โดย Charles Crichton
นอกจากนี้ การคิดอย่างเป็นกลางจะส่งผลให้วัตถุไม่เปลี่ยนรูป เช่น “น้ำหนักของสุนัข” ในตัวอย่างของเรา คุณจะเขียนโค้ดใหม่ดังนี้:
Dog dog = new Dog("23kg");
int weight = dog.weight();
สุนัขเป็นสิ่งมีชีวิตที่ไม่สามารถเปลี่ยนแปลงได้ ซึ่งจะไม่ยอมให้ใครภายนอกเปลี่ยนน้ำหนัก ขนาด หรือชื่อ ฯลฯ เธอสามารถ "บอก" น้ำหนักหรือชื่อของเธอได้ตามคำขอ ไม่มีอะไรผิดปกติกับวิธีการสาธารณะที่เปิดเผยการสืบค้นคุณสมบัติ "ภายใน" บางอย่างของออบเจ็กต์ แต่วิธีการเหล่านี้ไม่ใช่ "getters" และไม่ควรได้รับคำนำหน้า "get" เราไม่ "เอา" ออกจากสุนัข เราไม่เข้าใจชื่อของเธอ เราขอให้เธอบอกชื่อของเธอ คุณเห็นความแตกต่างหรือไม่? เราไม่ได้พูดถึงความหมายที่นี่ด้วยซ้ำ เราแยกความแตกต่างระหว่างแนวทางขั้นตอนในการเขียนโปรแกรมจากแนวทางเชิงวัตถุ ในการเขียนโปรแกรมตามขั้นตอน เราทำงานกับข้อมูล จัดการ รับ ตั้งค่า และลบออกหากจำเป็น เรามีหน้าที่รับผิดชอบ และข้อมูลเป็นเพียงส่วนประกอบที่ไม่โต้ตอบ สุนัขไม่มีความหมายอะไรสำหรับเรา แค่ "มีข้อมูล" เท่านั้น เธอไม่มีชีวิตของเธอเอง เราสามารถรับ (รับ) ทุกสิ่งที่เราต้องการจากมันได้อย่างอิสระ และใส่ (ตั้งค่า) ข้อมูลใด ๆ ลงไป นี่คือวิธีการทำงานของ C, COBOL, Pascal และภาษาขั้นตอนอื่น ๆ (ทำงาน) และสถานการณ์นั้นตรงกันข้ามอย่างสิ้นเชิงในโลกเชิงวัตถุ ที่นี่เราปฏิบัติต่อวัตถุต่างๆ เสมือนเป็นสิ่งมีชีวิต โดยมีวันเดือนปีเกิดและช่วงเวลาที่เสียชีวิต พร้อมด้วยบุคลิกภาพและนิสัยของพวกมันเอง หากคุณต้องการ เราสามารถขอให้สุนัขให้ข้อมูลชิ้นหนึ่งแก่เรา (เช่น น้ำหนักของมัน) และสุนัขก็สามารถส่งข้อมูลกลับมาให้เราได้ แต่จำไว้เสมอว่าสุนัขเป็นส่วนประกอบที่กระตือรือร้น เธอตัดสินใจว่าจะเกิดอะไรขึ้นหลังจากการร้องขอ และนั่นเป็นสาเหตุที่ผิดอย่างยิ่งที่เมธอดของอ็อบเจ็กต์จะเริ่มต้นด้วย set หรือ get และนี่ไม่ได้เกี่ยวกับการละเมิดการห่อหุ้มอย่างที่หลายคนคิด นี่เป็นเรื่องเกี่ยวกับความจริงที่ว่าคุณกำลังคิดเหมือนวัตถุหรือคุณยังคงเขียนภาษาโคบอลด้วยไวยากรณ์ Java ป.ล. _ และใช่ คุณอาจถามว่า: "แล้ว JavaBeans, JPA, JAXB และ Java API อื่นๆ อีกมากมายที่ขึ้นอยู่กับ get/set ล่ะ" แล้วฟังก์ชันในตัวใน Ruby ที่ทำให้การสร้าง accessors ง่ายขึ้นล่ะ? ฉันจะบอกอะไรคุณได้บ้าง... คุณโชคไม่ดี มันง่ายกว่ามากที่จะอยู่ในโลกดึกดำบรรพ์ของภาษาโคบอลเชิงขั้นตอนมากกว่าที่จะเข้าใจและยอมรับโลกมหัศจรรย์ของวัตถุจริง ป.ล. _ ฉันลืมที่จะบอกว่า ใช่ การแทรกการพึ่งพาผ่านตัวตั้งค่าก็เป็นการต่อต้านรูปแบบที่แย่มากเช่นกัน แต่จะเพิ่มเติมในโพสต์ถัดไป! บทความต้นฉบับ
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION