การพึ่งพาการฉีด: การฉีดภาคสนามและการฉีดคอนสตรัคเตอร์?


61

ฉันรู้ว่านี่คือการอภิปรายที่ร้อนแรงและความคิดเห็นมีแนวโน้มที่จะเปลี่ยนแปลงไปตามกาลเวลาเพื่อแนวทางการปฏิบัติที่ดีที่สุด

ผมเคยใช้เฉพาะการฉีดฟิลด์สำหรับชั้นเรียนของฉันจนผมเริ่มอ่านบนบล็อกที่แตกต่างกัน (EXS: petrikainulainenและschauderhaftและฟาวเลอร์ ) เกี่ยวกับประโยชน์ของการฉีดสร้าง ฉันได้เปลี่ยนวิธีการของฉันที่จะใช้การฉีดคอนสตรัคสำหรับการพึ่งพาที่จำเป็นและการฉีด Setter สำหรับการพึ่งพาตัวเลือก

อย่างไรก็ตามเมื่อไม่นานมานี้ฉันได้มีการถกเถียงกับผู้เขียน JMockit ซึ่งเป็นกรอบการเยาะเย้ยซึ่งเขาเห็นว่าการสร้างคอนสตรัคเตอร์และสุนัขเซทเทอร์เตอร์เป็นการปฏิบัติที่ไม่ดีและบ่งชี้ว่าชุมชน JEE เห็นด้วยกับเขา

ในโลกปัจจุบันมีวิธีที่เหมาะสมกว่าในการฉีดหรือไม่? การฉีดภาคสนามเป็นที่ต้องการหรือไม่?

หลังจากเปลี่ยนไปใช้คอนสตรัคเตอร์ฉีดจากการฉีดภาคสนามในช่วงสองสามปีที่ผ่านมาฉันพบว่ามันชัดเจนกว่าที่จะใช้ แต่ฉันสงสัยว่าฉันควรตรวจสอบมุมมองของฉันอีกครั้งหรือไม่ ผู้เขียนJMockit (Rogério Liesenfeld)มีความเชี่ยวชาญใน DI อย่างชัดเจนดังนั้นฉันรู้สึกผูกพันที่จะต้องทบทวนวิธีการของฉันเนื่องจากเขารู้สึกอย่างยิ่งกับการฉีดคอนสตรัคเตอร์ / สุนัขเซทเตอร์



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

2
@DavidArno: ในคลาสที่ไม่เปลี่ยนรูปรัฐจะถูกตั้งค่าครั้งเดียว ... ในตัวสร้าง
Robert Harvey

1
@Davkd สิ่งที่คุณกำลังอธิบายคือโมเดลโดเมนโลหิตจาง มีผู้สนับสนุนอย่างแน่นอน แต่มันไม่ได้คัดค้านอีกต่อไป ข้อมูลและหน้าที่ที่ทำงานกับข้อมูลนั้นอยู่ด้วยกัน
Richard Tingle

3
@ David ไม่มีอะไรผิดปกติกับการเขียนโปรแกรมใช้งานได้ แต่จาวาพื้นฐานถูกออกแบบมาให้เป็นวัตถุที่มุ่งเน้นและคุณจะต้องต่อสู้อย่างต่อเนื่องและจบลงด้วยรูปแบบโดเมน anemicถ้าคุณไม่ระมัดระวังมาก มีอะไรผิดปกติกับรหัสฟังก์ชั่น orientated แต่เครื่องมือที่เหมาะสมควรใช้สำหรับมันซึ่ง java ไม่ได้ (แม้ว่าแลมบ์ดาได้เพิ่มองค์ประกอบของการเขียนโปรแกรมตามฟังก์ชั่น)
Richard Tingle

คำตอบ:


48

การฉีดภาคสนามเป็นเรื่องเล็กน้อยเกินไป"การกระทำที่น่ากลัวในระยะไกล"สำหรับรสนิยมของฉัน

ลองพิจารณาตัวอย่างที่คุณให้ไว้ในโพสต์ของ Google Groups:

public class VeracodeServiceImplTest {


    @Tested(fullyInitialized=true)
    VeracodeServiceImpl veracodeService;
    @Tested(fullyInitialized=true, availableDuringSetup=true)
    VeracodeRepositoryImpl veracodeRepository;
    @Injectable private ResultsAPIWrapper resultsApiWrapper;
    @Injectable private AdminAPIWrapper adminApiWrapper;
    @Injectable private UploadAPIWrapper uploadApiWrapper;
    @Injectable private MitigationAPIWrapper mitigationApiWrapper;

