การเขียนโปรแกรมสำหรับการใช้อินเตอร์เฟสในอนาคต


42

ฉันมีเพื่อนร่วมงานนั่งถัดจากฉันที่ออกแบบอินเทอร์เฟซเช่นนี้:

public interface IEventGetter {

    public List<FooType> getFooList(String fooName, Date start, Date end)
        throws Exception;
    ....

}

ปัญหาคือตอนนี้เราไม่ได้ใช้พารามิเตอร์ "สิ้นสุด" ที่ใดก็ได้ในรหัสของเรามันอยู่ที่นั่นเพราะเราอาจจะต้องใช้มันในอนาคต

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

ตอนนี้คำถามของฉันคือมีแหล่งที่จัดการหัวข้อเช่นนี้ของปรมาจารย์การเข้ารหัส "เคารพ" ที่เราสามารถเชื่อมโยงเขาไป?


29
"การทำนายยากมากโดยเฉพาะอย่างยิ่งในอนาคต"
Jörg W Mittag

10
ส่วนหนึ่งของปัญหาคือมันไม่ใช่อินเทอร์เฟซที่ดีที่สุดในการเริ่มต้น การรับ Foos และการกรองเป็นสองประเด็นแยกกัน อินเทอร์เฟซนั้นบังคับให้คุณกรองรายการด้วยวิธีใดวิธีหนึ่ง วิธีการทั่วไปที่มากกว่านั้นคือการส่งผ่านฟังก์ชันที่ตัดสินใจว่าควรรวม foo หรือไม่ อย่างไรก็ตามนี่เป็นเพียงการอัปเดตหากคุณสามารถใช้งาน Java 8 ได้
Doval

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

3
ด้วยวิธีการเริ่มต้น Java 8 ไม่มีเหตุผลที่จะเพิ่มอาร์กิวเมนต์ที่ไม่จำเป็น วิธีการที่สามารถเพิ่มในภายหลังด้วยการใช้งานเริ่มต้นที่ง่าย ๆ โทรที่กำหนดด้วย, พูด, null. การใช้คลาสนั้นสามารถแทนที่ได้ตามต้องการ
Boris the Spider

1
@Doval ฉันไม่รู้เกี่ยวกับ Java แต่ใน. NET บางครั้งคุณจะเห็นสิ่งต่าง ๆ เพื่อหลีกเลี่ยงการเปิดเผยความไม่ชอบมาพากลของIQueryable(สามารถใช้บางนิพจน์เท่านั้น) ในการเขียนโค้ดนอก DAL
Ben Aaronson

คำตอบ:


62

เชิญเขาไปเรียนรู้เกี่ยวกับYAGNI ส่วนเหตุผลของหน้า Wikipedia อาจน่าสนใจเป็นพิเศษที่นี่:

ตามผู้ที่สนับสนุนแนวทางของ YAGNI สิ่งล่อใจในการเขียนโค้ดที่ไม่จำเป็นในขณะนี้ แต่อาจเป็นในอนาคตมีข้อเสียดังต่อไปนี้:

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

อาร์กิวเมนต์ที่เป็นไปได้อื่น ๆ :

  • “80% ของค่าใช้จ่ายที่อายุการใช้งานของชิ้นส่วนของซอฟต์แวร์ไปกับการบำรุงรักษา” การเขียนรหัสแบบทันเวลาช่วยลดค่าใช้จ่ายในการบำรุงรักษา: ต้องมีการบำรุงรักษารหัสให้น้อยลงและสามารถมุ่งเน้นไปที่รหัสที่จำเป็นจริง ๆ

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

  • คาดว่าซอร์สโค้ดจะจัดทำเอกสารด้วยตนเอง ลายเซ็นจริงนั้นทำให้เข้าใจผิดเนื่องจากผู้อ่านจะคิดว่าendส่งผลต่อผลลัพธ์หรือการดำเนินการของวิธีการ

  • ผู้ที่เขียนการใช้งานอินเทอร์เฟซนี้อย่างเป็นรูปธรรมอาจไม่เข้าใจว่าไม่ควรใช้อาร์กิวเมนต์สุดท้ายซึ่งจะนำไปสู่แนวทางที่แตกต่าง:

    1. ฉันไม่ต้องการendดังนั้นฉันจะเพิกเฉยต่อคุณค่าของมัน

    2. ฉันไม่จำเป็นต้องendดังนั้นฉันจะโยนยกเว้นถ้ามันไม่ได้null,

    3. ฉันไม่ต้องการendแต่จะพยายามใช้มันอย่างใด

    4. ฉันจะเขียนโค้ดจำนวนมากซึ่งอาจใช้ในภายหลังเมื่อendจำเป็น

แต่ระวังว่าเพื่อนร่วมงานของคุณอาจถูกต้อง

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

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

  • เฟรมเวิร์กบางตัวไม่รองรับโอเวอร์โหลด ตัวอย่างเช่นและถ้าฉันจำได้ดี (แก้ไขฉันถ้าฉันผิด), WCF ของ. NET ไม่สนับสนุนการโอเวอร์โหลด

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


