แนวคิดในการตั้งชื่อคลาสที่มีคำต่อท้าย“ ข้อมูล” เช่น:“ SomeClass” และ“ SomeClassInfo” คืออะไร


20

ฉันกำลังทำงานในโปรเจ็กต์ที่เกี่ยวข้องกับอุปกรณ์ทางกายภาพและฉันสับสนว่าจะตั้งชื่อคลาสบางคลาสในโครงการนี้ได้อย่างไร

เมื่อพิจารณาถึงอุปกรณ์จริง (เซ็นเซอร์และตัวรับสัญญาณ) เป็นสิ่งหนึ่งและการเป็นตัวแทนของพวกเขาในซอฟต์แวร์นั้นเป็นอีกสิ่งหนึ่ง

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

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

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

ภาษาที่ฉันทำงานด้วยคือ. NET และรูปแบบการตั้งชื่อนี้ดูเหมือนจะเป็นเรื่องทั่วไปตลอดทั้งเฟรมเวิร์กสำหรับตัวอย่างของคลาสเหล่านี้:

  • DirectoryและDirectoryInfoชั้นเรียน
  • FileและFileInfoชั้นเรียน
  • ConnectionInfoชั้นเรียน (ไม่มีConnectionชั้นเรียนผู้สื่อข่าว);
  • DeviceInfoชั้นเรียน (ไม่มีDeviceชั้นเรียนผู้สื่อข่าว);

ดังนั้นคำถามของฉันคือ: มีเหตุผลทั่วไปเกี่ยวกับการใช้รูปแบบการตั้งชื่อนี้หรือไม่? มีกรณีที่เหมาะสมหรือไม่ที่จะมีชื่อคู่ ( ThingและThingInfo) และกรณีอื่น ๆ ที่ควรมีอยู่เฉพาะThingInfoคลาสหรือThingคลาสโดยไม่มีคู่


5
เบ็นอารอนสันได้คำตอบที่ถูกต้องด้านล่าง Infoต่อท้ายที่แตกต่างstaticระดับที่มีวิธีการยูทิลิตี้จากคู่ stateful ของมัน มันไม่ใช่ "แนวปฏิบัติที่ดีที่สุด" เช่นนี้ มันเป็นเพียงวิธีที่ทีม. NET สร้างขึ้นมาเพื่อแก้ปัญหาเฉพาะ พวกเขาจะได้อย่างง่ายดายเพียงแค่ขึ้นมาด้วยFileUtilityและFileแต่File.DoSomething()และFileInfo.FileNameดูเหมือนจะอ่านดีกว่า
Robert Harvey

1
เป็นที่น่าสังเกตว่านี่เป็นรูปแบบทั่วไป แต่มีรูปแบบการตั้งชื่อที่แตกต่างกันมากเนื่องจากมีภาษาและ API ยกตัวอย่างเช่นใน Java ถ้าคุณมีคลาสที่Fooไม่เหมาะสมคุณอาจมีคลาสยูทิลิตี้ที่Foosไม่สามารถใช้งานได้ทันที เมื่อพูดถึงการตั้งชื่อสิ่งสำคัญคือความสอดคล้องภายใน API และนึกคิดข้าม APIs บนแพลตฟอร์ม
เควิน Krumwiede

1
จริงๆ? "ไม่มีใครแนะนำให้ตั้งชื่อคลาส EmployeeInfo" ?? ไม่มีใคร? ดูเหมือนจะแข็งแกร่งเล็กน้อยสำหรับบางสิ่งที่ไม่ชัดเจน
ThePopMachine

@ThePopMachine ฉันเห็นด้วยกับคำว่า "ไม่มีใคร" อาจจะยากเกินไปในกรณีนี้ แต่Employeeมีตัวอย่างมากมายหลายสิบไม่ว่าจะออนไลน์หรือในหนังสือคลาสสิกในขณะที่ฉันยังไม่ได้เห็นEmployeeInfo(อาจเป็นเพราะพนักงานเป็นสิ่งมีชีวิตไม่ใช่ โครงสร้างทางเทคนิคเช่นการเชื่อมต่อหรือไฟล์) แต่ตกลงถ้าชั้นEmployeeInfoจะเสนอในโครงการฉันเชื่อว่ามันจะมีประโยชน์
heltonbiker

