คำถามติดแท็ก interfaces

คำถามเกี่ยวกับข้อควรพิจารณาเกี่ยวกับการออกแบบส่วนต่อประสานเช่นการเขียนโปรแกรมไปยังส่วนต่อประสาน

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

12
“ ถ้าวิธีการถูกนำมาใช้ใหม่โดยไม่มีการเปลี่ยนแปลงให้ใส่วิธีการในคลาสพื้นฐานมิฉะนั้นสร้างอินเทอร์เฟซ” เป็นกฎที่ดี?
เพื่อนร่วมงานของฉันเกิดขึ้นกับกฎง่ายๆสำหรับการเลือกระหว่างการสร้างชั้นฐานหรืออินเตอร์เฟซ เขาพูดว่า: ลองนึกภาพทุกวิธีการใหม่ที่คุณกำลังจะใช้ สำหรับแต่ละของพวกเขาพิจารณานี้จะใช้วิธีการนี้จะดำเนินการโดยระดับมากกว่าหนึ่งในว่ารูปแบบนี้โดยไม่ต้องใด ๆการเปลี่ยนแปลง? หากคำตอบคือ "ใช่" ให้สร้างคลาสพื้นฐาน ในทุกสถานการณ์ให้สร้างอินเทอร์เฟซ ตัวอย่างเช่น: พิจารณาการเรียนcatและdogซึ่งขยายชั้นเรียนและมีวิธีการเดียวmammal pet()จากนั้นเราจะเพิ่มชั้นเรียนซึ่งไม่ขยายอะไรและมีวิธีการเดียวalligatorslither() ตอนนี้เราต้องการเพิ่มeat()วิธีการทั้งหมดของพวกเขา หากการดำเนินการตามeat()วิธีการที่จะตรงเดียวกันcat, dogและalligatorเราควรสร้างชั้นฐาน (สมมุติว่าanimal) ซึ่งใช้วิธีการนี้ อย่างไรก็ตามหากการติดตั้งใช้งานalligatorแตกต่างกันเล็กน้อยเราควรสร้างIEatส่วนต่อประสานและสร้างmammalและalligatorนำไปใช้งาน เขายืนยันว่าวิธีนี้ครอบคลุมทุกกรณี แต่ดูเหมือนว่าฉันจะทำให้เข้าใจง่ายเกินไป การทำตามกฎของหัวแม่มือนี้มีค่าหรือไม่

5
อินเทอร์เฟซและการสืบทอด: สุดยอดของทั้งสองโลก
ฉันค้นพบอินเทอร์เฟซและฉันเริ่มรักพวกเขา ความสวยงามของอินเทอร์เฟซคือมันเป็นสัญญาและวัตถุใด ๆ ที่ตอบสนองสัญญานั้นสามารถใช้ได้ทุกที่ที่ต้องการอินเตอร์เฟส ปัญหาของอินเทอร์เฟซคือมันไม่สามารถมีการใช้งานเริ่มต้นซึ่งเป็นคุณสมบัติที่เจ็บปวดสำหรับคุณสมบัติทางโลกและกำจัด DRY สิ่งนี้ก็เป็นสิ่งที่ดีเพราะมันทำให้การใช้งานและระบบแยกจากกัน ในทางกลับกันมรดกยังคงรักษาคัปปลิ้งที่แน่นกว่าและมีศักยภาพที่จะทำลายการห่อหุ้ม กรณีที่ 1 (การสืบทอดกับสมาชิกส่วนตัวการห่อหุ้มที่ดีเข้าด้วยกันอย่างแน่นหนา) class Employee { int money_earned; string name; public: void do_work(){money_earned++;}; string get_name(return name;); }; class Nurse : public Employee: { public: void do_work(/*do work. Oops, can't update money_earned. Unaware I have to call superclass' do_work()*/); }; void HireNurse(Nurse *n) …

2
เป็นวิธีที่เหมาะสมในการใช้อินเทอร์เฟซ OnClickListener สำหรับปุ่มมากมายได้อย่างไร
กิจกรรม Android ของฉันมีหลายปุ่มที่ทุกคนต้องมี OnClickListener ฉันเห็นวิธีการต่าง ๆ มากมายเช่น :: การนำอินเตอร์เฟสไปใช้ในคลาสกิจกรรม การสร้างคลาสแยกต่างหากที่ใช้อินเทอร์เฟซ การกำหนดคลาสภายในที่ไม่ระบุชื่อสำหรับแต่ละปุ่ม ฉันเห็นตัวอย่างมากมายของแต่ละวิธี อย่างไรก็ตามมันไม่ชัดเจนสำหรับฉันว่าทำไมจะใช้วิธีการหนึ่งแทนวิธีอื่น ความแตกต่างระหว่างแนวทางเหล่านี้มีโวหารหรือมีเหตุผลที่ทำให้วิธีการหนึ่งดีขึ้นหรือไม่

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

