การฉีดภาคสนามเป็นเรื่องเล็กน้อยเกินไป"การกระทำที่น่ากลัวในระยะไกล"สำหรับรสนิยมของฉัน
ลองพิจารณาตัวอย่างที่คุณให้ไว้ในโพสต์ของ 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 ซึ่งเป็นวิธีการที่มีจุดประสงค์ชัดเจนในการจัดเตรียมคลาสที่มีการอ้างอิงที่ต้องการ
ได้รับสิ่งนี้เป็นจำนวนมากสำเร็จรูป แต่นี่คือวิธีการออกแบบภาษา คำอธิบายประกอบดูเหมือนแฮ็คสกปรกสำหรับสิ่งที่ควรสร้างไว้ในภาษาของตัวเอง