คำตอบ:


21

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

คุณพยายามทำตัวเป็นแบบอะไรที่นี่จริง ๆ ? คุณต้องการวัตถุที่แสดงถึงฮาร์ดแวร์ในซอฟต์แวร์เพื่อให้รหัสอื่นสามารถใช้งานได้

นั่นเป็นเรื่องง่ายที่จะพูด แต่เมื่อคุณค้นพบว่ามีมากกว่านั้น "การแทนฮาร์ดแวร์" นั้นกว้างอย่างน่าประหลาดใจ วัตถุที่มีข้อกังวลหลายประการ:

  • การสื่อสารอุปกรณ์ระดับต่ำไม่ว่าจะเป็นการพูดคุยกับอินเตอร์เฟส USB, พอร์ตอนุกรม, TCP / IP หรือการเชื่อมต่อที่เป็นกรรมสิทธิ์
  • ผู้จัดการรัฐ อุปกรณ์เปิดอยู่หรือไม่ พร้อมที่จะคุยกับซอฟต์แวร์หรือยัง ไม่ว่าง?
  • การจัดการเหตุการณ์ อุปกรณ์ผลิตข้อมูล: ตอนนี้เราต้องสร้างกิจกรรมเพื่อส่งผ่านไปยังคลาสอื่น ๆ ที่สนใจ

อุปกรณ์บางอย่างเช่นเซ็นเซอร์จะมีความกังวลน้อยกว่าการพูดของอุปกรณ์มัลติฟังก์ชั่นเครื่องพิมพ์ / สแกนเนอร์ / แฟกซ์ เซ็นเซอร์มีแนวโน้มที่จะสร้างกระแสบิตในขณะที่อุปกรณ์ที่ซับซ้อนอาจมีโปรโตคอลที่ซับซ้อนและการมีปฏิสัมพันธ์

อย่างไรก็ตามกลับไปที่คำถามเฉพาะของคุณมีหลายวิธีในการทำเช่นนี้ขึ้นอยู่กับข้อกำหนดเฉพาะของคุณรวมถึงความซับซ้อนของการโต้ตอบกับฮาร์ดแวร์

นี่คือตัวอย่างของวิธีที่ฉันจะออกแบบลำดับชั้นของชั้นเรียนสำหรับเซ็นเซอร์อุณหภูมิ:

  • ITemperatureSource: อินเทอร์เฟซที่แสดงถึงสิ่งใดก็ตามที่สามารถสร้างข้อมูลอุณหภูมิ: เซ็นเซอร์อาจเป็นไฟล์หุ้มหรือข้อมูลที่เขียนโค้ดยาก (คิดว่า: การทดสอบจำลอง)

  • Acme4680Sensor: เซ็นเซอร์รุ่น ACME 4680 (เหมาะสำหรับการตรวจจับเมื่อมี Roadrunner อยู่ใกล้เคียง) สิ่งนี้อาจใช้หลายอินเตอร์เฟส: บางทีเซ็นเซอร์นี้ตรวจจับทั้งอุณหภูมิและความชื้น วัตถุนี้มีสถานะระดับโปรแกรมเช่น "มีการเชื่อมต่อเซ็นเซอร์หรือไม่?" และ "สิ่งสุดท้ายที่อ่านคืออะไร"

  • Acme4680SensorComm: ใช้แต่เพียงผู้เดียวสำหรับการสื่อสารกับอุปกรณ์ทางกายภาพ มันไม่ได้รักษาสถานะมาก มันใช้สำหรับการส่งและรับข้อความ มันมีวิธี C # สำหรับแต่ละข้อความที่ฮาร์ดแวร์เข้าใจ

  • HardwareManager: ใช้สำหรับรับอุปกรณ์ นี่คือโรงงานที่เก็บอินสแตนซ์: ควรมีเพียงหนึ่งอินสแตนซ์ของวัตถุอุปกรณ์สำหรับแต่ละอุปกรณ์ฮาร์ดแวร์ มันต้องฉลาดพอที่จะรู้ว่าถ้าเธรด A ร้องขอเซ็นเซอร์อุณหภูมิ ACME และเธรด B ร้องขอเซ็นเซอร์ความชื้น ACME จริง ๆ แล้วเป็นวัตถุเดียวกันและควรส่งคืนไปยังเธรดทั้งสอง


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

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

