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

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

8
อินเตอร์เฟสที่เปิดเผย async ทำหน้าที่เป็นนามธรรมหรือไม่?
ฉันกำลังอ่านหนังสือหลักการพึ่งพาวิธีปฏิบัติและรูปแบบการพึ่งพาหนังสือและฉันอ่านเกี่ยวกับแนวคิดของสิ่งที่เป็นนามธรรมซึ่งอธิบายไว้ในหนังสือ วันนี้ฉันกำลังสร้างฐานรหัส C # ขึ้นใหม่โดยใช้การฉีดอ้างอิงเพื่อให้มีการใช้การโทรแบบ async แทนการบล็อก การทำเช่นนี้ฉันกำลังพิจารณาอินเทอร์เฟซบางตัวที่เป็นนามธรรมในรหัสฐานของฉันและต้องได้รับการออกแบบใหม่เพื่อให้สามารถใช้การโทรแบบ async ได้ เป็นตัวอย่างให้พิจารณาอินเตอร์เฟสต่อไปนี้ที่แสดงถึงที่เก็บสำหรับผู้ใช้แอ็พพลิเคชัน: public interface IUserRepository { Task<IEnumerable<User>> GetAllAsync(); } ตามคำนิยามของหนังสือสิ่งที่เป็นนามธรรมคือสิ่งที่เป็นนามธรรมที่ได้รับการออกแบบมาโดยเฉพาะในใจนามธรรมเพื่อให้รายละเอียดของการดำเนินการ "รั่ว" ผ่านสิ่งที่เป็นนามธรรมเอง คำถามของฉันมีดังต่อไปนี้: เราสามารถพิจารณาอินเทอร์เฟซที่ออกแบบโดยคำนึงถึง async เช่น IUserRepository เป็นตัวอย่างของ Leaky Abstraction ได้หรือไม่? แน่นอนว่าการใช้งานที่เป็นไปไม่ได้ทั้งหมดมีบางอย่างที่เกี่ยวข้องกับ asynchrony: มีเพียงการติดตั้งแบบไม่ใช้กระบวนการ (เช่นการใช้ SQL) แต่การเก็บข้อมูลในหน่วยความจำไม่จำเป็นต้องใช้แบบอะซิงโครนัส ยากถ้าอินเทอร์เฟซถูกเปิดเผยเมธอด async ตัวอย่างเช่นคุณอาจต้องส่งคืนสิ่งที่ต้องการเช่น Task.CompletedTask หรือ Task.FromResult (ผู้ใช้) ในการประยุกต์ใช้เมธอด) คุณคิดยังไงเกี่ยวกับที่ ?

5
มันสมเหตุสมผลหรือไม่ที่จะนิยามอินเตอร์เฟสถ้าฉันมีคลาสนามธรรมอยู่แล้ว?
ฉันมีชั้นเรียนพร้อมฟังก์ชั่นเริ่มต้น / แชร์ ฉันใช้abstract classมัน public interface ITypeNameMapper { string Map(TypeDefinition typeDefinition); } public abstract class TypeNameMapper : ITypeNameMapper { public virtual string Map(TypeDefinition typeDefinition) { if (typeDefinition is ClassDefinition classDefinition) { return Map(classDefinition); } ... throw new ArgumentOutOfRangeException(nameof(typeDefinition)); } protected abstract string Map(ClassDefinition classDefinition); } ITypeNameMapperที่คุณสามารถดูฉันยังมีอินเตอร์เฟซ มันเหมาะสมหรือไม่ที่จะกำหนดอินเทอร์เฟซนี้ถ้าฉันมีคลาสนามธรรมTypeNameMapperหรือabstract classเพียงพอหรือไม่? TypeDefinition …

3
อินเทอร์เฟซจะถือว่าว่างหรือไม่ถ้ามันสืบทอดมาจากอินเทอร์เฟซอื่นหรือไม่
อินเทอร์เฟซที่ว่างเปล่าโดยทั่วไปจะพิจารณาการปฏิบัติที่ไม่ดีเท่าที่ฉันสามารถบอกได้ - โดยเฉพาะอย่างยิ่งเมื่อสิ่งต่าง ๆ เช่นแอตทริบิวต์ได้รับการสนับสนุนโดยภาษา อย่างไรก็ตามอินเทอร์เฟซถูกพิจารณาว่า 'ว่าง' ถ้ามันได้รับมาจากอินเทอร์เฟซอื่นหรือไม่ interface I1 { ... } interface I2 { ... } //unrelated to I1 interface I3 : I1, I2 { // empty body } สิ่งใดที่ใช้I3จะต้องนำไปปฏิบัติI1และI2และวัตถุจากคลาสที่แตกต่างกันซึ่งสืบทอดI3สามารถนำมาใช้แทนกันได้ (ดูด้านล่าง) ดังนั้นมันถูกต้องหรือI3 เปล่าที่จะเรียกว่าว่างเปล่า ? ถ้าเป็นเช่นนั้นจะมีวิธีใดที่ดีกว่าในการสร้างสถาปัตยกรรมนี้ // with I3 interface class A : I3 { ... } class B …

