前言
你可能看過很多課程,每個都跟你說要寫出高內聚低耦合,少不了依賴注入的使用。又或者Spring Boot、.NET等框架學習,最初幾個章節大多會介紹依賴注入,甚至許多資深前輩開口閉口總是一句: 不要自己new,讓框架幫你處理。
在真實專案裡,我們確實大量使用框架提供的 DI 特性(例如 Spring 的 @Autowired),但有時候在維護或理解程式時,還是會疑惑:不自己 new,功能到底要怎麼寫?
原始寫法
// 咖啡豆
class ArabicaBean {
public String getBean() {
return "阿拉比卡咖啡豆";
}
}
// 咖啡機自己 new 咖啡豆
class CoffeeMachine {
private CoffeeBean bean;
public CoffeeMachine() {
this.bean = new ArabicaBean(); // 直接 new
}
public void brew() {
System.out.println("沖煮 " + bean.getBean());
}
}
public class App {
public static void main(String[] args) {
CoffeeMachine machine = new CoffeeMachine();
machine.brew();
}
}
- 主要方法很單純,new建立一台咖啡機實例,呼叫煮咖啡。
- 咖啡機在建立實際的咖啡豆,也就是阿拉比卡咖啡豆,咖啡機擁有控制權。
- 如果要曼特寧豆,不好意思,請買別台機器,因為咖啡機寫死只能用阿拉比卡豆。
改成依賴注入
class ArabicaBean {
public String getBean() {
return "阿拉比卡咖啡豆";
}
}
// 咖啡機:不自己 new,外部給豆子
class CoffeeMachine {
private ArabicaBean bean;
public CoffeeMachine(ArabicaBean bean) { // 建構子注入
this.bean = bean;
}
public void brew() {
System.out.println("沖煮 " + bean.getBean());
}
}
public class App {
public static void main(String[] args) {
// 外部決定要用哪種豆子
ArabicaBean bean = new ArabicaBean();
CoffeeMachine machine = new CoffeeMachine(bean); // 注入依賴
machine.brew();
}
}
- 咖啡機不自己建立咖啡豆,建構子改由外部傳入豆子,控制權已移轉。
- 主要方法在使用上,改由先決定哪個咖啡豆,再把豆子丟給咖啡機。
- 如果要曼特寧豆,抱歉,機器還是只吃阿拉比卡豆。
加入抽象
當然,總不能一台機器只能煮單一種豆子吧? 可以加入抽象解決這個問題。
// 咖啡豆抽象
interface CoffeeBean {
String getBean();
}
// 具體的咖啡豆
class ArabicaBean implements CoffeeBean {
public String getBean() {
return "阿拉比卡咖啡豆";
}
}
class MandhelingBean implements CoffeeBean {
public String getBean() {
return "曼特寧咖啡豆";
}
}
// 咖啡機不自己 new,外部注入
class CoffeeMachine {
private CoffeeBean bean;
public CoffeeMachine(CoffeeBean bean) { // 建構子注入
this.bean = bean;
}
public void brew() {
System.out.println("沖煮 " + bean.getBean());
}
}
public class App {
public static void main(String[] args) {
// 外部決定要用哪種豆子
CoffeeBean bean = new MandhelingBean();
CoffeeMachine machine = new CoffeeMachine(bean); // 注入依賴
machine.brew();
}
}
- 主要方法決定要哪種咖啡豆,就new出實際咖啡豆丟給咖啡機
- 只要阿拉比卡跟曼特寧是咖啡豆,咖啡機就能運作
框架做了什麼?
透過上述例子可以發現一件事: 外部總得有個地方去new出物件,只不過更集中管理,而這個最髒的地方,正是框架幫我們處理的事情,包含物件的建立、生命週期控管、自動解析依賴並注入到需要的地方。
理解了這些,你就能更清楚框架在底層如何運作,也能在面對這些技術名詞時更從容地掌握它們的意義。


