หนึ่งระดับด้านล่างนี้เป็นคลาสจริงที่ใช้อินเทอร์เฟซเหล่านั้น: พวกเขาเป็นตัวแทนของอุปกรณ์หนึ่งที่คล้ายกับ Acme4680Sensor I ที่อธิบายไว้ข้างต้น คลาสใด ๆ โดยเฉพาะอาจใช้หลายอินเตอร์เฟสถ้าอุปกรณ์สามารถทำหน้าที่หลายอย่าง

แต่ละคลาสอุปกรณ์มีคลาส Comm (การสื่อสาร) ส่วนตัวที่จัดการงานระดับต่ำของการพูดคุยกับฮาร์ดแวร์

ด้านนอกของโมดูลฮาร์ดแวร์เลเยอร์เดียวที่มองเห็นได้คืออินเตอร์เฟส / enum รวมถึง HardwareManager ชั้นตัว hardware manager เป็นนามธรรมโรงงานที่จับ instantiation ของการเรียนอุปกรณ์แคชอินสแตนซ์ (คุณจริงๆไม่ต้องการสองชั้นเรียนอุปกรณ์การพูดคุยกับอุปกรณ์ฮาร์ดแวร์เดียวกัน) เป็นต้นชั้นที่ต้องการประเภทเฉพาะของเซ็นเซอร์ถามตัว hardware manager ที่จะได้รับ อุปกรณ์สำหรับ enum ที่เฉพาะเจาะจงซึ่งจะเป็นตัวกำหนดว่ามันอินสแตนซ์อยู่แล้วหากไม่ใช่วิธีการสร้างและเริ่มต้น ฯลฯ

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


ตัวอย่างแผนภาพคลาส UML แสดงการออกแบบที่อธิบายไว้ในคำตอบนี้

หมายเหตุ: มีการเชื่อมโยงระหว่าง HardwareManager และอุปกรณ์แต่ละคลาสที่ฉันไม่ได้วาดเพราะแผนภาพจะกลายเป็นซุปลูกศร


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

ฉันเพิ่มไดอะแกรมคลาส UML สิ่งนี้ช่วยได้ไหม?

2
ฉันจะบอกว่านี่เป็นคำตอบที่นักฆ่าและไม่เพียง แต่จะช่วยฉันได้มาก แต่ฉันเชื่อว่าสามารถช่วยผู้คนได้มากขึ้นในอนาคต นอกจากนี้ตัวอย่างลำดับชั้นของชั้นที่คุณให้แผนที่ของปัญหาและโดเมนการแก้ปัญหาของเราอย่างน่าทึ่ง ขอบคุณมากอีกครั้ง!
heltonbiker

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

11

อาจเป็นเรื่องยากเล็กน้อยที่จะหาการประชุมแบบรวมเป็นหนึ่งเดียวที่นี่เพราะคลาสเหล่านี้กระจายออกไปทั่วเนมสเปซจำนวนมาก ( ConnectionInfoดูเหมือนจะอยู่ในCrystalDecisionsและDeviceInfoในSystem.Reporting.WebForms)

