Monday, January 2, 2017

控制反转---依赖注入和Service Locator pattern


控制反转(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