控制反转容器& 依赖注入模式 ---读感。

几个web框架 : sprint Avalon PicoContainer
class MovieLister
MovieFinder finder = ServiceLocator.movieFinder();

//单件注册表 注册的时候 载入一个已经确定好属性的服务定位器
class ServiceLocator...
public static MovieFinder movieFinder(){
return soleInstance.movieFinder;
}
private static ServiceLocator soleInstance;
private MovieFinder movieFinder;

public static void load(ServiceLocator arg) {
soleInstance = arg;
}
public ServiceLocator(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}

//test code
class Tester
private void configure(){
//说明服务定位器是有构造函数可以在这个时候来决定实用的movieFinder的。
ServiceLocator.load(new ServiceLocator(new ColonMovieFinder("Movie1.txt")));
}

public void testSimple(){
configure();
MovieLister lister = new MovieLister();
Movie[] movies = lister.moviesDirectedBy("Sergio");
assertEquals("Once Upon a Time in the West", movies[0].getTitle());
}
//ServiceLocator 应该是一个静态的全局变量,如此lister 才能直接载入。
//更复杂的情况: 服务定位器派生子类,并且将子类传递给注册表类变量。???
// 暴露一个静态方法,而不是直接访问该类实例的变量。

//-------单件模式 -------------//以上设计的设计模式

//为定位器使用分离接口:
//由于list 可能只需要使用一个服务,可以使用角色接口(role interface)这样不用使用全部的服务接口,只需要声明需要使用的接口就行了。
public interface MovieFinderLocator{
public MovieFinder movieFinder();
}

class MovieLister
MovieFinderLocator locator = ServiceLocator.locator();
MoiveFinder finder = locator.movieFinder();

class ServiceLocator
public static ServiceLocator locator(){
return soleInstance;
}
public MovieFinder movieFinder() {
return movieFinder;
}
private static ServiceLocator soleInstance;
private MovieFinder movieFinder;
//这个时候,由于使用了接口,就无法使用静态变量了,需要使用locator() 来 获取一个实例

//动态服务定位器 上面两个例子是静态的,但是我们也可以使用动态服务定位器,允许在其中注册需要的服务,并且在运行时动态按需获取。
// 如下 服务定位器是使用map来保存服务信息,而非放到字段中。
class ServiceLocator
private static ServiceLocator soleInstance;
public static void load(ServiceLocator arg){
soleInstance = arg;
}

private Map services = new HashMap();
public static Object getService(String key){
return soleInstance.services.get(key);
}
public void loadService(String key, Object service){
service.put(key, service);

}

class Tester
private void configure(){
ServiceLocator locator = new ServiceLocator();
locator.loadService("MovieFinder", new ColonMovieFinder("movie1.txt"));
ServiceLocator.load(locator);
}
class MovieLister
MovieFinder finder = (MovieFinder) ServiceLocator.getService("MovieFinder");

//Locator 和 Injection 同时使用的案列:
public class MyMovieLister implements MovieLister, Serviceable {
private MovieFinder finder;

public void service(ServiceManager manager) throws ServiceException {
finder = (MovieFinder) manager.lookup("finder");
}
}
//容器将中ServiceManager对象注入到list 中,ServiceManager 是一个服务定位器的,使用它来查找finder实例

//-------服务定位器和依赖注入的对比
服务定位器比较直观,但是所有的请求者都会需要依赖服务定位器
如果需要提供一个组件出去,最好还是使用注入的方式,因为无法控制使用者会使用什么样的实现,可以直接使用注入来定义对应的实现。

//-------构造注入和属性注入比较
两者都比较容易配置,而接口注入的方式十分容易在各处代码中泛滥。
构造注入和属性注入就涉及了是否应该在构造的时候就对属性进行赋值。
构造注入可以将属性设置为不可变的,并且可以明确意图。
属性注入在参数太多的时候很有必要,同时有多个方法来构造一个有效对象时,就可以使用Factory Method的模式。
同时如果对象有很多的构造器,并且对象间存在继承关系,这可能会导致构造器膨胀,由于子类的构造器需要调用父类的构造器然后再处理自己的参数。
//----代码配置还是文件配置
对于多数多处部署的应用程序来说,使用配置文件的方式比较好,我想是因为方便查看的原因。配置文件也多为XML,不过我们之前的项目多用json文件进行配置。
如果配置文件变得复杂了 就需要考虑换一个适合的编程语言来实现。
其中提到的:如果一个配置的逻辑变得复杂了,应该使用适合的语言来描述配置信息 这里没有考虑到对应的情况,不过觉得之前的表数据的配置,是否也可以用语言来实习?而不是一直增加怕配置文件。是否是会更加明了。
有很多组件有各自的配置文件,需要维护不同的配置文件,这种情况可以通过统一的编程接口来提供,可以分开配置文件。通过这个接口,可以管理配置文件???? 只想到了可以统一配置文件来实现,但是这里所说的统一配置文件接口的情境没有想好。