1
ฉันจะโครงสร้างอินเทอร์เฟซเมื่อวัตถุใช้เพียงส่วนหนึ่งของอินเทอร์เฟซได้อย่างไร
ฉันมีโครงการที่ฉันมีสองคลาสที่ทั้งสองต้องการวัตถุเข้าถึงฐานข้อมูลที่ปรับปรุงตารางเดียวกัน ข้อ จำกัด ของกรอบงานและโครงการทำให้เป็นไปไม่ได้ที่จะรวมสองคลาสนี้ ฉันได้สร้างกรณีด้านล่างที่แสดงว่าการตั้งค่าเป็นอย่างไร คลาส A จำเป็นต้องสามารถอัปเดตและอ่านบันทึกในขณะที่คลาส B จำเป็นต้องสามารถอัปเดตและลบบันทึกได้ ถ้าฉันใช้คลาสเหมือนเดิมมันใช้งานได้ดี แต่ฉันมีปัญหากับความจริงที่ว่าแต่ละคลาสต้องการฟังก์ชันการทำงานที่ไม่ได้ใช้งาน ตัวอย่างเช่นในการใช้คลาส A ฉันต้องส่งผ่าน dao ที่ใช้ฟังก์ชั่นลบแม้ว่ามันจะไม่ถูกเรียกใช้ ในทำนองเดียวกันฉันต้องผ่านคลาส B a dao ที่ใช้ฟังก์ชั่นการอ่าน แต่มันจะไม่ถูกเรียก ฉันคิดเกี่ยวกับการเข้าถึงโดยการมีส่วนต่อประสานที่สืบทอดผู้อื่น (IReadDao, IUpdateDao, IDeleteDao เป็น daos ที่จะสืบทอดมาจาก) แต่วิธีการนี้โดยทั่วไปจะต้องใช้อินเทอร์เฟซที่แตกต่างกันสำหรับฟังก์ชั่นแต่ละชุด (IUpdateAndDelete ) ฉันต้องการใช้อินเทอร์เฟซสำหรับ dao เพราะฉันไม่ต้องการเชื่อมโยงแอปพลิเคชันกับฐานข้อมูล มีรูปแบบหรือวิธีการในการบรรลุสิ่งที่ฉันต้องการให้ใครรู้หรือไม่? ขอบคุณล่วงหน้า. class IDao { void update(ModelDao model); void delete(String guid); ModelDao read(String guid); …

3
มันตกลงหรือไม่สำหรับอินเตอร์เฟสที่ต้องพึ่งพาคลาสที่เป็นรูปธรรม?
ฉันกำลังสร้างส่วนติดต่อใน Java สำหรับตัวจัดการข้อผิดพลาดที่กำหนดเอง ต้องการส่งผ่านข้อผิดพลาดวัตถุข้อโต้แย้ง แต่ฉันต้องการมันเป็นลูกของExceptionชั้น จะใช้ชื่อคลาสที่กำหนดในอินเทอร์เฟซได้หรือไม่ มันจะทำให้อินเทอร์เฟซน้อยลงหรือไม่ขึ้นอยู่กับการใช้งานใด ๆ ฉันพยายามทำสิ่งนี้: public class CustomException { /* ... Implementation ... */ } public interface Interface { void onError(CustomException ex); }

2
การเขียนโปรแกรมไปยังอินเทอร์เฟซ Data Oriented
มีบางส่วนของ codebase ของเราเขียนในรูปแบบต่อไปนี้: // IScheduledTask.cs public interface IScheduledTask { string TaskName { get; set; } int TaskPriority { get; set; } List<IScheduledTask> Subtasks { get; set; } // ... several more properties in this vein } // ScheduledTaskImpl.cs public class ScheduledTaskImpl : IScheduledTask { public string TaskName { get; set; …

2
การแยกส่วนอินเทอร์เฟซหลักการ: จะทำอย่างไรถ้าส่วนต่อประสานมีการทับซ้อนกันอย่างมีนัยสำคัญ?
จากการพัฒนาซอฟต์แวร์หลักการรูปแบบและการปฏิบัติ: Pearson New International Edition : บางครั้งวิธีที่เรียกใช้โดยกลุ่มลูกค้าที่แตกต่างกันจะทับซ้อนกัน หากการซ้อนทับมีขนาดเล็กดังนั้นอินเทอร์เฟซสำหรับกลุ่มควรจะแยกจากกัน ควรประกาศฟังก์ชันทั่วไปในอินเทอร์เฟซที่ทับซ้อนกันทั้งหมด คลาสเซิร์ฟเวอร์จะสืบทอดฟังก์ชันทั่วไปจากแต่ละอินเตอร์เฟสเหล่านั้น แต่จะใช้งานเพียงครั้งเดียว ลุงบ๊อบพูดถึงกรณีที่มีการเหลื่อมกันเล็กน้อย เราควรทำอย่างไรหากมีการทับซ้อนอย่างมีนัยสำคัญ บอกว่าเรามี Class UiInterface1; Class UiInterface2; Class UiInterface3; Class UiIterface : public UiInterface1, public UiInterface2, public UiInterface3{}; เราควรทำอย่างไรหากมีการทับซ้อนกันระหว่างUiInterface1และUiInterface2?

5
มันสมเหตุสมผลหรือไม่ที่จะ "โปรแกรมไปยังส่วนต่อประสาน" ใน Java?
ฉันได้เห็นการอภิปรายในคำถามนี้เกี่ยวกับวิธีการที่คลาสที่ใช้จากอินเทอร์เฟซจะถูกยกตัวอย่าง ในกรณีของฉันฉันกำลังเขียนโปรแกรมขนาดเล็กมากใน Java ที่ใช้อินสแตนซ์ของTreeMapและตามความเห็นของทุกคนที่นั่นควรมีอินสแตนซ์เช่น: Map<X> map = new TreeMap<X>(); ในโปรแกรมของฉันฉันกำลังเรียกใช้ฟังก์ชั่นmap.pollFirstEntry()ซึ่งไม่ได้ประกาศในMapอินเทอร์เฟซ (และอีกสองสามคนที่อยู่ในMapอินเทอร์เฟซด้วย) ฉันจัดการเพื่อทำสิ่งนี้ได้โดยการส่งไปยังTreeMap<X>ทุกที่ที่ฉันเรียกวิธีนี้เช่น someEntry = ((TreeMap<X>) map).pollFirstEntry(); ฉันเข้าใจถึงข้อดีของแนวทางการเริ่มต้นตามที่อธิบายไว้ข้างต้นสำหรับโปรแกรมขนาดใหญ่อย่างไรก็ตามสำหรับโปรแกรมขนาดเล็กมากที่วัตถุนี้จะไม่ถูกส่งผ่านไปยังวิธีอื่นฉันคิดว่ามันไม่จำเป็น แต่ถึงกระนั้นฉันกำลังเขียนโค้ดตัวอย่างนี้เป็นส่วนหนึ่งของการสมัครงานและฉันไม่ต้องการให้รหัสของฉันดูไม่ดีหรือรก สิ่งที่จะเป็นทางออกที่หรูหราที่สุด? แก้ไข: TreeMapผมอยากจะชี้ให้เห็นว่าฉันสนใจมากขึ้นในการเข้ารหัสการปฏิบัติที่ดีในวงกว้างแทนของการประยุกต์ใช้ฟังก์ชั่นที่เฉพาะเจาะจง เนื่องจากคำตอบบางข้อได้ชี้ให้เห็นแล้ว (และฉันได้ทำเครื่องหมายเป็นคำตอบแรกให้ทำ) ควรใช้ระดับนามธรรมที่สูงขึ้นโดยไม่สูญเสียฟังก์ชันการทำงาน

3
ใช้อินเทอร์เฟซสำหรับประเภทข้อมูลเป็นแบบป้องกันหรือไม่
สมมติว่าฉันมีเอนทิตีต่าง ๆ ในแบบจำลองของฉัน (โดยใช้ EF), พูดว่าผู้ใช้ผลิตภัณฑ์ใบแจ้งหนี้และใบสั่ง ฉันกำลังเขียนตัวควบคุมผู้ใช้ที่สามารถพิมพ์บทสรุปของเอนทิตีวัตถุในแอปพลิเคชันของฉันซึ่งเป็นรายการที่กำหนดไว้ล่วงหน้าในกรณีนี้ฉันบอกว่าสรุปของผู้ใช้และผลิตภัณฑ์สามารถสรุปได้ บทสรุปจะมีเพียง ID และคำอธิบายเท่านั้นดังนั้นฉันจึงสร้างอินเทอร์เฟซอย่างง่ายสำหรับสิ่งนี้: public interface ISummarizableEntity { public string ID { get; } public string Description { get; } } จากนั้นสำหรับเอนทิตีที่มีปัญหาฉันสร้างคลาสบางส่วนที่ใช้อินเทอร์เฟซนี้: public partial class User : ISummarizableEntity { public string ID { get{ return UserID.ToString(); } } public string Description { get{ return …

6
แยกอินเตอร์เฟซที่มีขนาดใหญ่
ฉันใช้อินเตอร์เฟสขนาดใหญ่ที่มีประมาณ 50 วิธีในการเข้าถึงฐานข้อมูล ส่วนต่อประสานถูกเขียนขึ้นโดยเพื่อนร่วมงานของฉัน เราพูดถึงเรื่องนี้: ฉัน: 50 วิธีมากเกินไป มันเป็นกลิ่นรหัส เพื่อนร่วมงาน: ฉันต้องทำอย่างไรกับเรื่องนี้? คุณต้องการเข้าถึงฐานข้อมูล - คุณมีมัน ฉัน: ใช่ แต่มันไม่ชัดเจนและไม่สามารถบำรุงรักษาได้ในอนาคต เพื่อนร่วมงาน: โอเคคุณพูดถูกมันไม่ดีเลย อินเตอร์เฟสควรมีหน้าตาเป็นอย่างไร? ฉัน: วิธีการประมาณ 5 วิธีที่ส่งคืนวัตถุที่มีเช่น 10 วิธีในแต่ละวิธี? อืม แต่นี่จะไม่เหมือนกันหรือ สิ่งนี้นำไปสู่ความชัดเจนมากขึ้นหรือไม่? มันคุ้มค่ากับความพยายามหรือไม่? ทุก ๆ ครั้งที่ฉันอยู่ในสถานการณ์ที่ฉันต้องการอินเทอร์เฟซและสิ่งแรกที่นึกได้ก็คืออินเทอร์เฟซใหญ่ มีรูปแบบการออกแบบทั่วไปสำหรับสิ่งนี้หรือไม่? อัปเดต (ตอบกลับความคิดเห็นของ SJuan): "ชนิดวิธีการ": เป็นอินเทอร์เฟซสำหรับดึงข้อมูลจากฐานข้อมูล วิธีการทั้งหมดมีรูปแบบ (pseudocode) List<Typename> createTablenameList() วิธีการและตารางไม่ได้อยู่ในความสัมพันธ์ 1-1 อย่างชัดเจนสิ่งสำคัญคือความจริงที่ว่าคุณได้รับรายการบางประเภทที่มาจากฐานข้อมูลเสมอ

6
มีความแตกต่างระหว่างอินเตอร์เฟสและคลาส abstract ที่มีเมธอด abstract เท่านั้นหรือไม่?
สมมุติว่าเรามีคลาสนามธรรมและให้คลาสนี้มีวิธีนามธรรมเท่านั้น คลาสนามธรรมนี้แตกต่างจากอินเตอร์เฟสที่มีวิธีการเดียวกันเท่านั้นหรือไม่ สิ่งที่ฉันต้องการทราบคือหากมีความแตกต่างทั้งในเชิงปรัชญาวัตถุและในการใช้ภาษาโปรแกรมพื้นฐานระหว่างคลาสนามธรรมกับสมาชิกนามธรรมเท่านั้นและอินเทอร์เฟซที่เทียบเท่าหรือไม่

3
กฎเกี่ยวกับความคมชัดของชนิดพารามิเตอร์เมธอดชนิดส่งคืนและชนิดคุณสมบัติ
บางครั้งที่ผ่านมาฉันอ่าน "กฎของหัวแม่มือ" เกี่ยวกับความคมชัดของชนิดพารามิเตอร์เมธอดชนิดส่งคืนและชนิดคุณสมบัติ แต่ฉันจำไม่ได้ มันบอกอะไรบางอย่างเกี่ยวกับการรักษาประเภทการคืนสินค้าของคุณอย่างเป็นรูปธรรมมากที่สุดและพารามิเตอร์ประเภทของคุณจะเป็นนามธรรมมากที่สุด ... หรือในทางกลับกัน ฉันไม่รู้ว่าจริง ๆ แล้วมันเป็นคำแนะนำที่ดีหรือไม่ดีดังนั้นหากคุณมีความคิดของคุณเองเกี่ยวกับเรื่องนี้โปรดแจ้งความคิดเห็น ไชโย

2
มีหลักการอินเตอร์เฟซ“ ถามเฉพาะสิ่งที่คุณต้องการ” หรือไม่?
ฉันได้เติบโตขึ้นโดยใช้หลักการในการออกแบบและใช้งานส่วนต่อประสานที่พูดโดยทั่วไปว่า "ถามเฉพาะสิ่งที่คุณต้องการ" ตัวอย่างเช่นหากฉันมีประเภทที่สามารถลบได้มากมายฉันจะสร้างDeletableส่วนต่อประสาน: interface Deletable { void delete(); } จากนั้นฉันสามารถเขียนคลาสสามัญ: class Deleter<T extends Deletable> { void delete(T t) { t.delete(); } } ที่อื่นในรหัสฉันมักจะถามถึงความรับผิดชอบที่เล็กที่สุดที่เป็นไปได้เพื่อตอบสนองความต้องการของรหัสลูกค้า ดังนั้นถ้าฉันจะต้องลบFileก็ยังจะขอไม่ได้ DeletableFile หลักการนี้เป็นความรู้ทั่วไปและมีชื่อยอมรับแล้วหรือไม่? มันขัดแย้งหรือไม่ มันถูกกล่าวถึงในตำราหรือไม่?

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