วิธีการใช้งานเพียงส่วนหนึ่งของอินเทอร์เฟซ


14

เมื่อพัฒนาใน OOP บางครั้งจะมีการกำหนดอินเทอร์เฟซ / สัญญาโดยห้องสมุดที่คุณไม่สามารถเปลี่ยนแปลงได้ มาเรียกอินเตอร์เฟสนี้ว่า J

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

ฉันต้องการใช้ฟังก์ชั่นย่อยในอินเตอร์เฟส J แต่โซลูชันของฉันยังไม่เป็นที่พอใจ:

  • การนำทุกแง่มุมของ J ไปใช้แล้วโยน "notImplementedExceptions" ให้ผู้ใช้วัตถุของฉันเข้าใจผิด: ดูเหมือนว่าวัตถุประเภท D ของฉันจะสอดคล้องกับส่วนต่อประสาน J แต่พวกเขาทำไม่ได้ - และผู้บริโภควัตถุอื่นของฉัน J) ไม่สามารถพึ่งพาความสมบูรณ์ของวัตถุของฉัน
  • การใช้อินเทอร์เฟซที่กำหนดใหม่ห้ามไม่ให้ฉันใช้วัตถุที่ใช้เฉพาะอินเตอร์เฟส J แม้ว่าอินเตอร์เฟส J จะเข้ากันได้กับส่วนต่อประสานของฉันเอง
  • การปล่อยให้วัตถุที่กำหนดเองของฉันใช้อินเตอร์เฟส J จะสร้างค่าใช้จ่ายที่สำคัญเพราะพวกเขาไม่ต้องการฟังก์ชันทั้งหมดนี้

เมื่อฉันสามารถเปลี่ยนอินเตอร์เฟส J ได้ฉันจะสร้าง "super-interface" K ที่มีชุดย่อยของฟังก์ชัน J interface นี้และทำให้ Interface J สืบทอดจากอินเตอร์เฟส K แต่ฉันไม่สามารถเปลี่ยนอินเตอร์เฟส J ได้

การแก้ปัญหาเชิงวัตถุสำหรับปัญหานี้คืออะไร? ทางออกที่ดีที่สุดยังคงใช้งานอินเทอร์เฟซ "เพิ่ง" J หรือไม่? หรือมีวิธี OOP ในการ "superclass" อินเทอร์เฟซโดยไม่มีการเปลี่ยนแปลงหรือไม่


1
มาดูกันว่าคลาส Adapter * ใน Swing ดำเนินการอย่างไร

คำตอบ:


9

หากคุณไม่ได้ควบคุมอินเตอร์เฟส J คุณก็ติดอยู่

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

ถ้าเป็นไปได้ให้ใช้อินเตอร์เฟส J ทั้งหมด

หากเป็นไปได้ให้ติดต่อเจ้าของส่วนต่อประสาน J และขอให้เขา / เธอปรับเปลี่ยนให้เหมาะสมกับวัตถุประสงค์ของคุณมากขึ้น


2
ในฐานะที่เป็นการประนีประนอม: คุณสามารถขอให้เจ้าของส่วนต่อประสาน J เพื่อสืบทอดฟอร์มย่อยส่วนต่อประสานย่อยของคุณ
k3b

27

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

ด้วยการใช้อินเตอร์เฟส J คุณกำลังบอกกับโลกภายนอกว่าคุณสามารถทำอะไรได้บ้าง

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


5

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

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

เพื่อให้คลาส A ใช้วัตถุที่ใช้อินเตอร์เฟส J เพียงอย่างเดียวคุณสามารถจัดเตรียมคลาส wrapper ที่ใช้อินเตอร์เฟส K และผ่านการเรียกที่เหมาะสมไปยังสมาชิกอินเตอร์เฟส J


3

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

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

โปรดทราบว่านี่เป็นวิธีการแก้ปัญหาที่น่าเกลียดเนื่องจากต้องใช้กระดาษหุ้มที่ยอมรับหลายสิ่งที่เป็นหลักในสิ่งเดียวกัน แต่มันจะบรรลุผลดังต่อไปนี้:

  • ไม่มีการเปลี่ยนแปลง J หรือ A
  • ไม่มีการใช้งาน "เปิดเผย" ของ J ที่ไม่สมบูรณ์

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


1

การใช้อินเทอร์เฟซทั้งหมดจะใช้เวลานานเท่าใด

หากต้องใช้เวลาพอสมควรนี่หมายถึงปัญหาการออกแบบและฉันขอแนะนำให้คุณ (เหมือนที่ Steven A. ทำก่อนฉัน) เพื่อติดต่อเจ้าของและดูว่ามันอาจมีการเปลี่ยนแปลงในอนาคต

คุณใช้อินเทอร์เฟซในรหัสของคุณเป็นอิสระจากไลบรารีของอินเทอร์เฟซหรือไม่

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

การใช้งานของคุณจะต้องมีสมาชิกที่ไม่ได้ใช้อินเทอร์เฟซหรือไม่

ในกรณีที่คุณสามารถคาดหวังว่าพวกเขาไม่เคยที่จะเรียกว่าตั้งแต่พวกเขา 'ไม่สนับสนุน' NotSupportedExceptionฉันชอบใช้ สิ่งนี้แสดงให้เห็นอย่างชัดเจนว่าคุณจะไม่สนับสนุนอินเทอร์เฟซนี้มากกว่าที่คุณไม่ได้ใช้งาน


ความคิดที่ดีเกี่ยวกับการใช้NotSupportedExceptionมันทำให้ชัดเจนว่าคุณไม่สนับสนุนวิธีการนั้น
ChrisF

@ChrisF: ฉันเพียงใช้NotImplementedExceptionรหัสการผลิตที่ฉันอาจจะเขียน"สิ่งที่ต้องทำ: ระบบนี้"น่าเศร้าที่พวกเขาไม่ได้ปรากฏขึ้นในรายการงานภาพสตูดิโอ แต่ในทางปฏิบัติฉันแทบไม่เหลือวิธีที่ไม่ได้ใช้งานมานานกว่าสองวัน Resharper ยังแสดงข้อยกเว้นเหล่านั้นด้วยตัวหนา (อย่างน้อยกับการตั้งค่าของฉัน) :)
Steven Jeuris

0

ใช้สิ่งที่คุณต้องการและโยนข้อยกเว้น NoImplementedException ที่คนอื่น ๆ

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

ทำงานให้พร้อมสำหรับงานและให้ผู้อื่นติดตามได้ดีหากพวกเขาต้องการใช้อินเทอร์เฟซ

อินเตอร์เฟสจำนวนมากใน Java ไม่ได้ถูกใช้งานอย่างเต็มรูปแบบ

นี่คือ Apache aproach สู่สิ่งต่าง ๆ : http://commons.apache.org/lang/api-2.4/org/apache/commons/lang/NotImplementedException.html


อาจจะเถียงว่าทำไมคุณถึงเชื่อว่านี่เป็นทางออกที่เหมาะสม สิ่งนี้ไม่ช่วยเพิ่มคำถาม
Steven Jeuris

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