    static { VeracodeRepositoryImpl.class.getName(); }
...
}

ดังนั้นโดยทั่วไปสิ่งที่คุณพูดคือ "ฉันมีชั้นเรียนนี้ที่มีรัฐส่วนตัวซึ่งฉันได้แนบ@injectableคำอธิบายประกอบซึ่งหมายความว่ารัฐสามารถมีตัวแทนโดยอัตโนมัติจากภายนอกแม้ว่ารัฐของฉันจะได้รับการประกาศส่วนตัวทั้งหมด "

ฉันเข้าใจแรงจูงใจของสิ่งนี้ มันเป็นความพยายามที่จะหลีกเลี่ยงพิธีที่มีอยู่ในการจัดชั้นเรียนอย่างเหมาะสม โดยพื้นฐานแล้วสิ่งที่คนพูดคือ "ฉันเหนื่อยกับการเขียนแผ่นเหล็กทั้งหมดนี้ดังนั้นฉันแค่จะใส่คำอธิบายประกอบทั้งหมดของรัฐของฉันและปล่อยให้ภาชนะ DI ดูแลการตั้งค่าสำหรับฉัน"

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

ลองพิจารณาทางเลือกอื่น (นี่จะเป็น C # เพราะฉันรู้ดีกว่า แต่อาจเทียบเท่า Java แน่นอน):

public class VeracodeService
{        
    private readonly IResultsAPIWrapper _resultsApiWrapper;
    private readonly IAdminAPIWrapper _adminApiWrapper;
    private readonly IUploadAPIWrapper _uploadApiWrapper;
    private readonly IMitigationAPIWrapper _mitigationApiWrapper;

    // Constructor
    public VeracodeService(IResultsAPIWrapper resultsApiWrapper, IAdminAPIWrapper adminApiWrapper, IUploadAPIWrapper uploadApiWrapper,         IMitigationAPIWrapper mitigationApiWrapper)
    {
         _resultsAPIWrapper = resultsAPIWrapper;
         _adminAPIWrapper = adminAPIWrapper;
         _uploadAPIWrapper = uploadAPIWrapper;
         _mitigationAPIWrapper = mitigationAPIWrapper;
    }
}

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

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

ได้รับสิ่งนี้เป็นจำนวนมากสำเร็จรูป แต่นี่คือวิธีการออกแบบภาษา คำอธิบายประกอบดูเหมือนแฮ็คสกปรกสำหรับสิ่งที่ควรสร้างไว้ในภาษาของตัวเอง


ถ้าฉันไม่ได้อ่านโพสต์ของคุณผิดคุณจะไม่ได้ดูตัวอย่างที่ถูกต้อง การติดตั้งใช้งานของฉันVeracodeServiceใกล้เคียงกับที่คุณเขียนไว้ (แม้ว่าใน Java vs C #) VeracodeServiceImplTestเป็นจริงระดับหน่วยทดสอบ @Injectableฟิลด์ล้อเลียนหลักวัตถุถูกแทรกลงในบริบท @Testedฟิลด์วัตถุ / ชั้นกับ DI สร้างที่กำหนดไว้ ฉันเห็นด้วยกับมุมมองของคุณที่ชอบการสร้างคอนสตรัคเตอร์มากกว่าการฉีดภาคสนาม อย่างไรก็ตามอย่างที่ฉันพูดถึงผู้เขียน JMockit รู้สึกตรงกันข้ามและฉันพยายามเข้าใจว่าทำไม
Eric B.

หากคุณดูที่โพสต์แรกในการสนทนาคุณจะเห็นว่าฉันมี defn ที่เหมือนกันเกือบทั้งหมดในชั้นเรียน Repo ของฉัน
Eric B.

หากคุณกำลังพูดถึงคลาสทดสอบเท่านั้นมันอาจไม่สำคัญ เพราะชั้นเรียนทดสอบ
Robert Harvey

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

3
+1: ใช่ไม่มีเวทมนตร์ในรุ่น C # มันเป็นคลาสมาตรฐานมันมีการพึ่งพาพวกมันทั้งหมดถูกฉีดเข้าไปที่จุดหนึ่งก่อนที่จะมีการใช้คลาส คลาสสามารถใช้กับคอนเทนเนอร์ DI ได้หรือไม่ ไม่มีอะไรในคลาสที่บอกว่าเป็นกรอบ IOC หรือ "การพึ่งพาการพึ่งพาอัตโนมัติ"
Binary Worrier

27

อาร์กิวเมนต์ของ boiletplate ทดสอบการเริ่มต้นน้อยกว่านั้นใช้ได้ แต่มีข้อกังวลอื่น ๆ ที่ต้องนำมาพิจารณา ก่อนอื่นคุณต้องตอบคำถาม:

ฉันต้องการให้ชั้นเรียนของฉันสามารถสะท้อนได้ทันทีหรือไม่?

การใช้การฉีดภาคสนามหมายถึงการจำกัดความเข้ากันได้ของชั้นเรียนเพื่อให้สภาพแวดล้อมในการฉีดพึ่งพาซึ่งสร้างอินสแตนซ์ของวัตถุโดยใช้การสะท้อนภาพ บางแพลตฟอร์มที่ใช้ภาษาจาวาไม่รองรับการสะท้อนกลับ ( GWT ) ดังนั้นคลาส field ฟิลด์ที่ฉีดจะไม่สามารถทำงานร่วมกับพวกเขาได้

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

ผลการดำเนินงานมีผลกระทบต่อการบำรุงรักษา หากชุดทดสอบแต่ละชุดต้องทำงานในภาชนะฉีดพึ่งพาบางประเภทการทดสอบสองสามพันหน่วยทดสอบอาจใช้เวลาหลายสิบนาที นี่อาจเป็นปัญหาขึ้นอยู่กับขนาดของฐานรหัส

ทั้งหมดนี้ทำให้เกิดคำถามใหม่มากมาย:

  1. ความน่าจะเป็นในการใช้ชิ้นส่วนของรหัสบนแพลตฟอร์มอื่นคืออะไร
  2. จะมีการทดสอบหน่วยจำนวนเท่าไร
  3. ฉันต้องรวดเร็วแค่ไหนในการเตรียมการเปิดตัวแต่ละรุ่นใหม่
  4. ...

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

ข้อโต้แย้งมากมายจากการฉีดภาคสนาม


3
+1 คุณโดนเส้นประสาท ฉันไม่ชอบการสะท้อนความเห็นหรือกรอบ DI / IoC เพื่อยกตัวอย่างชั้นเรียน มันเหมือนกับการขับรถไปโรมเพื่อไปปารีสจากอัมสเตอร์ดัม ใจคุณฉันรัก DI เพียงแค่ไม่แน่ใจเกี่ยวกับกรอบ
Marjan Venema

1
ข้อโต้แย้งที่ดี มันใช้คำพูดมากมายในความคิดของฉัน แต่ฉันก็มีความสุขที่ได้เห็นคนอื่นรู้สึกแบบเดียวกัน น่าอัศจรรย์อย่างที่ฉันเคยเจอการฉีดภาคสนามฉันคิดว่าฉันชอบมากเพราะมัน "ง่ายกว่า" ฉันพบว่าคอนสตรัคเตอร์ฉีดชัดเจนขึ้นมากในขณะนี้
Eric B.

19

การฉีดภาคสนามได้รับการโหวตว่า "ไม่" จากฉัน

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

เช่น Maciej Chałapukฉันไม่ชอบการไตร่ตรองหรือ DI / IoC framework เพื่อยกตัวอย่างชั้นเรียน มันเหมือนกับการขับรถไปโรมเพื่อไปปารีสจากอัมสเตอร์ดัม

ใจคุณฉันรัก DI และข้อดีทั้งหมดที่นำมา เพียงแค่ไม่แน่ใจว่าต้องการกรอบการทำงานเพื่อยกตัวอย่างชั้นเรียน โดยเฉพาะอย่างยิ่งไม่ใช่ผลกระทบที่คอนเทนเนอร์ IoC หรือกรอบงาน DI อื่น ๆ สามารถมีรหัสทดสอบได้

ฉันชอบการทดสอบที่ตรงไปตรงมามาก ฉันไม่ชอบที่จะต้องผ่านการตั้งค่าคอนเทนเนอร์ IoC หรือโครงงาน DI อื่น ๆ เพื่อให้พวกเขาตั้งชั้นเรียนของฉันภายใต้การทดสอบ มันรู้สึกอึดอัดใจ

และทำให้การทดสอบของฉันขึ้นอยู่กับสถานะของกรอบงานทั่วโลก กล่าวคือฉันไม่สามารถรันการทดสอบสองแบบขนานที่ต้องการอินสแตนซ์ของคลาส X เพื่อตั้งค่าการพึ่งพาที่แตกต่างกันได้อีกต่อไป

อย่างน้อยด้วย Constructor และ Setter injection คุณมีตัวเลือกที่จะไม่ใช้เฟรมเวิร์กและ / หรือการสะท้อนกลับในการทดสอบของคุณ


ตัวอย่างเช่นถ้าคุณใช้ Mockito mockito.orgคุณไม่จำเป็นต้องมีกรอบ DI / IoC แม้ว่าจะใช้การฉีดภาคสนามและสามารถรันการทดสอบแบบขนานและอื่น ๆ ได้
Hans-Peter Störr

1
@hstoerr Nice อย่างไรก็ตามนั่นต้องหมายความว่า Mockito ใช้การสะท้อน (หรืออะไรก็ตามที่เทียบเท่ากับ Java ที่เรียกว่า) ...
Marjan Venema

5

ดูเหมือนว่าการถกเถียงเรื่องโต้เถียง สิ่งแรกที่ต้องได้รับการแก้ไขก็คือการฉีดสนามจะแตกต่างจากการฉีด Setter ฉันทำงานกับบางคนที่คิดว่า Field และ Setter injection เป็นสิ่งเดียวกัน

ดังนั้นเพื่อความชัดเจน:

การฉีดภาคสนาม:

@Autowired
private SomeService someService;

ฉีด Setter:

@Autowired
public void setSomeService(SomeService someService) {
    this.someService = someService;
}

แต่สำหรับฉันพวกเขามีความกังวลร่วมกัน และสิ่งที่ฉันชอบคือตัวสร้างการฉีด:

@AutoWired
public MyService(SomeService someService) {
    this.someService = someService;
}

ฉันมีเหตุผลต่อไปนี้ที่จะเชื่อว่าการฉีดคอนสตรัคเตอร์นั้นดีกว่า setter / field injection (ฉันจะอ้างลิงก์สปริงบางอันเพื่อแสดงจุดของฉัน):

  1. ป้องกันการพึ่งพาแบบวงกลม : สปริงสามารถตรวจจับการอ้างอิงแบบวงกลมระหว่างถั่วดังที่ @Tomasz อธิบาย ดูเพิ่มเติมที่Spring Teamด้วย
  2. การพึ่งพาของคลาสนั้นชัดเจน : การพึ่งพาของคลาสนั้นชัดเจนในตัวสร้างแต่ซ่อนด้วยการฉีดภาคสนาม / เซ็ตเตอร์ ฉันรู้สึกว่าชั้นเรียนของฉันเหมือน "กล่องดำ" ด้วยการฉีดภาคสนาม / เซ็ตเตอร์ และจากประสบการณ์ของฉันมีแนวโน้มที่นักพัฒนาจะไม่ใส่ใจกับคลาสที่มีการพึ่งพามากมายซึ่งเห็นได้ชัดเมื่อคุณพยายามจำลองคลาสโดยใช้การสร้างคอนสตรัคชัน (ดูรายการถัดไป) ปัญหาที่รบกวนผู้พัฒนามักจะได้รับการแก้ไข นอกจากนี้คลาสที่มีการขึ้นต่อกันมากเกินไปอาจละเมิดหลักการความรับผิดชอบเดี่ยว (SRP)
  3. ที่ง่ายและเชื่อถือได้ในการจำลอง : เมื่อเทียบกับการฉีดสนามก็ง่ายที่จะเยาะเย้ยในการทดสอบหน่วยเพราะคุณไม่จำเป็นต้องมีบริบทจำลองหรือสะท้อนเทคนิคในการเข้าถึงประกาศส่วนตัว Bean ภายในชั้นเรียนและคุณจะไม่ถูกหลอกโดยมัน คุณแค่ยกตัวอย่างชั้นเรียนและส่งถั่วที่เยาะเย้ย เข้าใจง่ายและเข้าใจง่าย
  4. เครื่องมือคุณภาพรหัสสามารถช่วยคุณได้ : เครื่องมือเช่น Sonar สามารถเตือนคุณเกี่ยวกับคลาสที่ซับซ้อนเกินไปเนื่องจากคลาสที่มีพารามิเตอร์จำนวนมากอาจเป็นคลาสที่ซับซ้อนเกินไปและต้องการผู้ปรับโครงสร้างบางส่วน เครื่องมือนี้ไม่สามารถระบุปัญหาเดียวกันได้เมื่อคลาสใช้ Field / Setter injection
  5. รหัสที่ดีขึ้นและอิสระ : ด้วยการ@AutoWiredแพร่กระจายน้อยลงในรหัสของคุณรหัสของคุณจะขึ้นอยู่กับกรอบน้อย ฉันรู้ว่าความเป็นไปได้ที่จะเปลี่ยนกรอบ DI ง่าย ๆ ในโครงการไม่ได้พิสูจน์ว่า (ใครทำอย่างนั้นใช่ไหม) แต่นี่แสดงให้เห็นว่าสำหรับฉันรหัสที่ดีกว่า (ฉันได้เรียนรู้สิ่งนี้อย่างยากลำบากกับ EJB และการค้นหา) และด้วยสปริงคุณสามารถลบ@AutoWiredคำอธิบายประกอบโดยใช้การสร้างคอนสตรัคชัน
  6. คำอธิบายประกอบเพิ่มเติมจะไม่เสมอคำตอบที่เหมาะสม : สำหรับบางเหตุผลที่ผมพยายามที่จะใช้คำอธิบายประกอบเฉพาะเมื่อพวกเขามีประโยชน์จริงๆ
  7. คุณสามารถทำให้การฉีดไม่เปลี่ยนรูป การเปลี่ยนแปลงไม่ได้เป็นคุณสมบัติที่ยินดีอย่างมาก

หากคุณกำลังมองหาข้อมูลเพิ่มเติมฉันขอแนะนำบทความเก่า (แต่ยังมีความเกี่ยวข้อง)จาก Spring Blog ซึ่งบอกเราว่าเหตุใดจึงใช้ setter injection มากและคำแนะนำในการใช้ constructor injection:

การฉีด setter นั้นถูกใช้บ่อยกว่าที่คุณคาดไว้เป็นความจริงที่ว่าเฟรมเวิร์กเช่น Spring โดยทั่วไปมีความเหมาะสมมากกว่าที่จะกำหนดค่าโดย setter injection มากกว่าการฉีด constructor

และบันทึกนี้เกี่ยวกับสาเหตุที่พวกเขาเชื่อว่านวกรรมิกเหมาะสำหรับรหัสแอปพลิเคชัน:

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

ความคิดสุดท้าย

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

เนื่องจากคุณสามารถผสมทั้ง Constructor- และ Setter-based DI มันเป็นกฎง่ายๆในการใช้อาร์กิวเมนต์ของ Constructor สำหรับการขึ้นต่อกันที่จำเป็นและ setters สำหรับการพึ่งพาที่ไม่จำเป็น

แต่จำไว้ว่าการฉีดภาคสนามนั้นน่าจะเป็นสิ่งที่ควรหลีกเลี่ยงในบรรดาสามคนนี้


-5

การพึ่งพาของคุณมีแนวโน้มที่จะเปลี่ยนแปลงในช่วงชีวิตของการเรียน? ถ้าเป็นเช่นนั้นใช้การฉีดภาคสนาม / ทรัพย์สิน มิฉะนั้นให้ใช้ตัวสร้างการฉีด


2
สิ่งนี้ไม่ได้อธิบายอะไรเลย ทำไมต้องแทรกเขตข้อมูลส่วนบุคคลเมื่อคุณสามารถทำวิธีที่เหมาะสมแทน
Robert Harvey

มันจะพูดอะไรเกี่ยวกับเขตข้อมูลส่วนตัว? ฉันกำลังพูดถึงอินเทอร์เฟซสาธารณะของคลาส /
Darren Young

ไม่มีข้อโต้แย้งเกี่ยวกับวิธีการฉีดและการสร้างคอนสตรัคชันในคำถาม ผู้เขียน JMockit เห็นว่าทั้งคู่เลวร้าย ดูที่ชื่อของคำถาม
Robert Harvey

คำถามไม่ได้บอกว่าการฉีดภาคสนามกับการฉีดคอนสตรัคเตอร์?
Darren Young

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