控制反转(Inversion of Control, IoC)
public class Client {private Service service;
Client() {
service = new ServiceExample();
}
}
Client中用到了Service的对象service,代码中显式的new一个Service的对象。采用依赖注入技术之后,Client的代码不需要直接new来获得这个对象,而是通过相关的容器控制程序来将Service对象在外部new出来并注入到Client类里的引用中。而Service对象被获取时的状态由配置文件(如XML)来指定。
Client(Service service) {
this.service = service;
}
通过控制反转,对象在被创建的时候,由一个调控系统将其所依赖的对象(Service)注入到目前对象(Client)中。这种依赖(如初始化Service需要加入参数)会被独立出来成XML或一个class从而提高代码可读性和减低计算机代码之间的耦合度(隔离)方便单元测试。当然,一些不利因素就是要学习Spring。
Dependency injection
依赖注入是IoC最常见的实现方式。DI支持composition pattern(就是把另一个类作为此类的一个成员变量)而不太支持继承。Construction Injection:
Client(Service service) {
this.service = service;
}
Setter Injection:
public void setService(Service service) {
this.service = service;
}
Interface Injection:
@Override
public void setService(Service service) {
this.service = service;
}
依赖注入代码实现:
Manually:
public class Injector {
public static void main(String[] args) {
Service service = new ServiceExample();
Client client = new Client(service);
System.out.println(client.greet());
}
}
XML:
public static void main(String[] args) {
BeanFactory beanfactory=new ClassPathXmlApplicationContext("Beans.xml");
Client client=(Client)beanfactory.getBean("client");
System.out.println(client.greet());
}
<beans>
<bean id="service" class="ServiceExample">
</bean>
<bean id="client" class="Client">
<constructor-arg value="service" />
</bean>
</beans>
Config.java:
public class Injector {
public static void main(String[] args) {
BeanFactory beanfactory = new AnnotationConfigApplicationContext(MyConfiguration.class);
Client client = beanfactory.getBean(Client.class);
System.out.println(client.greet());
}
}
@ComponentScan
static class MyConfiguration {
@Bean
public Client client(ServiceExample service) {
return new Client(service);
}
}
Service Locator pattern:
控制反转的另一种实现方式是Dependency lookup, 具体用Service Locator pattern来实现。此模式实质是工厂模式。
Locator提供各个接口如IServiceA, IServiceB, 以及一个_mapping的directory为接口和具体实现类做lookup,比如IServiceA->ServiceA。Locator还负责创建具体类的实例。
ServiceA:
interface IServiceA
{
string GetData();
}
class ServiceA : IServiceA
{
public string GetData()
{
return "This data is from ServiceA";
}
}
一个新的服务就要先注册,注册实质上把这个实例类型放入hash中可以创建实例
Main:
static void Main(string[] args)
{
//注册此类型
ServiceLocator.RegisterType<IServiceA, ServiceA>();
//创建此类型一个实例
IServiceA serviceA = ServiceLocator.Resolve<IServiceA>();
string data = serviceA.GetData();
Console.WriteLine(data);
Console.ReadKey();
}
No comments:
Post a Comment