[請益] Spring boot的依賴注入降低耦合的例子

看板Soft_Job作者 (阿龍)時間2年前 (2022/03/31 21:06), 2年前編輯推噓25(250102)
留言127則, 28人參與, 2年前最新討論串1/8 (看更多)
推文有個連結有解答我的疑惑 感謝bron大 文章有點長 先說說我對依賴注入的理解 Spring boot 依賴注入大致有三種方式 透過建構子的 透過setter的 或是 field 這三種都可以透過@Autowired註解來達到依賴注入的效果 我自己想到的建構子的舉例是 假設有兩個類 Address 和 Employee好了 1. public class Address { String Country; String City; String Street; public Address(String country, String city, String street) { Country = country; City = city; Street = street; } } 2. public class Employee { String sex; String name; Address address; // 沒有依賴注入的方式 public Employee(String Country,String City,String Street,String sex, String name ) { this.sex=sex; this.address = new Address( Country, City,Street ); this.name=name; } // 有依賴注入的方式 public Employee(String sex, String name, Address address) { this.sex = sex; this.name = name; this.address = address; } } 在上面的例子當中可以發現,如果哪一天 Address這個類新增了一個屬性叫 phoneNumber好了 沒有依賴注入的方式,必須要更改 Employee 的 this.address =new Address(Country,City,Street,phoneNumber) 而有依賴注入的方式確實降低了耦合 因為他不用更改Employee的建構方式 所以我理解依賴注入可以降低耦合 所以我理解依賴注入可以降低耦合 所以我理解依賴注入可以降低耦合 但我的問題是Spring boot 的 autowird annotation 有幫助我們降低耦合嗎 在常見的開發中 我們經常都會有 Dao 以及 Service 假設我有兩個 Dao 好了 分別是 Dao1 和 Dao2 以及一個Service Dao1 public class Dao { public void sayhi() { System.out.println("hello"); } } Dao1 public class Dao { public void sayhi() { System.out.println("hello"); } } Dao2 public class Dao2 { public void saygoodbye() { System.out.println("say goodbye"); } } 如果我不在service上面使用autowired 我的service會是 public class Service { Dao1 dao=new Dao1(); Dao2 dao2=new Dao2(); public void sayhi() { dao.sayhi(); } public void saygoodbye() { dao2.saygoodbye(); } } 如果我使用了@Autowired註解 那我只是將 Dao1 dao=new Dao1(); Dao2 dao2=new Dao2(); 替換成 @Autowired Dao1 dao @Autowired Dao2 dao2 我想請問所以我使用了Autowired註解 我知道我可以不需要使用new 來建構實體 但 Spring 真的有幫我降低耦合嗎 即使我換成 setter 配合 autowired的方式好了 那個 setter也是要我自己去撰寫 Spring 幫我降低了耦合甚麼? 我的問題簡單來說就是 我知道依賴注入可以降低耦合 但Spring boot透過 @Autowired註解幫我降低耦合在哪 謝謝 p.s 因為面試的時候常常被面試官問說懂不懂甚麼是 控制反轉還有DI,我基本上舉例都舉 Address還有 Employee的例子 但當我反問下面例子的時候,他們好像也說要再回去想一下... 只有其中一個就說更複雜的例子會用到,但也沒說甚麼是更複雜的例子QQ -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 118.167.157.11 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/Soft_Job/M.1648731970.A.382.html ※ 編輯: ntpuisbest (49.216.186.239 臺灣), 03/31/2022 21:14:38

03/31 21:27, 2年前 , 1F
當有需要抽換實作的時候
03/31 21:27, 1F

03/31 21:29, 2年前 , 2F
在你理解前應該先完全不靠 spring 的功能,只靠 java
03/31 21:29, 2F

03/31 21:29, 2年前 , 3F
本身來做依賴注入,然後判斷有沒有真的有效就是你的類
03/31 21:29, 3F

03/31 21:29, 2年前 , 4F
可以把依賴的東西改用mock替換。那等你都弄好後開始不
03/31 21:29, 4F

03/31 21:29, 2年前 , 5F
斷的堆積業務邏輯時,就會發現初始化的地方會有一堆 n
03/31 21:29, 5F

03/31 21:29, 2年前 , 6F
ew constructor 然後再傳進另一個 new constructor,那
03/31 21:29, 6F

03/31 21:29, 2年前 , 7F
這時候一個像 spring 這樣的框架就可以用各種方式來幫
03/31 21:29, 7F

03/31 21:29, 2年前 , 8F
助你避免自己寫這些 new,就可以避免一些麻煩。 但我是
03/31 21:29, 8F

03/31 21:29, 2年前 , 9F
喜歡自己手動操作啦,靠框架的話整個生命周期很難看懂
03/31 21:29, 9F

03/31 21:29, 2年前 , 10F
03/31 21:29, 10F

03/31 21:33, 2年前 , 11F
我覺得任何DI framework都跟singleton 87%像邪惡
03/31 21:33, 11F

03/31 21:35, 2年前 , 12F
個人覺得方便測試時去 mock,平常用 Laravel 的經驗
03/31 21:35, 12F

03/31 21:39, 2年前 , 13F
Polymorphism
03/31 21:39, 13F

03/31 21:42, 2年前 , 14F
通常是autowired interface啦,再依參數配置決定要使用
03/31 21:42, 14F

03/31 21:43, 2年前 , 15F
簡單的例子就是更換DB driver
03/31 21:43, 15F

03/31 21:44, 2年前 , 16F
哪個實作上面那interface的component
03/31 21:44, 16F

03/31 22:00, 2年前 , 17F
@Autowired只是依類名或型別幫你在Spring容器生物件
03/31 22:00, 17F

03/31 22:01, 2年前 , 18F
DI與IoC才是低耦合的關鍵,與@Autowired無關
03/31 22:01, 18F

03/31 22:03, 2年前 , 19F
可是如果DI要我自己寫的話,Spring幫我做了啥,單純
03/31 22:03, 19F

03/31 22:03, 2年前 , 20F
的控制反轉有降低耦合嗎?
03/31 22:03, 20F

03/31 22:04, 2年前 , 21F
Spring幫你new物件並注入到使用的對象屬性中
03/31 22:04, 21F

03/31 22:05, 2年前 , 22F
還有上面Dao1 Dao2例子有誤,DI是從外面set進來
03/31 22:05, 22F

03/31 22:07, 2年前 , 23F
我的第一個例子應該是DI吧,把ADDRESS注入到Employee
03/31 22:07, 23F

03/31 22:07, 2年前 , 24F
當中
03/31 22:07, 24F

03/31 22:08, 2年前 , 25F
即使用Spring,不用自己寫new,可是建構子還是要自己寫
03/31 22:08, 25F

03/31 22:08, 2年前 , 26F
阿,降低了什麼功夫呢
03/31 22:08, 26F

03/31 22:10, 2年前 , 27F
幫你搞定層層的依賴關係
03/31 22:10, 27F

03/31 22:10, 2年前 , 28F
你可以試試不用Spring自己寫依賴注入,你就知道差異
03/31 22:10, 28F

03/31 22:13, 2年前 , 29F
我第一個例子就沒有依賴Spring 阿 地址跟員工那個
03/31 22:13, 29F

03/31 22:16, 2年前 , 30F
spring就是做掉你自己舉的例子,不然誰要往兩個class傳
03/31 22:16, 30F

03/31 22:16, 2年前 , 31F
dao進去?
03/31 22:16, 31F

03/31 22:18, 2年前 , 32F
你後面舉的自己new dao的行為,就等於你前面沒有做DI的
03/31 22:18, 32F

03/31 22:18, 2年前 , 33F
舉例了
03/31 22:18, 33F

03/31 22:19, 2年前 , 34F
我看下來只覺得原po寫太少了 哈哈哈哈
03/31 22:19, 34F

03/31 22:24, 2年前 , 35F
今天是dao你感覺比較單純無法,如果你要new的是service
03/31 22:24, 35F

03/31 22:24, 2年前 , 36F
呢?視你的專案複雜度,一個service可能會有10幾20個建
03/31 22:24, 36F

03/31 22:24, 2年前 , 37F
構子需要你自己new出來,而service互相依賴不會只有有
03/31 22:24, 37F

03/31 22:24, 2年前 , 38F
兩個這樣簡單的情況
03/31 22:24, 38F
我有試著在Controller當中去new service @RestController public class Controller { Service service=new Service( ); @GetMapping("test") public void saysomething() { service.saygoodbye(); service.sayhi(); } } 即使Service 裡面需要20個DAO好了 在Controller裡面new Service不也一樣只要 一行 Service service=new Service( ); 另外如果是setter 或是 Constructor方式的 DI 就我的理解 setter和建構子也是要自己寫 Spring 不會幫你產生 那我這樣看起來好像只是幫你從 new 換成了 @Autowired 這樣真的看不太出來 降低了甚麼耦合 因為建構子也是要自己寫啊 我覺得我好像陷入了泥淖中了QQ 翻了很多網頁,舉的例子大都跟我自己舉的 員工還有地址的差不多 ※ 編輯: ntpuisbest (118.167.157.11 臺灣), 03/31/2022 22:36:56
還有 49 則推文
還有 1 段內文
04/01 09:29, 2年前 , 88F
當你打算寫單元測試就會懂DI的好處了
04/01 09:29, 88F

04/01 10:25, 2年前 , 89F
@Autowired找到完全同一個concrete class的bean來注入本來
04/01 10:25, 89F

04/01 10:27, 2年前 , 90F
就沒有降低耦合,可以找到相容的實作(實作interface的bean
04/01 10:27, 90F

04/01 10:27, 2年前 , 91F
或subclass的bean)才有降低耦合
04/01 10:27, 91F

04/01 10:40, 2年前 , 92F
Autowired介面,搭配profile註解,可以在不同環境使用不
04/01 10:40, 92F

04/01 10:40, 2年前 , 93F
同實作
04/01 10:40, 93F

04/01 10:52, 2年前 , 94F
關於di,spring in action有個騎士出任務的範例,還蠻有
04/01 10:52, 94F

04/01 10:52, 2年前 , 95F
趣的
04/01 10:52, 95F

04/01 13:45, 2年前 , 96F
你可以A一下91哥的文 id是landlord
04/01 13:45, 96F

04/01 13:45, 2年前 , 97F
他有個土砲重構的範例滿不錯的
04/01 13:45, 97F

04/01 18:42, 2年前 , 98F
spring 只是稍微降低耦合。主要降低的是多用介面,多寫
04/01 18:42, 98F

04/01 18:42, 2年前 , 99F
幾層
04/01 18:42, 99F

04/01 23:51, 2年前 , 100F
不想講但還是講一下好了 它就只是偵測你包內的
04/01 23:51, 100F

04/01 23:51, 2年前 , 101F
annotation並且儲存起來(map) 需要的時候取用初始化
04/01 23:51, 101F

04/01 23:52, 2年前 , 102F
而已 依賴注入本身不是問題 問題是使用annotation的
04/01 23:52, 102F

04/01 23:53, 2年前 , 103F
依賴注入 專案大了以後 一堆初始化流程你都不見得能
04/01 23:53, 103F

04/01 23:54, 2年前 , 104F
夠掌握 更別說annotation設值所造成的影響
04/01 23:54, 104F

04/01 23:55, 2年前 , 105F
然後這樣的初始化效能肯定比你直接new來的差
04/01 23:55, 105F

04/01 23:57, 2年前 , 106F
介面的話更是扯 你直接改個類不就得了... 當然如果
04/01 23:57, 106F

04/01 23:57, 2年前 , 107F
習慣非常好 用annotation也都無所謂 但你不一定是一
04/01 23:57, 107F

04/01 23:57, 2年前 , 108F
一個人開發
04/01 23:57, 108F

04/02 00:00, 2年前 , 109F
用這些框架有時候就不是人在使用工具 是人被工具玩
04/02 00:00, 109F

04/02 00:01, 2年前 , 110F
更準確的是人寫工具的惡意 而非工具本身自主
04/02 00:01, 110F

04/02 00:06, 2年前 , 111F
無腦開發你才有人生 耗在這沒意義的事情才糟糕
04/02 00:06, 111F

04/02 10:32, 2年前 , 112F
樓上肯定沒用到request、session、refresh scope
04/02 10:32, 112F

04/02 10:32, 2年前 , 113F
才會覺得spring DI只是個map存起來這麼簡單
04/02 10:32, 113F

04/02 22:42, 2年前 , 114F
當然不是講的這麼大致方向 剩下的就只是應用再應用
04/02 22:42, 114F

04/02 22:44, 2年前 , 115F
講的這些真的要自己寫框架不難寫
04/02 22:44, 115F

04/02 22:46, 2年前 , 116F
只是個人不會遇到一個問題解決了再創造一個名詞
04/02 22:46, 116F

04/02 22:48, 2年前 , 117F
光看這些其實很容易眼花撩亂 還是學習真的知識比較好
04/02 22:48, 117F

04/03 10:31, 2年前 , 118F
Java 哈哈 Java
04/03 10:31, 118F

04/03 10:31, 2年前 , 119F
Old school try hard language
04/03 10:31, 119F

04/03 10:31, 2年前 , 120F
搞笑的語言就是只能搞笑
04/03 10:31, 120F

04/03 21:17, 2年前 , 121F
去除掉springBoot,IoC、DI和DIP這些概念又不是Java獨有
04/03 21:17, 121F

04/03 21:17, 2年前 , 122F
,說Java搞笑跟這篇文章的關聯真是無法理解!?
04/03 21:17, 122F

04/04 13:21, 2年前 , 123F
樓上找給我看除了 Java 以外還有哪個語言什麼事都要 anno
04/04 13:21, 123F

04/04 13:21, 2年前 , 124F
tations ,設定檔,框架魔法和 reflection 才能做的?真
04/04 13:21, 124F

04/04 13:21, 2年前 , 125F
的笑死
04/04 13:21, 125F

04/04 14:04, 2年前 , 126F

04/04 21:15, 2年前 , 127F
嗯嗯,您說得對
04/04 21:15, 127F
文章代碼(AID): #1YHQT2E2 (Soft_Job)
討論串 (同標題文章)
文章代碼(AID): #1YHQT2E2 (Soft_Job)