ตามกฎหมายของ Demeter ชั้นเรียนได้รับอนุญาตให้ส่งคืนหนึ่งในสมาชิกหรือไม่
ใช่แน่นอนที่สุดคือ
ลองดูที่ประเด็นหลัก :
- แต่ละหน่วยควรมีความรู้ที่ จำกัด เฉพาะเกี่ยวกับหน่วยอื่น ๆ : เฉพาะหน่วย "อย่างใกล้ชิด" ที่เกี่ยวข้องกับหน่วยปัจจุบัน
- แต่ละหน่วยควรพูดคุยกับเพื่อนเท่านั้น อย่าคุยกับคนแปลกหน้า
- พูดคุยกับเพื่อนของคุณทันที
ทั้งสามข้อนี้ทำให้คุณถามคำถามเดียว: เพื่อนคือใคร
เมื่อตัดสินใจว่าจะส่งคืนอะไรกฎของ Demeter หรือหลักการของความรู้น้อยที่สุด (LoD) ไม่ได้กำหนดว่าคุณจะป้องกันผู้เข้ารหัสที่ยืนยันการละเมิด มันบอกว่าคุณไม่ได้บังคับให้ผู้เขียนโค้ดละเมิด
การสับสนเหล่านี้คือเหตุผลที่หลายคนคิดว่าผู้ตั้งตัวต้องกลับเป็นโมฆะเสมอ ไม่ได้คุณต้องอนุญาตวิธีในการสอบถาม (getters) ที่ไม่เปลี่ยนสถานะของระบบ นั่นเป็นพื้นฐานการแยกแบบสอบถามคำสั่ง
นี่หมายความว่าคุณมีอิสระที่จะเจาะลึกลงไปในฐานรหัสผูกมัดกันทุกสิ่งที่คุณต้องการ? ไม่ได้เชนเข้าด้วยกันเฉพาะสิ่งที่ตั้งใจไว้ด้วยกัน มิฉะนั้นโซ่อาจเปลี่ยนแปลงและทันใดนั้นสิ่งของคุณก็แตก นี่คือความหมายของเพื่อน
โซ่ยาวสามารถออกแบบมาเพื่อ อินเทอร์เฟซที่คล่องแคล่ว iDSL Java8 ส่วนใหญ่และ StringBuilder เก่าที่ดีล้วนมีไว้เพื่อให้คุณสร้างเครือข่ายยาว ๆ พวกเขาไม่ได้ละเมิด LoD เพราะทุกสิ่งในโซ่มีไว้เพื่อทำงานร่วมกันและสัญญาว่าจะทำงานร่วมกันต่อไป คุณละเมิดความผิดทางอาญาเมื่อคุณรวมกลุ่มสิ่งที่ไม่เคยได้ยินซึ่งกันและกัน เพื่อนคือคนที่สัญญาว่าจะทำให้ห่วงโซ่คุณทำงานได้ เพื่อนของเพื่อนไม่ได้
นอกเหนือจากคลาสที่ได้รับการแต่งตั้งเป็นพิเศษเพื่อส่งคืนวัตถุ - เช่นคลาสจากโรงงานและตัวสร้าง - มันไม่เป็นไรสำหรับวิธีการส่งคืนวัตถุเช่นวัตถุที่จัดขึ้นโดยคุณสมบัติอย่างใดอย่างหนึ่งของชั้นเรียนหรือจะละเมิดกฎของ demeter (1) ?
สิ่งนี้จะสร้างโอกาสที่จะละเมิด Demeter เท่านั้น นี่ไม่ใช่การละเมิด มันไม่ได้เลวร้ายเสมอไป
และถ้ามันละเมิดกฏหมายของ demeter มันจะสำคัญไหมถ้าวัตถุที่ส่งคืนนั้นเป็นวัตถุที่ไม่เปลี่ยนรูปซึ่งแสดงถึงชิ้นส่วนของข้อมูลและไม่มีอะไรนอกจาก getters สำหรับข้อมูลนี้ (2)?
ไม่เปลี่ยนรูปเป็นสิ่งที่ดี แต่ไม่เกี่ยวข้องที่นี่ การทำสิ่งต่าง ๆ ผ่านสายโซ่ที่ยาวขึ้นไม่ได้ทำให้ดีขึ้น สิ่งที่ทำให้ดีขึ้นคือการแยกการได้รับจากการใช้งาน หากคุณกำลังใช้ขอสิ่งที่คุณต้องการเป็นพารามิเตอร์ อย่าไปตามล่าหามันโดยการเจาะเข้าไปในผู้บุกรุกของคนแปลกหน้า
ในรหัสหลอก:
ฉันสงสัยว่ากฎหมายของ Demeter ห้ามรูปแบบดังกล่าวข้างต้น ฉันจะทำอย่างไรเพื่อให้มั่นใจว่าสามารถเรียก doSomethingElse () ในขณะที่ไม่ละเมิดกฎหมาย (3)
ก่อนที่ฉันจะพูดเกี่ยวกับx.doSomethingElse(a)
ความเข้าใจว่าคุณได้เขียนพื้นฐาน
b.getA().doSomething()
ตอนนี้LoD ไม่ได้ออกกำลังกายที่จุดนับ แต่เมื่อคุณสร้างห่วงโซ่ที่คุณกำลังจะบอกว่าคุณรู้วิธีการที่จะได้รับA
(โดยการใช้B
) A
และคุณรู้วิธีการใช้ ตอนนี้A
และB
ควรเป็นเพื่อนสนิทกันดีกว่าเพราะคุณแค่จับคู่พวกเขาเข้าด้วยกัน
ถ้าคุณได้ถามเพียงแค่บางสิ่งบางอย่างที่จะถึงมือคุณA
ชอบสิ่งที่คุณสามารถใช้A
และจะไม่ได้รับการดูแลมันมาจากไหนและB
จะมีชีวิตที่มีความสุขในชีวิตและเป็นอิสระจากความหลงใหลของคุณกับการได้รับจากA
B
สำหรับx.doSomethingElse(a)
รายละเอียดที่x
มาจากไหน LoD ไม่มีอะไรจะพูดเกี่ยวกับมัน
LoD สามารถกระตุ้นให้การใช้งานแยกจากการก่อสร้าง แต่ฉันจะชี้ให้เห็นว่าถ้าคุณปฏิบัติต่อวัตถุทุกอย่างที่ไม่เป็นมิตรคุณจะต้องเขียนรหัสด้วยวิธีการคงที่ คุณสามารถสร้างกราฟวัตถุที่ซับซ้อนอย่างน่าอัศจรรย์ในหลักด้วยวิธีนี้ แต่ในที่สุดคุณจะต้องเรียกวิธีการในการเริ่มต้นสิ่งที่ทำงาน คุณเพียงแค่ต้องตัดสินใจว่าเพื่อนของคุณคือใคร ไม่มีการหลีกหนีจากสิ่งนั้น
ใช่คลาสได้รับอนุญาตให้ส่งคืนหนึ่งในสมาชิกภายใต้ LoD เมื่อคุณควรชัดเจนว่าสมาชิกคนนั้นเป็นมิตรกับชั้นเรียนของคุณเพราะถ้าไม่ลูกค้าบางรายอาจลองเชื่อมโยงคุณกับชั้นเรียนโดยใช้คุณเพื่อให้ได้ก่อนที่จะใช้ นั่นเป็นสิ่งสำคัญเพราะตอนนี้สิ่งที่คุณกลับมาต้องสนับสนุนการใช้งานนั้นเสมอ
มีหลายกรณีที่สิ่งนี้ไม่น่าเป็นห่วง คอลเลกชันสามารถเพิกเฉยสิ่งนี้ได้เพราะพวกเขาตั้งใจจะเป็นเพื่อนกับทุกสิ่งที่ใช้พวกเขา วัตถุที่มีคุณค่าในทำนองเดียวกันนั้นเป็นมิตรกับทุกคน แต่ถ้าคุณเขียนยูทิลิตีการตรวจสอบความถูกต้องของที่อยู่ซึ่งเรียกร้องให้พนักงานของวัตถุนั้นดึงข้อมูลที่อยู่ออกมาจากนั้นก็แค่ขอที่อยู่คุณก็หวังว่าพนักงานและที่อยู่ทั้งสองจะมาจากห้องสมุดเดียวกัน