4
ฉันคิดว่ามันเป็นสิ่งสำคัญเช่นกันที่จะต้องพิจารณาว่าคุณลักษณะนี้มีแนวโน้มที่จะปรากฏในอนาคตหรือไม่ ถ้าคุณรู้ว่ามันจะถูกเพิ่มเข้ามา แต่ไม่ใช่ตอนนี้เพราะเหตุผลอะไรก็ตามฉันจะบอกว่านั่นเป็นเหตุผลที่ดีที่จะต้องคำนึงถึงเพราะมันไม่ใช่แค่คุณสมบัติ "ในกรณี"
Jeroen Vannevel

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

26

แต่เขายืนยันอย่างต่อเนื่องว่าจะต้องมีงานจำนวนมากหากเราใช้วันที่ "สิ้นสุด" ในภายหลังและต้องปรับรหัสทั้งหมดให้เหมาะสม

(บางครั้งในภายหลัง)

public class EventGetter implements IEventGetter {

    private static final Date IMPLIED_END_DATE_ASOF_20140711 = new Date(Long.MAX_VALUE); // ???

    @Override
    public List<FooType> getFooList(String fooName, Date start) throws Exception {
        return getFooList(fooName, start, IMPLIED_END_DATE_ASOF_20140711);
    }

    @Override
    public List<FooType> getFooList(String fooName, Date start, Date end) throws Exception {
        // Final implementation goes here
    }
}

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


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

1
หากทีมของ OP (ช่วยเพื่อนร่วมงาน) เชื่อว่าendพารามิเตอร์ไม่จำเป็นในตอนนี้และใช้endวิธีการแบบไม่มีเลสเตอรีตลอดโครงการการอัพเดทอินเทอร์เฟซนั้นเป็นสิ่งที่พวกเขากังวลน้อยที่สุดเพราะมันเป็นสิ่งจำเป็น ชั้นเรียนการดำเนินงาน คำตอบของฉันคือการกำหนดเป้าหมายโดยเฉพาะเกี่ยวกับส่วน "ปรับเปลี่ยนรหัสทั้งหมด" เพราะดูเหมือนว่าเพื่อนร่วมงานกำลังคิดตามบรรทัดที่ต้องอัปเดตผู้โทรของวิธีดั้งเดิมตลอดทั้งโครงการเพื่อแนะนำพารามิเตอร์ dummy / เริ่มต้นที่สาม .
hjk

18

[มี] ปรมาจารย์เข้ารหัส "เคารพ" หรือไม่ที่เราสามารถเชื่อมโยงเขากับ [เพื่อชักชวนเขา]]

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

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


สิ่งที่คุณต้องการจริงๆคือ

getFooList(String fooName, Date start, Date end, Date middle, 
           Date one_third, JulianDate start, JulianDate end,
           KlingonDate start, KlingonDate end)

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


22
You never know when you'll have to internationalize for Klingon. นั่นเป็นเหตุผลที่คุณควรผ่านCalendarและให้ลูกค้ารหัสตัดสินใจว่าเขาต้องการที่จะส่งGregorianCalendarหรือKlingonCalendar(ฉันเดิมพันบางคนทำไปแล้ว) ดุจ :-p
SJuan76

3
สิ่งที่เกี่ยวกับStarDate sdStartและStarDate sdEnd? เราไม่สามารถลืมเกี่ยวกับสหพันธ์หลังจากทั้งหมด ...
WernerCD

เห็นได้ชัดว่าทั้งหมดเป็นsubclasses ของหรือเปลี่ยนแปลงได้Date!
Darkhogg

ถ้าเพียง แต่มันเป็นที่เรียบง่าย
msw

@msw ฉันไม่แน่ใจว่าเขาขอ "ขอร้องต่อผู้มีอำนาจ" เมื่อเขาขอลิงค์ไปยัง "ผู้เชี่ยวชาญด้านการเข้ารหัสที่เคารพ" ในขณะที่คุณพูดเขาต้องการ "ข้อโต้แย้งที่ถูกต้องไม่ว่าใครจะพูดว่า" "ปราชญ์" - คนประเภทมักจะรู้จำนวนมาก นอกจากนี้คุณลืมและHebrewDate start HebrewDate end
trysis

12

จากมุมมองของวิศวกรรมซอฟต์แวร์ฉันเชื่อว่าวิธีแก้ไขปัญหาที่เหมาะสมสำหรับปัญหาประเภทนี้อยู่ในรูปแบบการสร้าง นี้แน่นอนการเชื่อมโยงจาก 'กูรู' ผู้เขียนสำหรับเพื่อนร่วมงานของคุณhttp://en.wikipedia.org/wiki/Builder_pattern

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

ตัวอย่างของคุณจะกลายเป็น:

public interface IEventGetter {
    public List<FooType> getFooList(ISearchFooRequest req) {
        throws Exception;
    ....
    }
}

public interface ISearchFooRequest {
        public String getName();
        public Date getStart();
        public Date getEnd();
        public int getOffset();
        ...
    }
}

public class SearchFooRequest implements ISearchFooRequest {

    public static SearchFooRequest buildDefaultRequest(String name, Date start) {
        ...
    }

