IoC反转控制,
举个反例:
//数据操作类
public class DataBase
{
//向数据库中存储数据
public void saveDB()
{
}
}
//业务逻辑类
public class Business
{
//定义数据接口
private DataBase db = new DataBase();
//数据保存
public void saveData()
{
//do something else
//保存数据
db.saveDB();
}
}
//现在修改为向XML文件保存
public class XMLData
{
//向xml中保存数据
public void saveXML()
{
}
}
//这个时候需要重新修改业务逻辑业务逻辑
public class Business
{
private XMLData xml = new XMLData();
//数据保存
public void saveData()
{
//do something esle
//保存数据
xml.saveXML();
}
}
可以看到 这种方法的不方便之处在于更改存储方式的时候,就需要更新全部的逻辑与方法
//定义一个接口
public interface SaveData()
{
public void saveData();
}
//数据操作类
public class DataBase implements SaveData
{
//向数据库中存储数据,实现接口的存储接口
public void saveData()
{
//具体的向数据库中存入数据的逻辑
}
}
//业务逻辑类
public class Business
{
//定义数据接口
private SaveData db;
//定义数据保存类,这里传入的参数实际上是接口的子类,用*接口接收
public void setSaveData(SaveData db)
{
//通过向上转型
this.db = db;
}
public void saveData()
{
//do something
this.db.saveData();
}
}
//测试类
public class TestBusiness
{
private Business b = new Business();
public void saveData()
{
.....
b.setSaveData(new DataBase());
}
}
现在的好处就是使Business成为一个工厂,调用者无需关心底部存储的细节,只需要将存储方法设定到business,然后调用保存即可,而且这样一来
扩展也变得容易了,首先编写xml存储方法(继承savedata接口,并且实现存储方法),然后business无需更改,在业务逻辑传递进去xml存储对象即可.
可以看到,这样实现使得代码得到重用,而且增强了扩展性.
依赖注入:原本的方式是业务逻辑控制具体的存储方式,但是面向接口了以后,就不再业务逻辑里面编写具体的存储方式了,而是在调用业务逻辑的类里控制具体的存储方式,也就是上面的,由testbusiness调用业务逻辑的时候,控制了存储方式(原本是业务逻辑设定好存储方式然后供调用),看起来是由具体的存储方式控制了业务逻辑.
注入方式:
1.set注入,也就是在business中定义一个私有的存储接口变量,然后定义set方法,注入具体的存储方式.
2.接口注入,具体存储方式与存储接口还是一样,但是在业务逻辑中定义的是业务逻辑接口,然后在这个接口中定义了需要注入的信息(比如定义一个Disavedata(SaveData db)),然后每个业务逻辑都需要去继承这个接口,然后实现这个存储方法,在原本的set方法上,相当于保证了每个业务逻辑都有一个默认的注入方法(可以覆写).
3,构造注入,跟set方法相比 只是把注入的逻辑放到了business的构造方法里面.
可以看到,无论是采用哪种方法,都需要使用面向接口编程