2
UnsupportedOperationException ในอินเตอร์เฟสเฟรมเวิร์กของ Java คอลเล็กชัน
มองผ่าน Java (optional operation)คอลเลกชันกรอบฉันพบค่อนข้างน้อยของอินเตอร์เฟซที่มีการแสดงความคิดเห็น วิธีการเหล่านี้อนุญาตให้นำคลาสไปใช้ผ่านUnsupportedOperationExceptionหากพวกเขาไม่ต้องการใช้วิธีนั้น ตัวอย่างนี้เป็นวิธีการในaddAllSet Interface ตอนนี้ตามที่ระบุไว้ในชุดคำถามนี้อินเทอร์เฟซเป็นสัญญาที่กำหนดสำหรับสิ่งที่ผู้ใช้สามารถคาดหวังได้ อินเทอร์เฟซมีความสำคัญเนื่องจากแยกสิ่งที่คลาสทำจากวิธีการใช้งาน สัญญาที่กำหนดสิ่งที่ลูกค้าสามารถคาดหวังปล่อยให้นักพัฒนาสามารถนำไปใช้ได้ทุกวิธีที่พวกเขาเลือกตราบใดที่พวกเขารักษาสัญญา และ อินเทอร์เฟซคือคำอธิบายของการกระทำที่วัตถุสามารถทำได้ ... ตัวอย่างเช่นเมื่อคุณพลิกสวิตช์ไฟแสงจะสว่างขึ้นคุณไม่สนใจว่ามันจะทำอย่างไร ในการเขียนโปรแกรมเชิงวัตถุอินเทอร์เฟซคือคำอธิบายของฟังก์ชันทั้งหมดที่วัตถุต้องมีเพื่อให้เป็น "X" และ ฉันคิดว่าวิธีการทำงานบนอินเตอร์เฟสนั้นดีกว่าอย่างมาก จากนั้นคุณสามารถเยาะเย้ยการพึ่งพาของคุณได้อย่างดีและทุกอย่างก็น้อยกว่ากันอย่างแน่นหนา จุดประสงค์ของอินเทอร์เฟซคืออะไร อินเตอร์เฟสคืออะไร อินเตอร์เฟส + ส่วนขยาย (มิกซ์อิน) เทียบกับคลาสพื้นฐาน ระบุว่าวัตถุประสงค์ของอินเทอร์เฟซคือการกำหนดสัญญาและทำให้การพึ่งพาของคุณควบคู่กันอย่างอิสระไม่ได้มีวิธีการบางอย่างที่จะUnsupportedOperationExceptionทำลายวัตถุประสงค์ มันหมายความว่าฉันไม่สามารถผ่านSetและใช้งานaddAllได้อีกต่อไป แต่ฉันต้องรู้ว่าSetฉันใช้งานอะไรบ้างฉันจึงสามารถรู้ได้ว่าฉันสามารถใช้addAllหรือไม่ นั่นดูเหมือนจะไร้ค่าสำหรับฉัน แล้วประเด็นUnsupportedOperationExceptionคืออะไร มันเป็นเพียงการสร้างรหัสดั้งเดิมและพวกเขาจำเป็นต้องทำความสะอาดอินเตอร์เฟสของพวกเขา? หรือว่ามันมีจุดประสงค์ที่ละเอียดอ่อนกว่าที่ฉันหลงหายไป?

