ทำไมเราจึงควรใช้คอลเลกชันชั้นหนึ่ง?


15

ตามกฎข้อที่ 4 ของObject Calisthenics โดย Jeff Bay (RTF)ใน The ThoughtWorks Anthology ขอแนะนำว่าควร " ใช้คอลเลกชันชั้นหนึ่ง "

กฎข้อที่ 4: คอลเลกชันชั้นหนึ่ง

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

สิ่งที่ฉันสามารถเข้าใจได้จากสิ่งนี้คือเราควรใช้คลาสแยกการรวบรวมคอลเลกชันและด้วยวิธีการเพิ่มลบแก้ไขข้อมูลของคอลเลกชันนั้น

และเราต้องการสิ่งนี้เพื่อให้เราแน่ใจว่าประเภทข้อมูลใดที่จะเข้าสู่การรวบรวมและสิ่งที่ออกมา

ในกรณีที่เราใช้การรวบรวมทั่วไป (ในภาษาที่ใช้ได้) เราจำเป็นต้องปฏิบัติตามกฎนี้หรือไม่?

หากฉันขาดความสำคัญที่สำคัญโปรดชี้แจง


1
Amogh Talpallikar ฉันเปลี่ยนกฎ 8 เป็นกฎ 4 เนื่องจากกฎ 8 เป็นจริง "ไม่มีคลาสที่มีตัวแปรอินสแตนซ์มากกว่าสอง"
yannis

ดูเหมือนว่าจะพูดกฎข้อที่ 8ในสารบัญแล้วเรียกมันว่ากฎข้อที่ 4ในร่างกาย
ไร้ประโยชน์

1
ลิงก์ที่ดีกว่าcs.helsinki.fi/u/luontola/tdd-2009/ext/ObjectCalisthenics.pdf ?
Ed James

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

@mjfgates: อืม ... จุดที่ดี! สิ่งที่คิดจริงๆ!
Amogh Talpallikar

คำตอบ:


12

ความปลอดภัยของประเภทเป็นเหตุผลเล็กน้อยที่ใช้คอลเลกชันชั้นหนึ่ง จากลิงค์ของคุณ:

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

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

เหตุผลของเรื่องนี้ค่อนข้างง่ายคอลเลคชั่นมีแนวโน้มที่จะผ่านไปได้ เร็ว ๆ นี้พอ 4 คลาสที่แตกต่างกันมีSearchByID()วิธีการของตนเอง หรือคุณได้รับค่าตอบแทนเช่นเดียวMap<Integer, String>กับบริบทของสิ่งที่เก็บไว้ในแผนที่นั้นหลุดออกไป คอลเลกชันชั้นหนึ่งเป็นทางออกที่ง่ายที่มีค่าใช้จ่ายไฟล์ต้นฉบับเดียว ในทางปฏิบัติเมื่อมีการทดสอบแล้ว (มันง่ายมากในการเขียนการทดสอบหน่วยสำหรับเช่นกัน) การเปลี่ยนแปลงใด ๆ ที่เกี่ยวข้องกับคอลเลกชันนั้นง่ายต่อการจัดการเช่นเมื่อSearchByIDจำเป็นต้องใช้ GUID แทนที่จะเป็น int


8

... ใช้คลาสการแยกคอลเลกชันและด้วยวิธีการเพิ่มลบแก้ไขข้อมูลของคอลเลกชันนั้น

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

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

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

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

ไม่มีอะไรเกี่ยวข้องกับประเภท (หรือข้อมูลทั่วไป) ทุกอย่างที่เกี่ยวข้องกับการเชื่อมโยงพฤติกรรมของคอลเลกชันกับข้อมูล


1

คำตอบง่ายๆคือ"ไม่"ถ้าคุณใช้ภาษาที่รองรับ Generics เนื่องจากไม่จำเป็นต้องตรวจสอบประเภทเนื่องจากคุณสมบัติภาษานั้นใช้งานได้ดีทีเดียว (จากประสบการณ์เกี่ยวกับ Java generics ของฉัน)

แต่ถ้าคุณมีสถานการณ์ใด ๆ ที่คุณต้องการปรับแต่งโครงสร้างข้อมูลที่ได้รับจากภาษาคุณสามารถสร้างคลาส wrapper รอบโครงสร้างข้อมูลดั้งเดิมและเปิดเผย API ของคุณเองและยังคงใช้การใช้งานพื้นฐานของโครงสร้างข้อมูลเดิม


ฉันยังคิดในบรรทัดที่คล้ายกัน แต่ควรมีบางอย่างตัวอย่างที่ฉันเห็นใน Java และ C # และทั้งสองสนับสนุนคอลเลกชันทั่วไป
Amogh Talpallikar

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