แม้ว่าการดูตัวอย่างเหล่านี้ดูเหมือนจะมีการใช้คำต่อท้ายที่ต่างกันสองแบบ:

  • แยกแยะคลาสที่จัดเตรียมเมธอดแบบสแตติกกับคลาสที่จัดเตรียมเมธอดอินสแตนซ์ นี่เป็นกรณีสำหรับSystem.IOคลาสตามที่ขีดเส้นใต้โดยคำอธิบาย:

    ไดเรกทอรี :

    เปิดเผยวิธีการคงที่สำหรับการสร้างการย้ายและการแจงนับผ่านไดเรกทอรีและไดเรกทอรีย่อย คลาสนี้ไม่สามารถสืบทอดได้

    DirectoryInfo :

    แสดงวิธีการอินสแตนซ์สำหรับการสร้างการย้ายและการแจงนับผ่านไดเรกทอรีและไดเรกทอรีย่อย คลาสนี้ไม่สามารถสืบทอดได้

    Infoดูเหมือนว่าเป็นทางเลือกที่แปลกออกไปเล็กน้อยที่นี่ แต่มันจะสร้างความแตกต่างที่ค่อนข้างชัดเจนคือDirectoryระดับพอทั้งเป็นตัวแทนของไดเรกทอรีโดยเฉพาะอย่างยิ่งหรือให้วิธีการช่วยเหลือไดเรกทอรีที่เกี่ยวข้องทั่วไปโดยไม่ต้องถือสถานะใด ๆ ในขณะที่DirectoryInfoสามารถเท่านั้นจริงๆเป็นอดีต

  • เน้นว่าคลาสเก็บข้อมูลเท่านั้นและไม่ได้จัดเตรียมลักษณะการทำงานที่อาจถูกคาดหวังจากชื่อที่ไม่ได้ต่อท้าย

    ผมคิดว่าส่วนสุดท้ายของประโยคที่อาจเป็นชิ้นส่วนของจิ๊กซอว์ที่แตกต่าง, กล่าวว่าจากConnectionInfo EmployeeInfoถ้าฉันมีชั้นเรียนที่เรียกว่าConnectionฉันคาดหวังว่ามันจะให้ฟังก์ชั่นการเชื่อมต่อที่ฉันมี - ฉันกำลังมองหาวิธีการเช่นvoid Open()ฯลฯ อย่างไรก็ตามไม่มีใครในใจที่ถูกต้องของพวกเขาจะคาดหวังว่าEmployeeชั้นเรียนจริง ๆ ทำในสิ่งที่จริงEmployeeไม่หรือมองหาวิธีการเช่นหรือvoid DoPaperwork()bool TryDiscreetlyBrowseFacebook()


1
ขอบคุณมากสำหรับคำตอบของคุณ! ฉันเชื่อว่าสัญลักษณ์แสดงหัวข้อย่อยแรกในคำตอบของคุณจะอธิบายสิ่งที่เกิดขึ้นใน. NET คลาส แต่อย่างที่สองมีค่ามากขึ้น (และโดยวิธีจะแตกต่างกัน) เพราะมันแสดงให้เห็นถึงนามธรรมที่ดีกว่า: สิ่งที่จะใช้กับ สิ่งที่จะอธิบาย มันยากที่จะเลือกคำตอบที่จะยอมรับ
heltonbiker

4

โดยทั่วไปInfoวัตถุห่อหุ้มข้อมูลเกี่ยวกับสถานะของวัตถุในขณะที่ในบางเวลา ถ้าฉันขอให้ระบบดูไฟล์และให้FileInfoวัตถุที่เกี่ยวข้องกับขนาดของมันฉันคาดหวังว่าวัตถุนั้นจะรายงานขนาดของไฟล์ในเวลาที่มีการร้องขอ (หรือเพื่อให้แม่นยำมากขึ้นขนาดของ ไฟล์ในบางช่วงเวลาระหว่างที่มีการโทรออกและเมื่อมันกลับมา) หากขนาดของไฟล์เปลี่ยนแปลงระหว่างเวลาที่คำขอส่งคืนและเวลาที่FileInfoตรวจสอบวัตถุฉันจะไม่คาดหวังว่าการเปลี่ยนแปลงดังกล่าวจะปรากฏในFileInfoวัตถุ

โปรดทราบว่าพฤติกรรมนี้จะแตกต่างอย่างมากจากFileวัตถุ หากการร้องขอให้เปิดไฟล์ดิสก์ในโหมดที่ไม่ผูกขาดให้Fileวัตถุที่มีSizeคุณสมบัติฉันคาดหวังว่าค่าที่ส่งคืนจะเปลี่ยนดังนั้นเมื่อขนาดของไฟล์ดิสก์เปลี่ยนแปลงเนื่องจากFileวัตถุไม่เพียงแสดงสถานะของ ไฟล์ - มันหมายถึงไฟล์ที่ตัวเอง

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