4
การใช้อินเทอร์เฟซสำหรับการจัดหมวดหมู่เป็นเรื่องที่ผิดหรือไม่
ตัวอย่างเช่น: บอกฉันได้เรียนA, ,B Cฉันมีสองอินเตอร์เฟซที่ช่วยให้เรียกพวกเขาและIAnimal สืบทอดจาก และมีs ในขณะที่ไม่ได้ แต่มันก็เป็นIDogIDogIAnimalABIDogCIAnimal ส่วนที่สำคัญคือIDogไม่มีการใช้งานเพิ่มเติม มันใช้เพื่ออนุญาตAและBไม่Cผ่านการโต้แย้งเป็นวิธีการบางอย่าง นี่คือการปฏิบัติที่ไม่ดีหรือไม่?

5
แนวคิดของคลาสเปลี่ยนไปอย่างไรเมื่อส่งข้อมูลไปยังตัวสร้างแทนพารามิเตอร์เมธอด?
สมมติว่าเรากำลังแยกวิเคราะห์ การใช้งานอย่างหนึ่งอาจ: public sealed class Parser1 { public string Parse(string text) { ... } } หรือเราสามารถส่งข้อความไปยังผู้สร้างได้: public sealed class Parser2 { public Parser2(string text) { this.text = text; } public string Parse() { ... } } การใช้งานเป็นเรื่องง่ายในทั้งสองกรณี แต่การเปิดใช้งานพารามิเตอร์อินพุตเมื่อเปรียบเทียบกับกรณีอื่น ๆหมายความว่าParser1อย่างไร ฉันได้ส่งข้อความอะไรถึงเพื่อนนักเขียนโปรแกรมเมื่อพวกเขาดู API นอกจากนี้ยังมีข้อดี / ข้อเสียด้านเทคนิคในบางกรณีหรือไม่? คำถามอื่นเกิดขึ้นเมื่อฉันตระหนักว่าอินเทอร์เฟซจะค่อนข้างไม่มีความหมายในการใช้งานที่สอง: public interface IParser { string …

1
เหตุใด CharSequence จึงไม่ประกอบด้วย (CharSequence)
สิ่งนี้ใช้กับทั้ง Java SE และ Android เนื่องจากสัญญาเหมือนกัน เอกสาร CharSequence สำหรับ Java SE CharSequence เอกสารประกอบสำหรับ Android CharSequenceไม่ได้กำหนดcontains(CharSequence)วิธีการ ฉันไม่สามารถหาเหตุผลว่าทำไมและรวมถึงมันจะมีประโยชน์มากทำให้ไม่ต้องโทรCharSequence#toString()เพื่อตรวจสอบลำดับของอักขระ ยกตัวอย่างเช่นใน Android ของผู้ใช้ที่ถูกบังคับให้โทรEditable#toString()เพื่อดูว่าจะมีลำดับของอักขระแม้ว่าEditableการดำเนินการCharSequenceซึ่งสามารถหลีกเลี่ยงได้ถ้ากำหนดไว้CharSequencecontains(CharSequence) แนวคิดเบื้องหลังตัวเลือกการออกแบบนี้คืออะไร มันเป็นการกำกับดูแลที่มีศักยภาพหรือมีเหตุผลในการออกแบบสำหรับเรื่องนี้?

5
อินเตอร์เฟซแยกต่างหากสำหรับวิธีการกลายพันธุ์
ฉันทำงานเกี่ยวกับการรีแฟคเตอร์โค้ดบางส่วนและฉันคิดว่าฉันอาจทำขั้นตอนแรกลงไปในช่องกระต่าย ฉันเขียนตัวอย่างใน Java แต่ฉันคิดว่ามันอาจเป็นผู้ไม่เชื่อเรื่องพระเจ้า ฉันมีอินเตอร์เฟซที่Fooกำหนดเป็น public interface Foo { int getX(); int getY(); int getZ(); } และการดำเนินการตาม public final class DefaultFoo implements Foo { public DefaultFoo(int x, int y, int z) { this.x = x; this.y = y; this.z = z; } public int getX() { return x; } public …

9
การออกแบบ OO ใดที่จะใช้ (มีรูปแบบการออกแบบ)
ฉันมีวัตถุสองชิ้นที่แสดงถึง 'บาร์ / คลับ' (สถานที่ที่คุณดื่ม / สังสรรค์) ในสถานการณ์หนึ่งฉันต้องการชื่อบาร์ที่อยู่ระยะทางสโลแกน ในสถานการณ์อื่นฉันต้องการชื่อบาร์, ที่อยู่, URL เว็บไซต์, โลโก้ ดังนั้นฉันจึงมีวัตถุสองชิ้นที่เป็นตัวแทนของสิ่งเดียวกัน แต่มีเขตข้อมูลที่แตกต่างกัน ผมชอบที่จะใช้วัตถุที่ไม่เปลี่ยนรูปเพื่อให้ทุกสาขามีการตั้งค่าจากตัวสร้าง ตัวเลือกหนึ่งคือการมีสองคอนสตรัคเตอร์และโมฆะสาขาอื่น ๆ เช่น: class Bar { private final String name; private final Distance distance; private final Url url; public Bar(String name, Distance distance){ this.name = name; this.distance = distance; this.url = null; } public …

4
คำว่า "อินเตอร์เฟส" ใน C ++
Java ทำให้ความแตกต่างที่ชัดเจนระหว่างและclass interface(ฉันเชื่อว่า C # ทำเช่นนั้น แต่ฉันไม่มีประสบการณ์ด้วย) เมื่อเขียน C ++ อย่างไรก็ตามไม่มีภาษาบังคับให้แยกความแตกต่างระหว่างคลาสและส่วนต่อประสาน ดังนั้นฉันมักจะดูอินเตอร์เฟซเป็นวิธีแก้ปัญหาสำหรับการขาดการสืบทอดหลายใน Java การทำให้ความแตกต่างดังกล่าวให้ความรู้สึกโดยพลการและไร้ความหมายใน C ++ ฉันมักจะไปกับวิธีการ "เขียนสิ่งต่าง ๆ ในวิธีที่ชัดเจนที่สุด" ดังนั้นใน C ++ ฉันมีสิ่งที่เรียกว่าส่วนติดต่อใน Java เช่น: class Foo { public: virtual void doStuff() = 0; ~Foo() = 0; }; และฉันก็ตัดสินใจว่าผู้ดำเนินการส่วนใหญ่Fooต้องการแบ่งปันฟังก์ชั่นทั่วไปบางอย่างที่ฉันอาจจะเขียน: class Foo { public: virtual void doStuff() = 0; ~Foo() …

3
ประเภทการดำรงอยู่แตกต่างจากอินเตอร์เฟสได้อย่างไร
กำหนดประเภทการดำรงอยู่ T = ∃X.{op₁:X, op₂:X→boolean} และอินเตอร์เฟส Java ทั่วไปนี้: interface T<X> { X op₁(); boolean op₂(X something); } อะไรคือความแตกต่างพื้นฐานระหว่างประเภทที่มีอยู่และส่วนต่อประสาน Java? เห็นได้ชัดว่ามีความแตกต่างทางไวยากรณ์และการวางแนววัตถุของ Java (ซึ่งรวมถึงรายละเอียดเช่นthisพารามิเตอร์ที่ซ่อนอยู่ฯลฯ ) ฉันไม่ได้สนใจสิ่งเหล่านี้มากนักในความแตกต่างทางความคิดและความหมาย - แม้ว่าบางคนอยากจะแสดงความเห็นในบางประเด็นที่ละเอียดกว่า (เช่นความแตกต่างระหว่างตัวละครTกับT<X>) ที่จะได้รับการชื่นชมเช่นกัน

3
ความแตกต่างระหว่างอินเตอร์เฟสทั่วไปของคอลเลกชันทั่วไปใน C #
ฉันได้เล่นกับ C # สำหรับ Windows และ ASP.net MVC พัฒนามาระยะหนึ่งแล้ว แต่ฉันยังไม่ชัดเจนในบางพื้นที่ ฉันกำลังพยายามที่จะเข้าใจความแตกต่างขั้นพื้นฐานระหว่างและปัญหาการปฏิบัติงานเกี่ยวกับการใช้และการสับเปลี่ยนชนิดที่คล้ายกันของทั่วไปการเก็บการเชื่อมต่อ คือความแตกต่างระหว่างสิ่งที่พื้นฐานIEnumerable<T>, ICollection<T>, List<T>(Class)? ฉันดูเหมือนจะใช้และแลกเปลี่ยนโดยไม่เห็นปัญหาใด ๆ ในแอปพลิเคชันของฉัน นอกจากนี้ยังมีคอลเลกชันทั่วไปที่คล้ายกันมากกว่านี้ที่สามารถแลกเปลี่ยนกับสามเหล่านี้ได้หรือไม่

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

6
อะไรคือเหตุผลที่ดีในการใช้งานส่วนติดต่ออย่างชัดเจนเพื่อจุดประสงค์ในการซ่อนสมาชิก
ระหว่างที่ฉันศึกษาเรื่องความซับซ้อนของ C # ฉันพบข้อความที่น่าสนใจเกี่ยวกับการใช้อินเทอร์เฟซที่ชัดเจน While this syntax is quite helpful when you need to resolve name clashes, you can use explicit interface implementation simply to hide more "advanced" members from the object level. ความแตกต่างระหว่างการอนุญาตให้ใช้object.method()หรือต้องการการหล่อของ((Interface)object).method()การทำให้งงงวยหมายถึงใจแข็งกับสายตาที่ไม่มีประสบการณ์ของฉัน ข้อความตั้งข้อสังเกตว่าสิ่งนี้จะซ่อนวิธีการจาก Intellisense ที่ระดับวัตถุ แต่ทำไมคุณต้องการทำเช่นนั้นหากไม่จำเป็นต้องหลีกเลี่ยงความขัดแย้งของชื่อ
11 c#  design  interfaces 

3
การใช้อินเทอร์เฟซสำหรับรหัสคู่ที่หลวม
พื้นหลัง ฉันมีโครงการที่ขึ้นอยู่กับการใช้งานของอุปกรณ์ฮาร์ดแวร์บางประเภทในขณะที่มันไม่สำคัญว่าใครจะทำอุปกรณ์ฮาร์ดแวร์นั้นตราบเท่าที่มันเป็นสิ่งที่ฉันต้องทำ จากที่กล่าวมาแม้กระทั่งอุปกรณ์สองชิ้นที่ควรทำในสิ่งเดียวกันจะมีความแตกต่างเมื่อไม่ได้ผลิตโดยผู้ผลิตรายเดียวกัน ดังนั้นฉันจึงคิดว่าจะใช้อินเทอร์เฟซเพื่อแยกแอปพลิเคชันออกจากอุปกรณ์/ รุ่นที่เกี่ยวข้องและมีอินเทอร์เฟซที่ครอบคลุมฟังก์ชั่นระดับสูงสุดแทน นี่คือสิ่งที่ฉันคิดว่าสถาปัตยกรรมของฉันจะมีลักษณะ: กำหนดอินเตอร์เฟซใน C # IDeviceโครงการหนึ่ง มีรูปธรรมในห้องสมุดที่กำหนดไว้ในโครงการ C # อื่นที่จะใช้เพื่อเป็นตัวแทนของอุปกรณ์ มีอุปกรณ์ที่เป็นรูปธรรมใช้IDeviceอินเตอร์เฟซ IDeviceอินเตอร์เฟซที่อาจจะมีวิธีการเช่นหรือGetMeasurementSetRange ทำให้แอปพลิเคชันมีความรู้เกี่ยวกับรูปธรรมและส่งผ่านรูปธรรมไปยังรหัสแอปพลิเคชั่นที่ใช้งาน ( ไม่นำไปใช้ ) IDeviceอุปกรณ์ ฉันค่อนข้างแน่ใจว่านี่เป็นวิธีที่ถูกต้องที่จะไปเกี่ยวกับเรื่องนี้เพราะแล้วฉันจะสามารถเปลี่ยนอุปกรณ์ที่ใช้โดยไม่ส่งผลกระทบต่อแอปพลิเคชัน (ซึ่งดูเหมือนว่าจะเกิดขึ้นบางครั้ง) กล่าวอีกนัยหนึ่งมันไม่สำคัญว่าการใช้งานGetMeasurementหรือSetRangeทำงานผ่านคอนกรีตอย่างแท้จริง (อาจแตกต่างกันระหว่างผู้ผลิตอุปกรณ์) ข้อสงสัยเดียวในใจของฉันคือตอนนี้ทั้งแอปพลิเคชันและคลาสที่เป็นรูปธรรมของอุปกรณ์นั้นขึ้นอยู่กับไลบรารีที่มีIDeviceส่วนต่อประสาน แต่นั่นเป็นสิ่งที่ไม่ดี? ฉันไม่เห็นด้วยว่าแอปพลิเคชันไม่จำเป็นต้องรู้เกี่ยวกับอุปกรณ์ได้อย่างไรนอกจากอุปกรณ์และIDeviceอยู่ในเนมสเปซเดียวกัน คำถาม ดูเหมือนว่าวิธีการที่ถูกต้องสำหรับการใช้อินเทอร์เฟซเพื่อแยกการพึ่งพาระหว่างแอปพลิเคชันของฉันและอุปกรณ์ที่ใช้หรือไม่

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