昨天有網友Call我留言,說他寫了個DI架構,讓我有時間看看,於是我就上去看了:
文章地址: http://www.cnblogs.com/lenic/archive/2013/06/04/3117893.html
發現是E文的,於是回復:
路過秋天
22:
32:
43
怎么還寫E文的
NOoK 22: 33: 03
直接在 CodePlex 上寫的介紹
NOoK 22: 33: 08
然后就粘過來了
NOoK 22: 33: 15
結果還被博客園下架了。。。
NOoK 22: 34: 40
悲催的
路過秋天 22: 35: 34
誰讓你 Look it on CodePlex
NOoK 22: 35: 41
。。。
怎么還寫E文的
NOoK 22: 33: 03
直接在 CodePlex 上寫的介紹
NOoK 22: 33: 08
然后就粘過來了
NOoK 22: 33: 15
結果還被博客園下架了。。。
NOoK 22: 34: 40
悲催的
路過秋天 22: 35: 34
誰讓你 Look it on CodePlex
NOoK 22: 35: 41
。。。
我錯了
接着他讓我下載他的處女開源項目,讓我看看:
NOoK
22
:
36
:
09
明天再修改一下吧
路過秋天 22: 37: 26
平時都習慣寫英文?
NOoK 22: 37: 40
肯定不是啊
NOoK 22: 38: 03
在 CodePlex 上面寫了,懶得改就貼過來了
路過秋天 22: 38: 43
平時也在CodePlex上面寫?
NOoK 22: 38: 54
第一個開源項目。。。
NOoK 22: 40: 35
改好了再說吧
路過秋天 22: 40: 46
NOoK 22: 41: 14
你可以下載代碼看看,維護了好幾年了
路過秋天 22: 43: 17
Ok,我看看
路過秋天 22: 48: 23
掃了一下,不是很理解
NOoK 22: 50: 15
思路是,注冊委托進字典,需要的時候,再用委托生成對象
NOoK 22: 50: 41
然后衍生了多個生存周期;
路過秋天 22: 50: 50
實用場景 ?
NOoK 22: 51: 42
一樣啊
NOoK 22: 51: 56
就是IOC的使用場景
NOoK 22: 52: 46
這個核心代碼,類似於Ninject,沒配置
明天再修改一下吧
路過秋天 22: 37: 26
平時都習慣寫英文?
NOoK 22: 37: 40
肯定不是啊
NOoK 22: 38: 03
在 CodePlex 上面寫了,懶得改就貼過來了
路過秋天 22: 38: 43
平時也在CodePlex上面寫?
NOoK 22: 38: 54
第一個開源項目。。。
NOoK 22: 40: 35
改好了再說吧
路過秋天 22: 40: 46
NOoK 22: 41: 14
你可以下載代碼看看,維護了好幾年了
路過秋天 22: 43: 17
Ok,我看看
路過秋天 22: 48: 23
掃了一下,不是很理解
NOoK 22: 50: 15
思路是,注冊委托進字典,需要的時候,再用委托生成對象
NOoK 22: 50: 41
然后衍生了多個生存周期;
路過秋天 22: 50: 50
實用場景 ?
NOoK 22: 51: 42
一樣啊
NOoK 22: 51: 56
就是IOC的使用場景
NOoK 22: 52: 46
這個核心代碼,類似於Ninject,沒配置
由於本人對IOC,雖然曾多次看過網上的文章介紹,除了“依賴注入,控制反轉”這八個字,沒有多余的存檔記憶了。
后來的聊天,我讓他給我舉一個實用場景,畢竟我是實戰派的,一種模式或一種東東,只有擺在現實的場景,並且有過深刻的使用痕跡,才能記的深,用的勞。
像那些設計模式的文章,一來就是UML圖,舉個例子基本就是貓和狗,要不就是會飛的鴨子。
費我十八層腦力,終於理解明白了。
第二天一睡醒,基本沒印象。
再過些天。。。連設計模式的名字都不知叫什么了。
費我十八層腦力,終於理解明白了。
第二天一睡醒,基本沒印象。
再過些天。。。連設計模式的名字都不知叫什么了。
后來中間擰了一陣,基本沒擰在一塊,我要的是實戰場景,他老給我講理論。
於是我就遷就他學理論了,我搜索看了看IOC的的基本介紹:
控制反轉(Inversion of Control,英文縮寫為IoC)是一個重要的面向對象編程的法則來削減計算機程序的耦合問題。 控制反轉還有一個名字叫做依賴注入(Dependency Injection)。簡稱DI。
早在2004年,Martin Fowler就提出了“哪些方面的控制被反轉了?”這個問題。他總結出是依賴對象的獲得被反轉了。基於這個結論,他為控制反轉創造了一個更好的名字:依賴注入。許多非凡的應用(比HelloWorld.java更加優美,更加復雜)都是由兩個或是更多的類通過彼此的合作來實現業務邏輯,這使得每個對象都需要,與其合作的對象(也就是它所依賴的對象)的引用。如果這個獲取過程要靠自身實現,那么如你所見,這將導致代碼高度耦合並且難以測試。
IoC 亦稱為 “依賴倒置原理”( " Dependency Inversion Principle ")。差不多所有框架都使用了“倒置注入(Fowler 2004)技巧,這可說是IoC原理的一項應用。SmallTalk,C++, Java 或各種.NET 語言等面向對象程序語言的程序員已使用了這些原理。
控制反轉是Spring框架的核心。
應用控制反轉,對象在被創建的時候,由一個調控系統內所有對象的外界實體,將其所依賴的對象的引用,傳遞給它。也可以說,依賴被注入到對象中。所以,控制反轉是,關於一個對象如何獲取他所依賴的對象的引用,這個責任的反轉。
oC就是IoC,不是什么技術,與GoF一樣,是一種設計模式。
早在2004年,Martin Fowler就提出了“哪些方面的控制被反轉了?”這個問題。他總結出是依賴對象的獲得被反轉了。基於這個結論,他為控制反轉創造了一個更好的名字:依賴注入。許多非凡的應用(比HelloWorld.java更加優美,更加復雜)都是由兩個或是更多的類通過彼此的合作來實現業務邏輯,這使得每個對象都需要,與其合作的對象(也就是它所依賴的對象)的引用。如果這個獲取過程要靠自身實現,那么如你所見,這將導致代碼高度耦合並且難以測試。
IoC 亦稱為 “依賴倒置原理”( " Dependency Inversion Principle ")。差不多所有框架都使用了“倒置注入(Fowler 2004)技巧,這可說是IoC原理的一項應用。SmallTalk,C++, Java 或各種.NET 語言等面向對象程序語言的程序員已使用了這些原理。
控制反轉是Spring框架的核心。
應用控制反轉,對象在被創建的時候,由一個調控系統內所有對象的外界實體,將其所依賴的對象的引用,傳遞給它。也可以說,依賴被注入到對象中。所以,控制反轉是,關於一個對象如何獲取他所依賴的對象的引用,這個責任的反轉。
oC就是IoC,不是什么技術,與GoF一樣,是一種設計模式。
當然了,資料還有一大堆,就不詳細貼了。
后來他為了擰過我,決定給我培訓一下,給我出了道題:
NOoK
23:
30:
52
要不要做題?
NOoK 23: 31: 28
一個四則運算的
路過秋天 23: 32: 06
說說看
NOoK 23: 32: 06
好吧,我睡覺了,晚安咯
NOoK 23: 33: 30
通過不同的配置,加載不同的程序集,實現四則運算
NOoK 23: 34: 19
輸入兩個參數,運算得到結果
NOoK 23: 35: 01
不允許用反射
路過秋天 23: 35: 31
其它條件呢?
NOoK 23: 35: 39
沒有了
路過秋天 23: 36: 33
使用程序集,卻不允許用反射?
NOoK 23: 36: 42
我就是想通過兩個數字,得到結果,怎么運算我不管,只要給我結果就好
NOoK 23: 37: 07
你可以寫到一個程序集里面
路過秋天 23: 37: 28
過程就是修改配置?
NOoK 23: 37: 29
我說錯了,加載程序集就是反射
NOoK 23: 37: 51
哥,你問偏了
NOoK 23: 38: 11
過程你寫好
NOoK 23: 38: 34
通過配置修改
路過秋天 23: 38: 51
OK,我try一下
NOoK 23: 39: 09
我等你消息啊,哈哈
要不要做題?
NOoK 23: 31: 28
一個四則運算的
路過秋天 23: 32: 06
說說看
NOoK 23: 32: 06
好吧,我睡覺了,晚安咯
NOoK 23: 33: 30
通過不同的配置,加載不同的程序集,實現四則運算
NOoK 23: 34: 19
輸入兩個參數,運算得到結果
NOoK 23: 35: 01
不允許用反射
路過秋天 23: 35: 31
其它條件呢?
NOoK 23: 35: 39
沒有了
路過秋天 23: 36: 33
使用程序集,卻不允許用反射?
NOoK 23: 36: 42
我就是想通過兩個數字,得到結果,怎么運算我不管,只要給我結果就好
NOoK 23: 37: 07
你可以寫到一個程序集里面
路過秋天 23: 37: 28
過程就是修改配置?
NOoK 23: 37: 29
我說錯了,加載程序集就是反射
NOoK 23: 37: 51
哥,你問偏了
NOoK 23: 38: 11
過程你寫好
NOoK 23: 38: 34
通過配置修改
路過秋天 23: 38: 51
OK,我try一下
NOoK 23: 39: 09
我等你消息啊,哈哈
根據要求,2-3分鍾后,我就上圖了:
根據配置,加個switch,解決了,不過既然我們在說IOC,肯定是需要不斷演進。
NOoK
0:
02:
58
如果這里的業務很負責呢
NOoK 0: 03: 04
不是簡單的四則運算
NOoK 0: 03: 08
你怎么辦
路過秋天 0: 03: 14
很負責?
NOoK 0: 03: 43
很復雜
NOoK 0: 03: 48
手誤
路過秋天 0: 03: 50
既然是題目,你就舉個場景,我按場景實現
NOoK 0: 04: 06
你應該寫4個類,對不對
NOoK 0: 04: 11
分別實現四種運算
NOoK 0: 04: 21
比這樣寫一個類要好
NOoK 0: 04: 28
以后擴展就可以再寫一個類
如果這里的業務很負責呢
NOoK 0: 03: 04
不是簡單的四則運算
NOoK 0: 03: 08
你怎么辦
路過秋天 0: 03: 14
很負責?
NOoK 0: 03: 43
很復雜
NOoK 0: 03: 48
手誤
路過秋天 0: 03: 50
既然是題目,你就舉個場景,我按場景實現
NOoK 0: 04: 06
你應該寫4個類,對不對
NOoK 0: 04: 11
分別實現四種運算
NOoK 0: 04: 21
比這樣寫一個類要好
NOoK 0: 04: 28
以后擴展就可以再寫一個類
好吧,很復雜的話,要分類就這樣了:

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace ABCD
{
class Program
{
static void Main( string[] args)
{
while ( true)
{
Console.Read();
int result = GetResult( 12, 4);
Console.WriteLine(result);
}
}
static int GetResult( int a, int b)
{
switch (GetConfig())
{
case " + ":
return new A().GetResult(a,b);
case " - ":
return new B().GetResult(a, b);
case " * ":
return new C().GetResult(a, b);
case " / ":
return new D().GetResult(a, b);
}
return 0;
}
static string GetConfig()
{
string config = AppDomain.CurrentDomain.BaseDirectory + " config.ini ";
return File.ReadAllText(config);
}
}
public class A
{
public int GetResult( int a, int b)
{
return a + b;
}
}
public class B
{
public int GetResult( int a, int b)
{
return a - b;
}
}
public class C
{
public int GetResult( int a, int b)
{
return a * b;
}
}
public class D
{
public int GetResult( int a, int b)
{
return a / b;
}
}
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace ABCD
{
class Program
{
static void Main( string[] args)
{
while ( true)
{
Console.Read();
int result = GetResult( 12, 4);
Console.WriteLine(result);
}
}
static int GetResult( int a, int b)
{
switch (GetConfig())
{
case " + ":
return new A().GetResult(a,b);
case " - ":
return new B().GetResult(a, b);
case " * ":
return new C().GetResult(a, b);
case " / ":
return new D().GetResult(a, b);
}
return 0;
}
static string GetConfig()
{
string config = AppDomain.CurrentDomain.BaseDirectory + " config.ini ";
return File.ReadAllText(config);
}
}
public class A
{
public int GetResult( int a, int b)
{
return a + b;
}
}
public class B
{
public int GetResult( int a, int b)
{
return a - b;
}
}
public class C
{
public int GetResult( int a, int b)
{
return a * b;
}
}
public class D
{
public int GetResult( int a, int b)
{
return a / b;
}
}
剛發過去,就來一句:可以提取一個接口嗎
改了改,代碼發過去如下:

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace ABCD
{
class Program
{
static void Main( string[] args)
{
while ( true)
{
Console.Read();
int result = GetResult( 12, 4);
Console.WriteLine(result);
}
}
static int GetResult( int a, int b)
{
IGetResult iResult = null;
switch (GetConfig())
{
case " + ":
iResult = new A();
break;
case " - ":
iResult = new B();
break;
case " * ":
iResult = new C();
break;
case " / ":
iResult = new D();
break;
}
return iResult.GetResult(a, b);
}
static string GetConfig()
{
string config = AppDomain.CurrentDomain.BaseDirectory + " config.ini ";
return File.ReadAllText(config);
}
}
public interface IGetResult
{
int GetResult( int a, int b);
}
public class A : IGetResult
{
public int GetResult( int a, int b)
{
return a + b;
}
}
public class B : IGetResult
{
public int GetResult( int a, int b)
{
return a - b;
}
}
public class C : IGetResult
{
public int GetResult( int a, int b)
{
return a * b;
}
}
public class D : IGetResult
{
public int GetResult( int a, int b)
{
return a / b;
}
}
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace ABCD
{
class Program
{
static void Main( string[] args)
{
while ( true)
{
Console.Read();
int result = GetResult( 12, 4);
Console.WriteLine(result);
}
}
static int GetResult( int a, int b)
{
IGetResult iResult = null;
switch (GetConfig())
{
case " + ":
iResult = new A();
break;
case " - ":
iResult = new B();
break;
case " * ":
iResult = new C();
break;
case " / ":
iResult = new D();
break;
}
return iResult.GetResult(a, b);
}
static string GetConfig()
{
string config = AppDomain.CurrentDomain.BaseDirectory + " config.ini ";
return File.ReadAllText(config);
}
}
public interface IGetResult
{
int GetResult( int a, int b);
}
public class A : IGetResult
{
public int GetResult( int a, int b)
{
return a + b;
}
}
public class B : IGetResult
{
public int GetResult( int a, int b)
{
return a - b;
}
}
public class C : IGetResult
{
public int GetResult( int a, int b)
{
return a * b;
}
}
public class D : IGetResult
{
public int GetResult( int a, int b)
{
return a / b;
}
}
四則變五則:
NOoK
0:
11:
51
我現在要加一個業務
NOoK 0: 12: 00
邏輯是 (a + b) * a
NOoK 0: 12: 07
怎么辦
我現在要加一個業務
NOoK 0: 12: 00
邏輯是 (a + b) * a
NOoK 0: 12: 07
怎么辦
只是加一個類和修改switch,代碼過去如下:

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace ABCD
{
class Program
{
static void Main( string[] args)
{
while ( true)
{
Console.Read();
int result = GetResult( 12, 4);
Console.WriteLine(result);
}
}
static int GetResult( int a, int b)
{
IGetResult iResult = null;
switch (GetConfig())
{
case " + ":
iResult = new A();
break;
case " - ":
iResult = new B();
break;
case " * ":
iResult = new C();
break;
case " / ":
iResult = new D();
break;
case " +* ":
iResult = new E();
break;
}
return iResult.GetResult(a, b);
}
static string GetConfig()
{
string config = AppDomain.CurrentDomain.BaseDirectory + " config.ini ";
return File.ReadAllText(config);
}
}
public interface IGetResult
{
int GetResult( int a, int b);
}
public class A : IGetResult
{
public int GetResult( int a, int b)
{
return a + b;
}
}
public class B : IGetResult
{
public int GetResult( int a, int b)
{
return a - b;
}
}
public class C : IGetResult
{
public int GetResult( int a, int b)
{
return a * b;
}
}
public class D : IGetResult
{
public int GetResult( int a, int b)
{
return a / b;
}
}
public class E : IGetResult
{
public int GetResult( int a, int b)
{
return (a + b) * a;
}
}
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace ABCD
{
class Program
{
static void Main( string[] args)
{
while ( true)
{
Console.Read();
int result = GetResult( 12, 4);
Console.WriteLine(result);
}
}
static int GetResult( int a, int b)
{
IGetResult iResult = null;
switch (GetConfig())
{
case " + ":
iResult = new A();
break;
case " - ":
iResult = new B();
break;
case " * ":
iResult = new C();
break;
case " / ":
iResult = new D();
break;
case " +* ":
iResult = new E();
break;
}
return iResult.GetResult(a, b);
}
static string GetConfig()
{
string config = AppDomain.CurrentDomain.BaseDirectory + " config.ini ";
return File.ReadAllText(config);
}
}
public interface IGetResult
{
int GetResult( int a, int b);
}
public class A : IGetResult
{
public int GetResult( int a, int b)
{
return a + b;
}
}
public class B : IGetResult
{
public int GetResult( int a, int b)
{
return a - b;
}
}
public class C : IGetResult
{
public int GetResult( int a, int b)
{
return a * b;
}
}
public class D : IGetResult
{
public int GetResult( int a, int b)
{
return a / b;
}
}
public class E : IGetResult
{
public int GetResult( int a, int b)
{
return (a + b) * a;
}
}
最后的需求,消滅switch
NOoK
0:
15:
31
NOoK 0: 15: 37
這里能寫一個字典嗎
NOoK 0: 15: 46
這不就是鍵值對嗎

NOoK 0: 15: 37
這里能寫一個字典嗎
NOoK 0: 15: 46
這不就是鍵值對嗎
OK,我給出了最終代碼:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace ABCD
{
class Program
{
static void Main( string[] args)
{
while ( true)
{
Console.Read();
int result = GetResult( 12, 4);
Console.WriteLine(result);
}
}
static int GetResult( int a, int b)
{
IGetResult iResult = null;
string key = GetConfig();
iResult = ResultRegList.ResultList[key];
return iResult.GetResult(a, b);
}
static string GetConfig()
{
string config = AppDomain.CurrentDomain.BaseDirectory + " config.ini ";
return File.ReadAllText(config);
}
}
public interface IGetResult
{
int GetResult( int a, int b);
}
public class A : IGetResult
{
public int GetResult( int a, int b)
{
return a + b;
}
}
public class B : IGetResult
{
public int GetResult( int a, int b)
{
return a - b;
}
}
public class C : IGetResult
{
public int GetResult( int a, int b)
{
return a * b;
}
}
public class D : IGetResult
{
public int GetResult( int a, int b)
{
return a / b;
}
}
public class E : IGetResult
{
public int GetResult( int a, int b)
{
return (a + b) * a;
}
}
public class ResultRegList
{
static Dictionary< string, IGetResult> resultList = new Dictionary< string, IGetResult>( 5);
public static Dictionary< string, IGetResult> ResultList
{
get
{
if (resultList.Count == 0)
{
resultList.Add( " + ", new A());
resultList.Add( " - ", new B());
resultList.Add( " * ", new C());
resultList.Add( " / ", new D());
resultList.Add( " +* ", new E());
}
return resultList;
}
}
}
}
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace ABCD
{
class Program
{
static void Main( string[] args)
{
while ( true)
{
Console.Read();
int result = GetResult( 12, 4);
Console.WriteLine(result);
}
}
static int GetResult( int a, int b)
{
IGetResult iResult = null;
string key = GetConfig();
iResult = ResultRegList.ResultList[key];
return iResult.GetResult(a, b);
}
static string GetConfig()
{
string config = AppDomain.CurrentDomain.BaseDirectory + " config.ini ";
return File.ReadAllText(config);
}
}
public interface IGetResult
{
int GetResult( int a, int b);
}
public class A : IGetResult
{
public int GetResult( int a, int b)
{
return a + b;
}
}
public class B : IGetResult
{
public int GetResult( int a, int b)
{
return a - b;
}
}
public class C : IGetResult
{
public int GetResult( int a, int b)
{
return a * b;
}
}
public class D : IGetResult
{
public int GetResult( int a, int b)
{
return a / b;
}
}
public class E : IGetResult
{
public int GetResult( int a, int b)
{
return (a + b) * a;
}
}
public class ResultRegList
{
static Dictionary< string, IGetResult> resultList = new Dictionary< string, IGetResult>( 5);
public static Dictionary< string, IGetResult> ResultList
{
get
{
if (resultList.Count == 0)
{
resultList.Add( " + ", new A());
resultList.Add( " - ", new B());
resultList.Add( " * ", new C());
resultList.Add( " / ", new D());
resultList.Add( " +* ", new E());
}
return resultList;
}
}
}
}
接下來就是終結理論了:
NOoK
0:
23:
45
這就是了
路過秋天 0: 24: 22
這東西寫了很多,不過沒感覺ioc的存在
NOoK 0: 24: 23
如果以后再添加邏輯,只要寫一個IGetResult接口的實現類,再配置到字典里面,就可以了
NOoK 0: 24: 34
那個字典,其實就是ioc的雛形
NOoK 0: 24: 44
IOC說到底,就是這樣的一個字典
NOoK 0: 25: 03
通過一個條件,找到所需的實現類
NOoK 0: 25: 09
然后用到邏輯上
NOoK 0: 25: 12
就好了
NOoK 0: 25: 27
再改進,就是用IOC替換你那個字典了
這就是了
路過秋天 0: 24: 22
這東西寫了很多,不過沒感覺ioc的存在
NOoK 0: 24: 23
如果以后再添加邏輯,只要寫一個IGetResult接口的實現類,再配置到字典里面,就可以了
NOoK 0: 24: 34
那個字典,其實就是ioc的雛形
NOoK 0: 24: 44
IOC說到底,就是這樣的一個字典
NOoK 0: 25: 03
通過一個條件,找到所需的實現類
NOoK 0: 25: 09
然后用到邏輯上
NOoK 0: 25: 12
就好了
NOoK 0: 25: 27
再改進,就是用IOC替換你那個字典了
路過秋天 0:25:32
通過一個條件,找到所需要的實現類,看似更像反射
NOoK 0:25:40
這是反射嗎?
NOoK 0:26:09
你看到了嗎?
路過秋天 0:26:11
你看我的代碼,如果增加一個類,ResultRegList這里還需要再注冊
NOoK 0:26:18
是的
NOoK 0:26:37
字典是需要你手工改代碼的
路過秋天 0:26:38
只有變更為反射,可以解決
NOoK 0:26:49
IOC就是配置一下就可以了
NOoK 0:26:54
不需要改代碼了
NOoK 0:27:33
每種IOC都不一樣,最簡單的就是你寫的這種字典
NOoK 0:27:38
然后加上反射
NOoK 0:27:42
這容易理解
NOoK 0:27:55
但是能用到生產上的IOC容器
NOoK 0:28:03
都做了很多工作的
路過秋天 0:28:15
什么工作呢?
NOoK 0:28:29
比如你可以集成AOP
NOoK 0:28:47
添加一些創建前、創建后的事件
大體上話就擰到這了,后面也沒多擰幾句,到了洗洗睡了的時間。
再回頭看這段話,理解了,IOC原來是這樣子的:
可以把IoC模式看做是工廠模式的升華,可以把IoC看作是一個大工廠,只不過這個大工廠里要生成的對象都是在XML文件中給出定義的,然后利用Java 的“反射”編程,根據XML中給出的類名生成相應的對象。從實現來看,IoC是把以前在工廠方法里寫死的對象生成代碼,改變為由XML文件來定義,也就是把工廠和對象生成這兩者獨立分隔開來,目的就是提高靈活性和可維護性。
接下來理解“依賴注入、控制反轉”八個字:
依賴注入:
首先Program里的switch本來是調用new A()這個對象,經過演進后,變成調用IGetResult接口了。
所以Program本來是依賴new A()對象,結果被IGetResult接口給插了菊花。
最終就是Program只調用IGetResult接口,Programe和new A()沒有直接依賴關系。
這就是依賴注入的解釋了。
所以Program本來是依賴new A()對象,結果被IGetResult接口給插了菊花。
最終就是Program只調用IGetResult接口,Programe和new A()沒有直接依賴關系。
這就是依賴注入的解釋了。
控制反轉:
正常說的,
new A()對象,是由Program寫死在代碼里的了,相當於控制權是在Program里。
代碼演進之后,對象的產生的控制權轉移到配置文件里。
這就是控制(權)反轉的解釋了。
代碼演進之后,對象的產生的控制權轉移到配置文件里。
這就是控制(權)反轉的解釋了。
文章有點長,不知道你理解了沒。