1
สิ่งนี้ไม่ถูกต้อง แต่ไม่ได้อธิบายรูปแบบการตั้งชื่อของ. NET ได้เป็นอย่างดีเนื่องจากFileคลาสไม่สามารถสร้างอินสแตนซ์ได้และFileInfoวัตถุจะอัปเดตด้วยระบบไฟล์พื้นฐาน
Nathan Tuggy

@NathanTuggy ฉันยอมรับว่านี่ไม่เกี่ยวข้องกับการตั้งชื่อนี้ใน. NET แต่เกี่ยวกับปัญหาปัจจุบันของฉันฉันเชื่อว่ามันมีความเกี่ยวข้องมากและอาจทำให้เกิดโซลูชั่นที่สอดคล้องกัน ฉัน upvoted คำตอบนี้ แต่มันเป็นเรื่องยากที่จะเลือกเพียงหนึ่งเดียวที่จะยอมรับ ...
heltonbiker

@NathanTuggy: ฉันไม่แนะนำให้ใช้. NET ในรูปแบบของความสอดคล้องใด ๆ เป็นกรอบงานที่ดีและมีประโยชน์ซึ่งสรุปความคิดที่ดีมากมาย แต่ความคิดที่ไม่ดีบางอย่างเข้ามารวมกันด้วย
supercat

@supercat: แน่นอน; ดูเหมือนแปลกที่จะตอบคำถามเกี่ยวกับ "ทำไม. NET ทำสิ่งนี้ทาง?" ด้วย "คงเป็นความคิดที่ดีที่จะทำสิ่งนี้% this_WAY%"
นาธาน Tuggy

@NathanTuggy: ฉันไม่จำรายละเอียดที่แน่นอนของชั้นเรียนที่สงสัย แต่ฉันคิดว่าFileInfoเพียงแค่เก็บข้อมูลที่จับได้แบบคงที่ มันไม่ได้เหรอ? นอกจากนี้ฉันไม่เคยมีโอกาสที่จะเปิดไฟล์ในโหมดที่ไม่เฉพาะ แต่ควรจะเป็นไปได้และฉันคาดว่าจะมีวิธีการที่จะรายงานขนาดปัจจุบันของไฟล์แม้ว่าวัตถุที่ใช้สำหรับการเปิดไม่ได้ เรียกว่าFile(ปกติผมใช้เพียงReadAllBytes, WriteAllBytes, ReadAllText, WriteAllTextฯลฯ )
supercat

2

เมื่อพิจารณาถึงอุปกรณ์จริง (เซ็นเซอร์และตัวรับสัญญาณ) เป็นสิ่งหนึ่งและการเป็นตัวแทนของพวกเขาในซอฟต์แวร์นั้นเป็นอีกสิ่งหนึ่ง

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

ฉันไม่ชอบความแตกต่างนี้ วัตถุทั้งหมดคือ "การแสดง [s] ในซอฟต์แวร์" นั่นคือความหมายของคำว่า "วัตถุ"

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

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

ทรัพยากรระบบไฟล์เช่นไดเรกทอรีในความคิดของฉันอยู่ใกล้กับขอบนี้มาก มีบางสถานการณ์ที่คุณต้องการอธิบายถึงไดเรกทอรีที่ไม่สามารถเข้าถึงได้ในพื้นที่จริง แต่นักพัฒนาโดยเฉลี่ยอาจไม่ได้อยู่ในสถานการณ์เหล่านั้น ความซับซ้อนของโครงสร้างชั้นเรียนในแบบนี้คือในความคิดของฉันไม่ช่วยเหลือ Contrast Python เข้าใกล้pathlib: มีคลาสเดียวที่ "น่าจะเป็นสิ่งที่คุณต้องการ" และคลาสเสริมต่าง ๆ ซึ่งผู้พัฒนาส่วนใหญ่สามารถเพิกเฉยได้อย่างปลอดภัย หากคุณต้องการพวกเขาจริงๆพวกเขาให้อินเตอร์เฟซเดียวกันส่วนใหญ่เพียงแค่มีวิธีการที่เป็นรูปธรรม