    public String getName() {...}
    public Date getStart() {...}
    ...
    public void setEnd(Date end) {...}
    public void setOffset(int offset) {...}
    ...
}

3
นี้เป็นวิธีการที่ดีทั่วไป แต่ในกรณีนี้น่าจะเป็นเพียงแค่ผลักดันปัญหาจากการIEventGetter ISearchFootRequestฉันขอแนะนำสิ่งที่คล้ายpublic IFooFilterกับสมาชิกpublic bool include(FooType item)ที่คืนค่าว่าจะรวมรายการหรือไม่ จากนั้นการใช้อินเทอร์เฟซแต่ละตัวสามารถตัดสินใจได้ว่าพวกเขาจะทำอย่างไรในการกรอง
เบ็น Aaronson

@Ben Aaronson ฉันเพิ่งแก้ไขรหัสเพื่อแสดงวิธีการสร้างวัตถุพารามิเตอร์ขอ
InformedA

ผู้สร้างไม่จำเป็นที่นี่ (และค่อนข้างตรงไปตรงมาเป็นรูปแบบ overused / over-recommended โดยทั่วไป); ไม่มีกฎที่ซับซ้อนเกี่ยวกับวิธีการตั้งค่าพารามิเตอร์ดังนั้นวัตถุพารามิเตอร์จึงสมบูรณ์แบบหากมีความกังวลที่ถูกกฎหมายเกี่ยวกับพารามิเตอร์วิธีที่ซับซ้อนหรือเปลี่ยนแปลงบ่อยครั้ง และฉันเห็นด้วยกับ @BenAaronson ถึงแม้ว่าจุดของการใช้วัตถุพารามิเตอร์จะไม่รวมถึงพารามิเตอร์ที่ไม่จำเป็นทันที แต่ทำให้พวกเขาง่ายต่อการเพิ่มในภายหลัง (แม้ว่าจะมีการใช้อินเตอร์เฟซหลาย)
Aaronaught

7

คุณไม่ต้องการมันในตอนนี้ดังนั้นอย่าเพิ่มเข้าไป หากคุณต้องการในภายหลังให้ขยายส่วนต่อประสาน:

public interface IEventGetter {

    public List<FooType> getFooList(String fooName, Date start)
         throws Exception;
    ....

}

public interface IBoundedEventGetter extends IEventGetter {

    public List<FooType> getFooList(String fooName, Date start, Date end)
        throws Exception;
    ....

}

+1 สำหรับการไม่เปลี่ยนอินเทอร์เฟซที่มีอยู่ (และอาจผ่านการทดสอบ / จัดส่งแล้ว)
เซบาสเตียน Godelet

4

ไม่มีหลักการออกแบบที่แน่นอนดังนั้นในขณะที่ฉันเห็นด้วยกับคำตอบอื่น ๆ ส่วนใหญ่ฉันคิดว่าฉันเล่นเป็นผู้สนับสนุนของปีศาจและหารือเกี่ยวกับเงื่อนไขบางประการที่ฉันจะพิจารณายอมรับการแก้ปัญหาของเพื่อนร่วมงานของคุณ:

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

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

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


2

มีข้อมูลไม่เพียงพอที่จะตอบคำถามนี้ มันขึ้นอยู่กับสิ่งที่ทำgetFooListจริงและมันจะทำอย่างไร

นี่คือตัวอย่างที่ชัดเจนของวิธีการที่ควรสนับสนุนพารามิเตอร์เพิ่มเติมที่ใช้หรือไม่

void CapitalizeSubstring (String capitalize_me, int start_index);

การใช้วิธีการที่ทำงานกับคอลเลกชันที่คุณสามารถระบุการเริ่มต้น แต่ไม่ใช่จุดสิ้นสุดของคอลเลกชันที่มักจะโง่

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


1

ฉันเกรงว่าเพื่อนร่วมงานของคุณอาจมีจุดที่ถูกต้องจริง ๆ แม้ว่าทางออกของเขาจะไม่ดีที่สุด

จากส่วนต่อประสานที่เขาเสนอนั้นเป็นที่ชัดเจนว่า

public List<FooType> getFooList(String fooName, Date start, Date end) throws Exception;

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

ดังนั้นอินเทอร์เฟซที่ดีกว่าคือ:

public List<FooType> getFooList(String fooName, Interval interval) throws Exception;

หากคุณจัดหาช่วงเวลาด้วยวิธีการที่คงที่จากโรงงาน:

public static Interval startingAt(Date start) { return new Interval(start, null); }

จากนั้นลูกค้าจะไม่รู้สึกว่าจำเป็นต้องระบุเวลาสิ้นสุด

ในเวลาเดียวกันอินเทอร์เฟซของคุณถูกต้องมากขึ้นบ่งบอกถึงสิ่งที่มันทำเพราะgetFooList(String, Date)ไม่สื่อสารว่าข้อตกลงนี้มีช่วงเวลา

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


0

การเพิ่มพารามิเตอร์ที่ไม่ได้ใช้ทำให้เกิดความสับสน ผู้คนอาจเรียกวิธีการนั้นโดยสมมติว่าคุณสมบัตินี้ใช้งานได้

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

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

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