Individual study notes, from Acode.
1. Terminology
Control inversion/Reverse control, English full name "inversion of Control", referred to as IOC.
Dependency Injection, English full name "Dependency injection", referred to as DI.
It is said that Martin Fowler after a deep exploration of the principle of inversion of control, a new name called "Dependency Injection" for control inversion. In other words, the two terms are about the same thing.
2. The "secret" of control inversion
"Implementations must rely on abstraction, not abstract dependency implementations."
3. Example understanding
Only look at the control of the reversal of the secret, for the average person is still difficult to understand, like a kung fu master told us "No recruit wins a recruit", the quality of mediocre I still can not understand the words of the masters, so it is messy ...
Below, the actual procedure to understand the inversion of control.
Suppose scenario: Get data from a SQL Server database.
"Common Method"
The average person would write the program like this:
First, implement a class sqlserverdatabase for various operations on the database:
1 /*2 *sqlserverdatabase.java3 **/4 5 Public classSqlserverdatabase {6 7 /*8 * Statements corresponding to constructors, database connections, and other operations9 */Ten One //getting data from a SQL Server database A PublicList Getdatafromsqlserver () { - //get the specific statement of the data - } the}
You can then get the data you want at the business layer through an instance of the object:
1 /*2 *business.java3 **/4 5 Public classbusiness{6 PrivateSqlserverdatabase db =Newsqlserverdatabase ();7 8 //getting data from a SQL Server database9 Public voidGetData () {TenList List =db.getdatafromsqlserver (); One } A -}
In such a look, the sense of code is very good, ah, perfect to meet the needs. However, one day, decided to change the database to MySQL, so we have to go through the arduous writing of two programs are not available, we need to rewrite the following code:
/**mysqldatabase.java**/ Public classMysqldatabase {/** Statements corresponding to constructors, database connections, and other operations*/ //getting data from the MySQL database PublicList Getdatafrommysql () {//get the specific statement of the data }}/**business.java**/ Public classbusiness{PrivateMysqldatabase db =Newmysqldatabase (); //getting data from the MySQL database Public voidGetData () {List List=Db.getdatafrommysql (); }}
We struggled to write the two files on the other. At this point, the customer also decided to use Oracle as Data!!! At this point, it is estimated that your heart is extremely collapsed. For Grandpa Mao, we endured, and again wrote a new program.
When the Oracle database program was written, the customer said to use MongoDB as a database!!! At this point, feel no longer be a programmer.
Summarize:
As you can see from the above example, once the customer's business needs change, the code we write is basically useless, and the new code is rewritten. What is this for? The reason: The business class is used in the specific database corresponding to the class, once the database to be used changes, business code will have to follow the change AH (getdatafromsqlserver () Getdatafrommysql ()-> )。
Lesson:
To implement a kind of code can be reused multiple times, do not rely on the specific business of the code, to achieve the re-use. At this point, we think of what the great God tells us that the "realization of the inversion of control must depend on abstraction, not abstract dependency implementation."
"IOC Way to achieve"
1, first, define a database to obtain data from the interface, as an interface, it is only the declaration of methods, here we need a method to obtain data from the database: GetData ().
1 /* 2 *database.java 3 */ 4 5 Public Interface database{ 6 // This method is used to obtain data 7 Public void GetData (); 8 }
2. Next, when the customer requests SQL Server as the database for the project, implement a class sqlserverdatabase that takes the data from the SQL Server database:
1 /*2 *sqlserverdatabase.java3 */4 5 Public classSqlserverdatabaseImplementsdatabase{6 //This method is used to obtain data7 Public voidGetData () {8 //Here is the code that takes the data from the SQL Server database specifically9 ......Ten } One}
This class specifically implements the process of getting data from a SQL Server database.
3, at this time, the business needs to obtain data from the database, to achieve business-class businesses (note that the type of writing, it is important):
1 /*2 *business.java3 */4 5 Public classBusiness {6 //defining variables for interface database7 PrivateDataBase db;8 9 Public voidsetdatabase (DataBase db) {Ten This. db=db; One } A - //get data from the XXX database based on the injected database class - Public voidGetData () { the Db.getdata (); - } -}
Note the place:
(1) In line 7th, a variable db that defines an interface for manipulating the database is not a variable that depends on the implementation of the specific class;
(2) The Setdatabase () method is defined, which realizes the injection of the variables of the database Operation class.
(3) GetData () method or fetch data based on the actual injected database type.
Summarize:
It can be seen that the implementation of this method relies on abstraction rather than on concrete implementations, and whether the ultimate "realization of the IOC" must rely on abstraction rather than abstract dependency implementation.
4, through the business class in 3, the implementation of the Code reuse (personal feeling, that is, the operational layer has also implemented a "compatibility of a strong package", so that the code to achieve the reuse), the following look at how to implement the database according to the specific type of database data:
1 /*2 *testbusiness.java3 */4 5 Public classtestbusiness {6 PrivateBusiness Business =NewBusiness ();7 8 //get data from a SQL Server database based on the injected database class9 Public voidGetData () {TenBusiness.setdatabase (Newsqlserverdatabase ()); One Business.getdata (); A } -}
In line 10th, we inject the variables of the SQL Server class into business classes, and we implement the operation of fetching data from the SQL Server database. At this point, we are no longer afraid of customers to replace the database.
Assuming that the customer wants to use MySQL as the database, then we need to do only two points:
(1) Implementation of MySQL-based fetch data class Mysqldatabase
1 /*2 *mysqldatabase.java3 */4 5 Public classMysqldatabaseImplementsdatabase{6 //This method is used to obtain data7 Public voidGetData () {8 //Here is the code that takes the data from the MySQL database in detail9 ......Ten } One}
(2) Changing the type of database injected
1 /*2 *testbusiness.java3 */4 5 Public classtestbusiness {6 PrivateBusiness Business =NewBusiness ();7 8 //get data from the MySQL database based on the injected database class9 Public voidGetData () {TenBusiness.setdatabase (Newmysqldatabase ()); One Business.getdata (); A } -}
We just need to change the database type of the Chinese herbal medicine injected in line 10th, and do all the work.
At this point, once again understand the IOC's ultimate secret: the implementation must rely on abstraction, not an abstract dependency implementation. (The realm of cultivation has been upgraded to another level.)
Reprint Please specify source: http://www.cnblogs.com/acode/p/5356686.html
Control inversion (IOC)/Dependency Injection (DI) understanding