ขอบคุณสำหรับคำตอบของคุณและขอชื่นชมสำหรับ "have-a" build;) คำตอบของคุณทำให้ฉันนึกถึงความรู้สึกไม่สบายที่เกิดจากแนวคิด "DTO" (Data Transfer Object) - หรือพี่น้องของพารามิเตอร์ Parameter - ซึ่งมันขมวดคิ้ว โดย zealots OO ดั้งเดิมมากขึ้นเพราะมันมักจะไม่ได้มีวิธีการ (หลังจากทั้งหมดมันเป็นวัตถุการถ่ายโอนข้อมูล ) ในแง่นั้นและสรุปสิ่งที่คนอื่นพูดด้วยฉันคิดว่าSensorInfoมันจะเป็น DTO และ / หรือเช่น "snapshot" หรือแม้แต่ "spec" ซึ่งแสดงเฉพาะส่วนข้อมูล / สถานะของSensorวัตถุจริงว่า "อาจจะไม่ได้อยู่ที่นั่น"
heltonbiker

เช่นเดียวกับปัญหาการออกแบบส่วนใหญ่ไม่มีกฎที่ยากและรวดเร็ว ในตัวอย่าง pathlib ที่ฉันให้ไว้PureWindowsPathทำหน้าที่คล้ายวัตถุข้อมูล แต่มีวิธีการทำสิ่งต่าง ๆ ที่ไม่จำเป็นต้องใช้ระบบ Windows (เช่นการทำไดเรกทอรีย่อยแยกส่วนขยายไฟล์ ฯลฯ ) สิ่งนี้มีประโยชน์มากกว่าเพียงแค่ให้โครงสร้างที่น่ายกย่อง
เควิน

1
อีกครั้งรุ่งโรจน์สำหรับส่วน "ชื่นชมโครงสร้าง" :) นั่นทำให้ฉันนึกถึงคำพูดที่เกี่ยวข้องจากหนังสือ "Clean Code" ของลุงบ๊อบบทที่ 6: "โปรแกรมเมอร์ผู้ใหญ่รู้ว่าความคิดที่ว่าทุกอย่างเป็นวัตถุเป็นตำนานบางครั้งคุณต้องการโครงสร้างข้อมูลแบบง่าย ๆ
heltonbiker

2

ฉันจะบอกว่าบริบท / โดเมนมีความสำคัญเนื่องจากเรามีรหัสตรรกะทางธุรกิจระดับสูงและโมเดลระดับต่ำส่วนประกอบสถาปัตยกรรมและอื่น ๆ ...

'Info', 'Data', 'Manager', 'Object', 'Class', 'Model', 'Controller' เป็นต้นสามารถส่งต่อท้ายโดยเฉพาะอย่างยิ่งในระดับที่ต่ำกว่าเนื่องจากวัตถุทุกชิ้นมีข้อมูลหรือข้อมูลดังนั้น ข้อมูลนั้นไม่จำเป็น

ชื่อคลาสของโดเมนธุรกิจควรเป็นเหมือนที่ผู้มีส่วนได้ส่วนเสียทุกคนพูดถึงไม่ว่าจะฟังดูแปลกหรือเป็นภาษาที่ไม่ถูกต้อง 100%

ส่วนต่อท้ายที่ดีสำหรับโครงสร้างข้อมูลเช่น 'รายการ', 'แผนที่' และสำหรับรูปแบบที่บอกใบ้ 'มัณฑนากร', 'อะแดปเตอร์' หากคุณคิดว่าจำเป็น

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

จุดอื่น:

มีเพียงสองสิ่งที่ยากในวิทยาการคอมพิวเตอร์คือ: การตรวจสอบแคชและการตั้งชื่อสิ่ง

- ฟิลคาร์ลตัน

มันทำให้ฉันนึกถึงชื่อเพียงไม่กี่วินาทีและถ้าฉันไม่พบชื่อใดฉันก็ใช้ชื่อแปลก ๆ และ 'todo'- ทำเครื่องหมายไว้ ฉันสามารถเปลี่ยนได้ในภายหลังเนื่องจาก IDE ของฉันให้การสนับสนุนการปรับโครงสร้างใหม่ มันไม่ใช่สโลแกนของ บริษัท ที่ต้องดี แต่แค่บางรหัสที่เราสามารถเปลี่ยนได้ทุกครั้งที่เราต้องการ เก็บไว้ในใจ


