Java 8 เพิ่มแนวคิดของส่วนต่อประสานการทำงานรวมถึงวิธีการใหม่มากมายที่ออกแบบมาเพื่อใช้งานส่วนต่อประสานการทำงาน อินสแตนซ์ของอินเทอร์เฟซเหล่านี้สามารถสร้างได้อย่างกระชับโดยใช้นิพจน์การอ้างอิงเมธอด (เช่นSomeClass::someMethod
) และนิพจน์แลมบ์ดา (เช่น(x, y) -> x + y
)
เพื่อนร่วมงานและฉันมีความคิดเห็นที่แตกต่างกันเมื่อควรใช้แบบฟอร์มเดียวหรือแบบอื่น (ซึ่ง "ดีที่สุด" ในกรณีนี้จะทำให้ "อ่านได้ง่ายที่สุด" และ "สอดคล้องกับมาตรฐานการปฏิบัติทั่วไป" มากที่สุด เทียบเท่า) โดยเฉพาะกรณีนี้เกี่ยวข้องกับกรณีที่ข้อมูลต่อไปนี้เป็นจริงทั้งหมด:
- ฟังก์ชั่นที่เป็นปัญหาไม่ได้ใช้งานนอกขอบเขตเดียว
- การตั้งชื่อให้ช่วยให้สามารถอ่านได้ (ตรงข้ามกับตรรกะที่เรียบง่ายพอที่จะดูว่าเกิดอะไรขึ้นอย่างรวดเร็ว)
- ไม่มีเหตุผลการเขียนโปรแกรมอื่นทำไมรูปแบบหนึ่งจะดีกว่าอีกรูปแบบหนึ่ง
ความเห็นของฉันในปัจจุบันเกี่ยวกับเรื่องนี้คือการเพิ่มวิธีการส่วนตัวและการอ้างอิงโดยวิธีการอ้างอิงเป็นวิธีที่ดีกว่า รู้สึกว่านี่เป็นวิธีที่คุณสมบัติถูกออกแบบมาให้ใช้และดูเหมือนง่ายขึ้นในการสื่อสารสิ่งที่เกิดขึ้นผ่านชื่อวิธีการและลายเซ็น (เช่น "บูลีน isResultInFuture (ผลผลลัพธ์)" ชัดเจนว่ากำลังส่งคืนบูลีน) นอกจากนี้ยังทำให้วิธีการส่วนตัวนำมาใช้ซ้ำได้มากขึ้นหากการปรับปรุงในอนาคตให้กับชั้นเรียนต้องการใช้ประโยชน์จากการตรวจสอบเดียวกัน แต่ไม่ต้องการเครื่องมือห่อหุ้มส่วนต่อประสานการทำงาน
การตั้งค่าของเพื่อนร่วมงานของฉันคือการมีวิธีการที่ส่งกลับอินสแตนซ์ของอินเทอร์เฟซ (เช่น "Predicate resultInFuture ()") สำหรับฉันแล้วมันรู้สึกว่ามันไม่ได้เป็นวิธีที่จะใช้คุณสมบัติรู้สึก clunkier เล็กน้อยและดูเหมือนว่ามันยากที่จะสื่อสารความตั้งใจผ่านการตั้งชื่อ
เพื่อให้ตัวอย่างคอนกรีตนี้นี่คือรหัสเดียวกันเขียนในสไตล์ที่แตกต่าง:
public class ResultProcessor {
public void doSomethingImportant(List<Result> results) {
results.filter(this::isResultInFuture).forEach({ result ->
// Do something important with each future result line
});
}
private boolean isResultInFuture(Result result) {
someOtherService.getResultDateFromDatabase(result).after(new Date());
}
}
เมื่อเทียบกับ
public class ResultProcessor {
public void doSomethingImportant(List<Result> results) {
results.filter(resultInFuture()).forEach({ result ->
// Do something important with each future result line
});
}
private Predicate<Result> resultInFuture() {
return result -> someOtherService.getResultDateFromDatabase(result).after(new Date());
}
}
เมื่อเทียบกับ
public class ResultProcessor {
public void doSomethingImportant(List<Result> results) {
Predicate<Result> resultInFuture = result -> someOtherService.getResultDateFromDatabase(result).after(new Date());
results.filter(resultInFuture).forEach({ result ->
// Do something important with each future result line
});
}
}
มีเอกสารอย่างเป็นทางการหรือกึ่งทางการหรือแสดงความคิดเห็นว่าแนวทางใดวิธีหนึ่งเป็นที่ต้องการมากกว่านั้นสอดคล้องกับเจตนารมณ์ของนักออกแบบภาษาหรืออ่านได้มากกว่าหรือไม่? การ จำกัด แหล่งที่มาอย่างเป็นทางการมีเหตุผลใดที่ชัดเจนว่าทำไมจึงเป็นแนวทางที่ดีกว่า
Object::toString
) ดังนั้นคำถามของฉันเกี่ยวกับว่ามันดีกว่าในอินสแตนซ์ชนิดนี้ที่ฉันจัดไว้ที่นี่ดีกว่ามีอินสแตนซ์ที่หนึ่งดีกว่าอีกอัน