//------将配置和应用分离
服务的配置和应用分离,之前的应用就是这样的,单独配置应用的配置文件的地方。
一个设计原则:分离接口和具体的实现。
比如数据源的使用,测试的时候 可能是直接读取文件配置来着,但是在生产环境的时候,是读取服务器上的数据源JNDI的配置。

重点是应该将 服务配置从应用程序内部分离出来。

参考:

http://www.cnblogs.com/me-sa/archive/2008/07/30/IocDI.html

http://www.martinfowler.com/articles/injection.html

时间: 2024-10-10 07:16:40

控制反转容器& 依赖注入模式 ---读感。的相关文章

控制反转和依赖注入模式(转)

Java社群近来掀起了一阵轻量级容器的热潮,这些容器能够帮助开发者将来自不同项目的组件组装成为一个内聚的应用程序.在它们的背后有着同一个模式,这个模式决定了这些容器进行组件装配的方式.人们用一个大而化之的名字来称呼这个模式:"控制反转"( Inversion of Control,IoC).在本文中,我将深入探索这个模式的工作原理,给它一个更能描述其特点的名字--"依赖注入"(Dependency Injection),并将其与"服务定位器"(S

Inversion of Control Containers and the Dependency Injection pattern(控制反转和依赖注入模式)

本文内容 Components and Services A Naive Example Inversion of Control Forms of Dependency Injection Constructor Injection with PicoContainer Setter Injection with Spring Interface Injection Using a Service Locator Using a Segregated Interface for the Loc

工厂模式、控制反转及依赖注入

在介绍工厂模式与控制反转(Inversion of Control)及依赖注入(Dependency Injection)之前,先介绍下类的调用方法.目前调用方法总共有3种:1.自己创建:2.工厂模式:3.外部注入,其中外部注入即为控制反转/依赖注入模式(IoC/DI).我们可以用3个形象的东西来分别表示它们,就是new.get.set.顾名思义,new表示自己创建,get表示主动去取(即工厂),set表示是被别人送进来的(即注入),其中get和set分别表示了主动去取和等待送来两种截然相反的特

spring的容器(控制反转、依赖注入)

一.spring的容器 ”容器“是spring的一个重要概念,其主要作用是完成创建成员变量,并完成装配. 而容器的特点”控制反转“和”依赖注入“是两个相辅相成的概念. 控制反转:我们在使用一个类型的实例实现某个功能时,需要先new出该类型的一个实例,并赋值给我们声明的某个引用变量,这样我们才能够使用该变量进行操作.而new和赋值本事我们自己的权限,此处便是将该控制权限反转交给了spring. 依赖注入:某个类型要完成一个功能往往需要其他类型的变量来完成,我们在程序中往往通过自己new的方式来完成

spring(3)------控制反转(IOC)/依赖注入(DI)

一,spring核心概念理解 控制反转: 控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理. 所谓的"控制反转"概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器. 没有控制反转这种模式前,你创建一个对象,在什么地方用,你得单独通过关键字new出来用, 但现在可以不用这样,你把new对象的权利交给spring配置文件,通过配置文件来'new', 就是权利的反转,你以前干的事

控制反转和依赖注入(转)

1.控制反转(Inversion of Control)与依赖注入(Dependency Injection) 控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理.所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器. IoC是一个很大的概念,可以用不同的方式来实现.其主要实现方式有两种:<1>依赖查找(Dependency Lookup):容器提供回调接口和上下文环

Spring 基础 控制反转和依赖注入

Spring框架两个最重要的知识点 1.IOC(控制反转)/DI(依赖注入):把整个项目中的所有对象交给Spring容器管理 IOC:取到对象 DI:对象的装配 依赖注入有两种方式: 1.      属性值注入方式 a.     普通类型 注入方式 b.bean注入方式 测试结果 在使用普通类型方式注入的时候,我们会有一些特殊字符,处理这种特殊字符时 我们会想使特殊字符保持原有的样子,这时候就要使用CDATA,就如上一张图片所示 2.构造参数注值方式 在一般情况,一个类会有一个默认的无参构造函数

控制反转与依赖注入

关于控制反转和依赖注入的文章和书籍很多,对其定义也解释的也仁者见仁,这里就不赘述了,这是本人(只代表个人观点)理解之后用通俗的例子和平淡的话词为您解释,希望对您有所帮助: 控制反转(IoC/Inverse Of Control):   调用者不再创建被调用者的实例,由spring框架实现(容器创建)所以称为控制反转. 依赖注入(DI/Dependence injection) :   容器创建好实例后再注入调用者称为依赖注入. 当 某个角色(可能是一个Java实例,调用者)需要另一个角色(另一个

Spring框架之控制反转和依赖注入

学Spring框架必须理解控制反转和依赖注入.下面各自举一个例子,来说明. IOC(控制反转):应用本身创建和维护的依赖对象:现在交由外部容器(Spring)来创建和维护:这个控制权的转移: 就叫做控制反转. 第一步:配置applicationContextcreateproject.xml和applicationcontext.xml(总体) <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=