1

ThingInfo สามารถใช้เป็นพร็อกซีสำหรับอ่านอย่างเดียวที่ยอดเยี่ยม

ดูhttp://www.dofactory.com/net/proxy-design-pattern

พร็อกซี: "ระบุตัวแทนหรือตัวยึดสำหรับวัตถุอื่นเพื่อควบคุมการเข้าถึง"

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

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


ยอดเยี่ยม ก่อนหน้าวันนี้ฉันวิเคราะห์ความต้องการด้านสถาปัตยกรรมของฉันเกี่ยวกับชั้นเรียนที่ฉันใช้ในคำถามและมาถึงข้อสรุปเดียวกันนี้ ในกรณีของฉันฉันมีหนึ่งReceiverที่ได้รับกระแสข้อมูลจากหลายSensorๆ ความคิดคือ: ผู้รับควรนามธรรมเซ็นเซอร์ที่เกิดขึ้นจริง แต่ปัญหาคือ: ฉันต้องการข้อมูลเซ็นเซอร์เพื่อให้ฉันสามารถเขียนลงในส่วนหัวของไฟล์ วิธีการแก้ปัญหาแต่ละจะมีรายชื่อของIReceiver SensorInfoถ้าผมส่งคำสั่งไปยังผู้รับซึ่งบ่งบอกเปลี่ยนสถานะเซ็นเซอร์การเปลี่ยนแปลงเหล่านี้จะสะท้อนให้เห็น (ผ่าน getter) SensorInfoบนตามลำดับ
heltonbiker

(ต่อ ... ) นั่นคือ: ฉันไม่ได้พูดคุยกับเซ็นเซอร์ตัวเองฉันพูดคุยกับผู้รับผ่านคำสั่งระดับสูงเท่านั้นและผู้รับจะพูดคุยกับเซ็นเซอร์แต่ละตัว แต่ในที่สุดฉันก็ต้องการข้อมูลจากเซ็นเซอร์ซึ่งฉันได้รับจากอินสแตนซ์ของตัวรับผ่านList<SensorInfo>คุณสมบัติแบบอ่านอย่างเดียว
heltonbiker

1

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

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

Employeeความคมชัดที่มีระดับที่ชื่อว่า นี่อาจเป็นวัตถุเอนทิตี ORM และเป็นวัตถุเดียวที่อธิบายถึงพนักงานคนนั้น EmployeeInfoถ้ามันเป็นค่าวัตถุโดยไม่ต้องตัวตนของมันควรจะเรียกว่า อันEmployeeไม่ได้เป็นตัวแทนของพนักงานจริง คลาส DTO ที่มีค่าเหมือนกันที่เรียกว่าEmployeeInfoจะไม่ได้เป็นตัวแทนของพนักงานอย่างชัดเจน แต่จะอธิบายหรือเก็บข้อมูลเกี่ยวกับมัน

มีตัวอย่างจริงใน BCL ที่มีคลาสทั้งสองอยู่: A ServiceControllerเป็นคลาสที่อธิบายบริการของ Windows สามารถมีคอนโทรลเลอร์จำนวนเท่าใดก็ได้สำหรับแต่ละบริการ A ServiceBase(หรือคลาสที่ได้รับ) เป็นบริการจริงและไม่เข้าใจว่ามีหลายอินสแตนซ์ต่อบริการที่แตกต่างกัน


เสียงนี้คล้ายกับProxyรูปแบบที่ @Shmoken พูดไว้ใช่ไหม
heltonbiker

@heltonbiker ไม่จำเป็นต้องเป็นพร็อกซี อาจเป็นวัตถุที่ไม่ได้เชื่อมต่อกับสิ่งที่อธิบาย ตัวอย่างเช่นคุณอาจได้รับEmployeeInfoจากบริการเว็บ นั่นไม่ใช่พร็อกซี ตัวอย่างต่อไป: การAddressInfoไม่ได้มีสิ่งที่จะสามารถพร็อกซี่เพราะที่อยู่ไม่ได้เป็นกิจการ มันเป็นค่าแบบสแตนด์อโลน
usr

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