ทุกคลาสที่ฉันเขียนติดกับอินเตอร์เฟสหรือไม่?


10

ฉันกำลังเขียนเกมใน typescript และตัดสินใจว่าจะลองทำตามแนวคิดของ " การเขียนโปรแกรมด้วยอินเตอร์เฟส " ซึ่งคุณเขียนโค้ดตามอินเตอร์เฟสแทนการใช้งานของวัตถุ

ฉันเขียนอินเทอร์เฟซจำนวนมากและคลาสที่ใช้งานพวกเขาจากนั้นถอยกลับและตระหนักว่าคลาสนั้นง่ายพอที่ฉันจะไม่ต้องเปลี่ยนการใช้งานเนื่องจากมีวิธีเดียวที่จะทำสิ่งที่ คลาสทำ (เคลื่อนที่Phaser.Spriteในลักษณะที่ จำกัด เพื่อทำตัวเหมือนรถถัง)

จากนั้นฉันจำได้ว่าได้อ่านเมื่อไม่กี่ปีที่ผ่านมาเกี่ยวกับแนวคิดของYAGNIซึ่งโดยพื้นฐานแล้วคุณไม่ควรสร้างรหัสของคุณมากเกินไปเพื่อรวมสิ่งที่คุณไม่เคยใช้

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


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

คำตอบ:


6

เหตุผลของการมีอินเตอร์เฟสเป็นเพราะมันทำให้ polymorphism ง่ายขึ้น หมายความว่าคุณสามารถส่งอินสแตนซ์โดยสัญญาแทนที่จะรู้ว่าการใช้งานจริงของพวกเขา ตัวอย่างเช่นคุณอาจส่ง "Reader" ไปยังวิธีการหนึ่งเพื่อให้วิธีการที่เรียกว่าสามารถใช้วิธีการ "read ()" ด้วยการประกาศอินเทอร์เฟซ "Reader" คุณสามารถทำให้วัตถุใด ๆ เป็นไปตามสัญญานี้โดยใช้วิธีการที่ระบุ ด้วยวิธีนี้ผู้โทรใด ๆ อาจถือว่าวิธีการบางอย่างจะมีอยู่แม้ว่าวัตถุที่อยู่ภายใต้สัญญาอาจแตกต่างกันโดยสิ้นเชิง

การแยกความแตกต่างนี้จากคลาสฐานและทำให้เป็นไปได้เช่นกันระหว่างเส้นขอบโซ่ระดับโดยการทำสัญญา

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

หากคุณมีหนึ่งเชนการสืบทอด (baseclass-> subclass) หรือเพียงแค่ฐานหรือคุณไม่จำเป็นต้องผ่านวัตถุที่เกี่ยวข้องกับคนอื่นหรือใช้พวกมันโดยทั่วไปคุณจะไม่เพิ่มการใช้งานอินเทอร์เฟซ ไร้ประโยชน์


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

7

หากคุณไม่แน่ใจว่าคุณต้องการอินเทอร์เฟซจริงหรือไม่คุณอาจไม่ต้องการ นี่คือแกนหลักของหลักการ YAGNI เมื่อคุณต้องการที่จะสามารถสลับการใช้งานจากนั้นคุณแนะนำอินเทอร์เฟซ


6

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

โดยทั่วไปเราใช้ "อินเตอร์เฟส" เพื่อหมายถึง "คลาส Java ที่กำหนดโดยใช้interfaceคำหลัก" หรือ "คลาส C ++ ที่มีฟังก์ชั่นเสมือนสาธารณะที่บริสุทธิ์เท่านั้น" สิ่งเหล่านี้เป็น abstractions ที่มีประโยชน์เพราะพวกมันแยกอินเทอร์เฟซของคลาสจากการใช้งาน

โดยคำนึงถึงสิ่งนั้นให้ใช้อินเตอร์เฟสเมื่อเหมาะสม

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

  • ฉันจะส่งมอบการใช้งานอินเทอร์เฟซที่เป็นไปได้ให้กับโมดูลอื่น ๆ ที่ไม่ควรรู้ถึงการทำงานภายในของโมดูลของฉันหรือไม่? อินเทอร์เฟซมีประโยชน์ที่นี่เพราะจะลดขนาดของจุดสัมผัสระหว่างโมดูล

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

ที่กล่าวว่ามีส่วนต่อประสานสำหรับทุกสิ่งน่าจะเกินความจริง หากคุณเห็นรูปแบบนี้คุณจะไปไกล:

interface I {
  int getA()
  int getB()
  ...
  int getY()
  int getZ()
}

class C : I {
  int getA() { ... }
  int getB() { ... }
  ...
  int getY() { ... }
  int getZ() { ... }
}

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

@Darien: เหตุผลที่ระบบการทดสอบอาจต้องการส่วนต่อประสานเนื่องจากการทดสอบนั้นใช้การนำไปใช้ (จำลอง) ที่แตกต่างกันซึ่งจะนำคุณกลับไปที่สัญลักษณ์แรกของเมื่อส่วนต่อประสานที่เหมาะสม
Bart van Ingen Schenau

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

@Robbie มันเป็นเรื่องจริงสำหรับ Java เช่นinterfaceกันมันเกิดขึ้นได้ทุกอย่างใน Java interfaceนั้นก็เป็นส่วนต่อประสานสาธารณะ (OO concept)

ทุกคน! เขียนประโยคที่ 2 และ 3 ของคำตอบ ลามิเนตมัน ใส่ไว้ในกระเป๋าของคุณ อ้างอิงบ่อยครั้ง
Radarbob

5

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

มีหลายเหตุผลที่ดีมากที่คุณควรพิจารณาอินเทอร์เฟซสำหรับการพัฒนาที่ใหญ่กว่าแทนที่จะรวบรวมชุดของคลาส

กรอบการเยาะเย้ย

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

ฉีดพึ่งพา

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


วิธีการเหล่านี้มีรายละเอียดในDจากหลักการ SOLID ถูสิ่งนี้คือ - ใช้ abstractions ไม่ใช่ concretions

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


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

@kai "คุณสามารถใช้ DI โดยไม่ต้องใช้ภาชนะ IoC" ฉันคิดว่าร้านพัฒนาที่เป็นผู้ใหญ่มากขึ้นสามารถ (และทำ) ไม่มีความจำเป็นที่จะทำให้รหัสสกปรกสำหรับแนวคิดที่เรียบง่ายอย่างชัดเจน Joelมีมุมมองที่คล้ายกัน
Robbie Dee

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