﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-Rukas - Oh, My Blog!-随笔分类-设计模式</title><link>http://www.cnitblog.com/rukas/category/1378.html</link><description /><language>zh-cn</language><lastBuildDate>Sat, 08 Oct 2011 12:55:10 GMT</lastBuildDate><pubDate>Sat, 08 Oct 2011 12:55:10 GMT</pubDate><ttl>60</ttl><item><title>Thinking in Patterns with Java (Bruce Eckel)</title><link>http://www.cnitblog.com/rukas/archive/2005/11/22/4817.html</link><dc:creator>Rukas - Oh, My Blog!</dc:creator><author>Rukas - Oh, My Blog!</author><pubDate>Tue, 22 Nov 2005 09:14:00 GMT</pubDate><guid>http://www.cnitblog.com/rukas/archive/2005/11/22/4817.html</guid><wfw:comment>http://www.cnitblog.com/rukas/comments/4817.html</wfw:comment><comments>http://www.cnitblog.com/rukas/archive/2005/11/22/4817.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/rukas/comments/commentRss/4817.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/rukas/services/trackbacks/4817.html</trackback:ping><description><![CDATA[<A href="http://www.jdon.com/designpatterns/TIPatterns/html/Index.html">http://www.jdon.com/designpatterns/TIPatterns/html/Index.html</A><img src ="http://www.cnitblog.com/rukas/aggbug/4817.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/rukas/" target="_blank">Rukas - Oh, My Blog!</a> 2005-11-22 17:14 <a href="http://www.cnitblog.com/rukas/archive/2005/11/22/4817.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>板桥里人讲 GoF 的 23 种设计模式</title><link>http://www.cnitblog.com/rukas/archive/2005/11/22/4816.html</link><dc:creator>Rukas - Oh, My Blog!</dc:creator><author>Rukas - Oh, My Blog!</author><pubDate>Tue, 22 Nov 2005 08:40:00 GMT</pubDate><guid>http://www.cnitblog.com/rukas/archive/2005/11/22/4816.html</guid><wfw:comment>http://www.cnitblog.com/rukas/comments/4816.html</wfw:comment><comments>http://www.cnitblog.com/rukas/archive/2005/11/22/4816.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/rukas/comments/commentRss/4816.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/rukas/services/trackbacks/4816.html</trackback:ping><description><![CDATA[<A href="http://www.jdon.com/designpatterns/">http://www.jdon.com/designpatterns/</A><BR><BR>
<H3 align=center>设计模式(Patterns in Java)</H3><BR>　　板桥里人的设计模式讲解是国内媒体（包括书籍和网站）中最早的成体系介绍，本系列介绍纯为免费传播(转载本站文章，请保留作者和网址)，尽量做到言简意赅，通俗易懂，但是难免有所疏漏敬请来信或论坛讨论，不断完善。 
<P></P>
<P>　　真正掌握设计模式需要在实践中不断研究和使用，关于设计模式在具体实例的应用，可以阅读板桥里人的书籍《<A href="http://www.jdon.com/mybook/index.htm">Java实用系统开发指南</A>》。书籍中8个实例都从设计模式、框架等高度对系统进行崭新的设计和实现，这种应用理念正是现在以及将来软件设计和编程的根本之道。 
<TABLE cellSpacing=5 cellPadding=5 width="100%" border=0>
<TBODY>
<TR>
<TD>
<TABLE cellSpacing=3 cellPadding=3 width="90%" border=0>
<TBODY>
<TR>
<TD bgColor=#8ca5b7><FONT color=#ffffff><B>1:前言</B></FONT></TD></TR>
<TR>
<TD>
<P><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9> <A href="http://www.jdon.com/designpatterns/patternsimportant.htm">学习GoF设计模式的重要性</A> </P>
<P><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9 border=0> <A href="http://www.jdon.com/designpatterns/architecture.htm">建筑和软件中模式之异同</A> </P></TD></TR></TBODY></TABLE></TD></TR>
<TR>
<TD>
<TABLE cellSpacing=3 cellPadding=3 width="90%" border=0>
<TBODY>
<TR>
<TD bgColor=#8ca5b7><FONT color=#ffffff><B>2:GoF设计模式</B></FONT></TD></TR>
<TR>
<TD>A.<B>创建模式</B> 
<TABLE cellSpacing=3 cellPadding=3 width="95%" align=center border=0>
<TBODY>
<TR>
<TD bgColor=#fbfce9>
<P><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9> <A href="http://www.javaolympus.com/java/JavaDesignDirectory.html" target=_blank></A><A href="http://www.jdon.com/designpatterns/designpattern_factory.htm">设计模式之Factory(工厂模式)<BR></A>使用工厂模式就象使用new一样频繁.<FONT color=#ff0000>2002/10/9更新</FONT></P></TD></TR>
<TR>
<TD bgColor=#ffffff><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9> <A href="http://www.jdon.com/designpatterns/prototype.htm">设计模式之Prototype(原型模式)</A><BR>用原型实例指定创建对象的种类，并且通过拷贝这些原型创建新的对象。</TD></TR>
<TR>
<TD bgColor=#fbfce9><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9> <A href="http://www.jdon.com/designpatterns/builder.htm">设计模式之Builder</A><BR>汽车由车轮 方向盘 发动机很多部件组成，同时，将这些部件组装成汽车也是一件复杂的工作，Builder模式就是将这两种情况分开进行。</TD></TR>
<TR>
<TD bgColor=#ffffff><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9> <A href="http://www.jdon.com/designpatterns/singleton.htm">设计模式之Singleton(单态模式)</A><BR>保证一个类只有一个实例,并提供一个访问它的全局访问点 <FONT color=#ff0000>2002/10/9更新</FONT></TD></TR></TBODY></TABLE><BR><B>B.结构模式</B> 
<TABLE cellSpacing=3 cellPadding=3 width="95%" align=center border=0>
<TBODY>
<TR>
<TD bgColor=#fbfce9>
<P><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9> <A href="http://www.jdon.com/designpatterns/designpattern_Facade.htm">设计模式之Facade</A><BR>可扩展的使用JDBC针对不同的数据库编程,Facade提供了一种灵活的实现.</P></TD></TR>
<TR>
<TD bgColor=#ffffff>
<P><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9> <A href="http://www.jdon.com/designpatterns/designpattern_proxy.htm">设计模式之Proxy</A><BR>以Jive为例,剖析代理模式在用户级别授权机制上的应用</P></TD></TR>
<TR bgColor=#fbfce9>
<TD bgColor=#fbfce9>
<P><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9> <A href="http://www.jdon.com/designpatterns/adapter.htm">设计模式之Adapter</A><BR>使用类再生的两个方式:组合(new)和继承(extends),这个已经在"thinking in java"中提到过.</P></TD></TR>
<TR>
<TD bgColor=#ffffff><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9> <A href="http://www.jdon.com/designpatterns/composite.htm">设计模式之Composite</A><BR>就是将类用树形结构组合成一个单位.你向别人介绍你是某单位，你是单位中的一个元素，别人和你做买卖，相当于和单位做买卖。文章中还对Jive再进行了剖析。</TD></TR>
<TR bgColor=#fbfce9>
<TD bgColor=#fbfce9><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9> <A href="http://www.jdon.com/designpatterns/decorator.htm">设计模式之Decorator</A><BR>Decorator是个油漆工,给你的东东的外表刷上美丽的颜色.</TD></TR>
<TR>
<TD bgColor=#ffffff><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9> <A href="http://www.jdon.com/designpatterns/bridge.htm">设计模式之Bridge</A><BR>将"牛郎织女"分开(本应在一起,分开他们,形成两个接口),在他们之间搭建一个桥(动态的结合)</TD></TR>
<TR bgColor=#fbfce9>
<TD bgColor=#fbfce9><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9> <A href="http://www.jdon.com/designpatterns/flyweight.htm">设计模式之Flyweight</A><BR>提供Java运行性能,降低小而大量重复的类的开销.</TD></TR></TBODY></TABLE><BR><B>C.行为模式</B> 
<TABLE cellSpacing=3 cellPadding=5 width="95%" align=center border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9> <A href="http://www.jdon.com/designpatterns/template.htm">设计模式之Template</A><BR>实际上向你介绍了为什么要使用Java 抽象类,该模式原理简单,使用很普遍.</TD></TR>
<TR>
<TD bgColor=#fbfce9><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9> <A href="http://www.jdon.com/designpatterns/memento.htm">设计模式之Memento</A><BR>很简单一个模式,就是在内存中保留原来数据的拷贝. </TD></TR>
<TR>
<TD bgColor=#ffffff><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9> <A href="http://www.jdon.com/designpatterns/observer.htm">设计模式之Observer<BR></A>介绍如何使用Java API提供的现成Observer</TD></TR>
<TR>
<TD bgColor=#fbfce9><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9> <A href="http://www.jdon.com/designpatterns/cor.htm">设计模式之Chain of Responsibility</A><BR>各司其职的类串成一串,好象击鼓传花,当然如果自己能完成,就不要推委给下一个.</TD></TR>
<TR>
<TD bgColor=#ffffff><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9> <A href="http://www.jdon.com/designpatterns/command.htm">设计模式之Command</A><BR>什么是将行为封装,Command是最好的说明.</TD></TR>
<TR>
<TD bgColor=#fbfce9><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9> <A href="http://www.jdon.com/designpatterns/designpattern_State.htm">设计模式之State<BR></A>状态是编程中经常碰到的实例,将状态对象化,设立状态变换器,便可在状态中轻松切换.</TD></TR>
<TR>
<TD bgColor=#ffffff><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9> <A href="http://www.jdon.com/designpatterns/designpattern_Strategy.htm">设计模式之Strategy</A><BR>不同算法各自封装,用户端可随意挑选需要的算法.</TD></TR>
<TR>
<TD bgColor=#fbfce9><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9> <A href="http://www.jdon.com/designpatterns/mediator.htm">设计模式之Mediator</A><BR>Mediator很象十字路口的红绿灯,每个车辆只需和红绿灯交互就可以.</TD></TR>
<TR>
<TD bgColor=#ffffff><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9> <A href="http://www.jdon.com/designpatterns/interpreter.htm">设计模式之Interpreter</A><BR>主要用来对语言的分析,应用机会不多.</TD></TR>
<TR>
<TD bgColor=#fbfce9><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9> <A href="http://www.jdon.com/designpatterns/visitor.htm">设计模式之Visitor</A><BR>访问者在进行访问时,完成一系列实质性操作,而且还可以扩展.</TD></TR>
<TR>
<TD bgColor=#ffffff><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9> 设计模式之Iterator<BR>这个模式已经被整合入Java的Collection.在大多数场合下无需自己制造一个Iterator,只要将对象装入Collection中，直接使用Iterator进行对象遍历。</TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></TD></TR>
<TR>
<TD>
<TABLE cellSpacing=3 cellPadding=3 width="90%" border=0>
<TBODY>
<TR>
<TD bgColor=#8ca5b7><FONT color=#ffffff><B>3:英文资料</B></FONT></TD></TR>
<TR>
<TD>
<TABLE cellSpacing=3 cellPadding=3 width="100%" border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff>
<P><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9> <A href="http://www.jdon.com/designpatterns/TIPatterns/html/Index.html">Thinking in Patterns with Java</A> Thinking in Java的作者<A href="http://www.mindview.net/" target=_blank>Eckel</A>又一著作!</P>
<P><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9> <A href="http://www.research.umbc.edu/%7Etarr/dp/fall00/cs491.html">CMSC491D Design Patterns In Java </A><BR><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9> <A href="http://www.mindspring.com/%7Emgrand/pattern_synopses.htm" target=_blank>Overview of Design Patterns</A> 精确定义各个模式以及他们的关系<BR><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9> <A href="http://www.patterndepot.com/put/8/JavaPatterns.htm" target=_blank>Design Patterns Java Companion</A> </P></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=3 cellPadding=3 width="90%" border=0>
<TBODY>
<TR>
<TD bgColor=#8ca5b7><FONT color=#ffffff><B>4:J2EE设计模式</B></FONT></TD></TR>
<TR>
<TD>
<TABLE cellSpacing=3 cellPadding=3 width="100%" border=0>
<TBODY>
<TR>
<TD bgColor=#ffffff>
<P><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9> <A href="http://www.jdon.com/designpatterns/ejb.htm">设计模式在EJB中应用</A> 这是板桥里人banq发表在《程序员》第6期的文章。<BR><IMG height=9 src="http://www.jdon.com/images/top.gif" width=9> <A href="http://www.jdon.com/books/ejbdesignpatterns.pdf">EJB设计模式(英文)</A> 从设计模式去理解EJB或J2EE我认为是个非常有效的办法. </P></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>
<UL>
<LI>感谢台湾「<A href="http://www.dotspace.idv.tw/" target=_blank>点空间</A>」将本站设计模式文章翻译成<A href="http://www.dotspace.idv.tw/Patterns.htm" target=_blank>繁体字并转载</A> 
<LI>感谢网友David Yu将本站设计模式制作成PDF文件，<A href="http://www.jdon.com/designpatterns/PatternsInJava.pdf">这里下载PDF文件</A></LI></UL><img src ="http://www.cnitblog.com/rukas/aggbug/4816.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/rukas/" target="_blank">Rukas - Oh, My Blog!</a> 2005-11-22 16:40 <a href="http://www.cnitblog.com/rukas/archive/2005/11/22/4816.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SUN - J2EE Patterns 链接</title><link>http://www.cnitblog.com/rukas/archive/2005/11/22/4804.html</link><dc:creator>Rukas - Oh, My Blog!</dc:creator><author>Rukas - Oh, My Blog!</author><pubDate>Tue, 22 Nov 2005 06:49:00 GMT</pubDate><guid>http://www.cnitblog.com/rukas/archive/2005/11/22/4804.html</guid><wfw:comment>http://www.cnitblog.com/rukas/comments/4804.html</wfw:comment><comments>http://www.cnitblog.com/rukas/archive/2005/11/22/4804.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/rukas/comments/commentRss/4804.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/rukas/services/trackbacks/4804.html</trackback:ping><description><![CDATA[<SPAN class=title>J2EE Patterns</SPAN> <A href="http://java.sun.com/blueprints/patterns/"><BR>http://java.sun.com/blueprints/patterns/</A><A href="http://java.sun.com/blueprints/corej2eepatterns/index.html"><BR><BR><FONT color=#000000>Welcome to Core J2EE Patterns!</FONT><BR>http://java.sun.com/blueprints/corej2eepatterns/index.html</A><BR><BR>Core J2EE Patterns: Patterns index page<BR><A href="http://java.sun.com/blueprints/corej2eepatterns/Patterns/index.html">http://java.sun.com/blueprints/corej2eepatterns/Patterns/index.html</A><BR><BR><img src ="http://www.cnitblog.com/rukas/aggbug/4804.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/rukas/" target="_blank">Rukas - Oh, My Blog!</a> 2005-11-22 14:49 <a href="http://www.cnitblog.com/rukas/archive/2005/11/22/4804.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Inversion of Control Containers and the Dependency Injection pattern</title><link>http://www.cnitblog.com/rukas/archive/2005/11/17/4638.html</link><dc:creator>Rukas - Oh, My Blog!</dc:creator><author>Rukas - Oh, My Blog!</author><pubDate>Thu, 17 Nov 2005 13:00:00 GMT</pubDate><guid>http://www.cnitblog.com/rukas/archive/2005/11/17/4638.html</guid><wfw:comment>http://www.cnitblog.com/rukas/comments/4638.html</wfw:comment><comments>http://www.cnitblog.com/rukas/archive/2005/11/17/4638.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/rukas/comments/commentRss/4638.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/rukas/services/trackbacks/4638.html</trackback:ping><description><![CDATA[<H1>Inversion of Control Containers and the Dependency Injection pattern</H1>
<DIV class=author>
<P><A href="http://martinfowler.com/">Martin Fowler</A></P></DIV>
<P class=abstract><I>In the Java community there's been a rush of lightweight containers that help to assemble components from different projects into a cohesive application. Underlying these containers is a common pattern to how they perform the wiring, a concept they refer under the very generic name of "Inversion of Control". In this article I dig into how this pattern works, under the more specific name of "Dependency Injection", and contrast it with the Service Locator alternative. The choice between them is less important than the principle of separating configuration from use.</I></P>
<P class=lastUpdate>Last significant update: <A href="http://www.martinfowler.com/articles/injection.html#SignificantRevisions">23 Jan 04</A></P>
<P class=translations>|&nbsp;<A href="http://gigix.blogdriver.com/diary/gigix/inc/DependencyInjection.pdf"><STRONG>中文版</STRONG></A> | <A href="http://www.javafree.com.br/home/modules.php?name=Content&amp;pa=showpage&amp;pid=4">Portuguese</A> | <A href="http://www.dotnetguru.org/article.php?sid=493&amp;mode=thread&amp;order=0&amp;thold=0">French</A> | </P>
<DIV class=contents>
<P>Contents</P>
<UL>
<LI><A href="http://www.martinfowler.com/articles/injection.html#ComponentsAndServices">Components and Services</A> 
<LI><A href="http://www.martinfowler.com/articles/injection.html#ANaiveExample">A Naive Example</A> 
<LI><A href="http://www.martinfowler.com/articles/injection.html#InversionOfControl">Inversion of Control</A> 
<LI><A href="http://www.martinfowler.com/articles/injection.html#FormsOfDependencyInjection">Forms of Dependency Injection</A> 
<UL>
<LI><A href="http://www.martinfowler.com/articles/injection.html#ConstructorInjectionWithPicocontainer">Constructor Injection with PicoContainer</A> 
<LI><A href="http://www.martinfowler.com/articles/injection.html#SetterInjectionWithSpring">Setter Injection with Spring</A> 
<LI><A href="http://www.martinfowler.com/articles/injection.html#InterfaceInjection">Interface Injection</A> </LI></UL>
<LI><A href="http://www.martinfowler.com/articles/injection.html#UsingAServiceLocator">Using a Service Locator</A> 
<UL>
<LI><A href="http://www.martinfowler.com/articles/injection.html#UsingASegregatedInterfaceForTheLocator">Using a Segregated Interface for the Locator</A> 
<LI><A href="http://www.martinfowler.com/articles/injection.html#ADynamicServiceLocator">A Dynamic Service Locator</A> 
<LI><A href="http://www.martinfowler.com/articles/injection.html#UsingBothALocatorAndInjectionWithAvalon">Using both a locator and injection with Avalon</A> </LI></UL>
<LI><A href="http://www.martinfowler.com/articles/injection.html#DecidingWhichOptionToUse">Deciding which option to use</A> 
<UL>
<LI><A href="http://www.martinfowler.com/articles/injection.html#ServiceLocatorVsDependencyInjection">Service Locator vs Dependency Injection</A> 
<LI><A href="http://www.martinfowler.com/articles/injection.html#ConstructorVersusSetterInjection">Constructor versus Setter Injection</A> 
<LI><A href="http://www.martinfowler.com/articles/injection.html#CodeOrConfigurationFiles">Code or configuration files</A> 
<LI><A href="http://www.martinfowler.com/articles/injection.html#SeparatingConfigurationFromUse">Separating Configuration from Use</A> </LI></UL>
<LI><A href="http://www.martinfowler.com/articles/injection.html#SomeFurtherIssues">Some further issues</A> 
<LI><A href="http://www.martinfowler.com/articles/injection.html#ConcludingThoughts">Concluding Thoughts</A> </LI></UL></DIV>
<DIV class=paperBody>
<HR class=bodySep>
</HR>
<P>One of the entertaining things about the enterprise Java world is the huge amount of activity in building alternatives to the mainstream J2EE technologies, much of it happening in open source. A lot of this is a reaction to the heavyweight complexity in the mainstream J2EE world, but much of it is also exploring alternatives and coming up with creative ideas. A common issue to deal with is how to wire together different elements: how do you fit together this web controller architecture with that database interface backing when they were built by different teams with little knowledge of each other.A number of frameworks have taken a stab at this problem, and several are branching out to provide a general capability to assemble components from different layers. These are often referred to as lightweight containers, examples include <A href="http://www.picocontainer.org/">PicoContainer</A>, and <A href="http://www.springframework.org/">Spring</A>.</P>
<P>Underlying these containers are a number of interesting design principles, things that go beyond both these specific containers and indeed the Java platform. Here I want to start exploring some of these principles. The examples I use are in Java, but like most of my writing the principles are equally applicable to other OO environments, particularly .NET.</P>
<HR class=topSection>
</HR><A name=ComponentsAndServices></A>
<H2>Components and Services</H2>
<P>The topic of wiring elements together drags me almost immediately into the knotty terminology problems that surround the terms service and component. You find long and contradictory articles on the definition of these things with ease. For my purposes here are my current uses of these overloaded terms.</P>
<P>I use component to mean a glob of software that's intended to be used, without change, by application that is out of the control of the writers of the component. By 'without change' I mean that the using application doesn't change the source code of the components, although they may alter the component's behavior by extending it in ways allowed by the component writers. </P>
<P>A service is similar to a component in that it's used by foreign applications. The main difference is that I expect a component to be used locally (think jar file, assembly, dll, or a source import). A service will be used remotely through some remote interface, either synchronous or asynchronous (eg web service, messaging system, RPC, or socket.)</P>
<P>I mostly use service in this article, but much of the same logic can be applied to local components too. Indeed often you need some kind of local component framework to easily access a remote service. But writing "component or service" is tiring to read and write, and services are much more fashionable at the moment.</P>
<HR class=topSection>
</HR><A name=ANaiveExample></A>
<H2>A Naive Example</H2>
<P>To help make all of this more concrete I'll use a running example to talk about all of this. Like all of my examples it's one of those super-simple examples; small enough to be unreal, but hopefully enough for you to visualize what's going on without falling into the bog of a real example.</P>
<P>In this example I'm writing a component that provides a list of movies directed by a particular director. This stunningly useful function is implemented by a single method.</P><PRE>class MovieLister...
    public Movie[] moviesDirectedBy(String arg) {
        List allMovies = finder.findAll();
        for (Iterator it = allMovies.iterator(); it.hasNext();) {
            Movie movie = (Movie) it.next();
            if (!movie.getDirector().equals(arg)) it.remove();
        }
        return (Movie[]) allMovies.toArray(new Movie[allMovies.size()]);
    }
</PRE>
<P>The implementation of this function is naive in the extreme, it asks a finder object (which we'll get to in a moment) to return every film it knows about. Then it just hunts through this list to return those directed by a particular director. This particular piece of naivety I'm not going to fix, since it's just the scaffolding for the real point of this article.</P>
<P>The real point of this article is this finder object, or particularly how we connect the lister object with a particular finder object. The reason why this is interesting is that I want my wonderful <CODE>moviesDirectedBy</CODE> method to be completely independent of how all the movies are being stored. So all the method does is refer to a finder, and all that finder does is know how to respond to the <CODE>findAll</CODE> method. I can bring this out by defining an interface for the finder.</P><PRE>public interface MovieFinder {
    List findAll();
}
</PRE>
<P>Now all of this is very well decoupled, but at some point I have to come up with a concrete class to actually come up with the movies. In this case I put the code for this in the constructor of my lister class.</P><PRE>class MovieLister...
  private MovieFinder finder;
  public MovieLister() {
    finder = new ColonDelimitedMovieFinder("movies1.txt");
  }
</PRE>
<P>The name of the implementation class comes from the fact that I'm getting my list from a colon delimited text file. I'll spare you the details, after all the point is just that there's some implementation.</P>
<P>Now if I'm using this class for just myself, this is all fine and dandy. But what happens when my friends are overwhelmed by a desire for this wonderful functionality and would like a copy of my program? If they also store their movie listings in a colon delimited text file called "movies1.txt" then everything is wonderful. If they have a different name for their movies file, then it's easy to put the name of the file in a properties file. But what if they have a completely different form of storing their movie listing: a SQL database, an XML file, a web service, or just another format of text file? In this case we need a different class to grab that data. Now because I've defined a <CODE>MovieFinder</CODE> interface, this won't alter my <CODE>moviesDirectedBy</CODE> method. But I still need to have some way to get an instance of the right finder implementation into place.</P>
<DIV class=figure>
<P class=figureImage><A name=naive.gif></A><IMG alt="Figure 1" src="http://www.martinfowler.com/articles/naive.gif"></IMG></P>
<P class=figureCaption>Figure 1: The dependencies using a simple creation in the lister class</P></DIV>
<P>Figure <A href="http://www.martinfowler.com/articles/injection.html#naive.gif">1</A> shows the dependencies for this situation. The <CODE>MovieLister</CODE> class is dependent on both the <CODE>MovieFinder</CODE> interface and upon the implementation. We would prefer it if it were only dependent on the interface, but then how do we make an instance to work with?</P>
<P>In my book <A href="http://www.martinfowler.com/books.html#eaa">P of EAA</A>, we described this situation as a <A href="http://martinfowler.com/eaaCatalog/plugin.html">Plugin</A>. The implementation class for the finder isn't linked into the program at compile time, since I don't know what my friends are going to use. Instead we want my lister to work with any implementation, and for that implementation to be plugged in at some later point, out of my hands. The problem is how can I make that link so that my lister class is ignorant of the implementation class, but can still talk to an instance to do its work.</P>
<P>Expanding this into a real system, we might have dozens of such services and components. In each case we can abstract our use of these components by talking to them through an interface (and using an adapter if the component isn't designed with an interface in mind). But if we wish to deploy this system in different ways, we need to use plugins to handle the interaction with these services so we can use different implementations in different deployments.</P>
<P>So the core problem is how do we assemble these plugins into an application? This is one of the main problems that this new breed of lightweight containers face, and universally they all do it using Inversion of Control.</P>
<HR class=topSection>
</HR><A name=InversionOfControl></A>
<H2>Inversion of Control</H2>
<P>When these containers talk about how they are so useful because they implement "Inversion of Control" I end up very puzzled. <A href="http://martinfowler.com/bliki/InversionOfControl.html">Inversion of control</A> is a common characteristic of frameworks, so saying that these lightweight containers are special because they use inversion of control is like saying my car is special because it has wheels.</P>
<P>The question, is what aspect of control are they inverting? When I first ran into inversion of control, it was in the main control of a user interface. Early user interfaces were controlled by the application program. You would have a sequence of commands like "Enter name", "enter address"; your program would drive the prompts and pick up a response to each one. With graphical (or even screen based) UIs the UI framework would contain this main loop and your program instead provided event handlers for the various fields on the screen. The main control of the program was inverted, moved away from you to the framework.</P>
<P>For this new breed of containers the inversion is about how they lookup a plugin implementation. In my naive example the lister looked up the finder implementation by directly instantiating it. This stops the finder from being a plugin. The approach that these containers use is to ensure that any user of a plugin follows some convention that allows a separate assembler module to inject the implementation into the lister.</P>
<P>As a result I think we need a more specific name for this pattern. Inversion of Control is too generic a term, and thus people find it confusing. As a result with a lot of discussion with various IoC advocates we settled on the name <I>Dependency Injection</I>.</P>
<P>I'm going to start by talking about the various forms of dependency injection, but I'll point out now that that's not the only way of removing the dependency from the application class to the plugin implementation. The other pattern you can use to do this is Service Locator, and I'll discuss that after I'm done with explaining Dependency Injection.</P>
<HR class=topSection>
</HR><A name=FormsOfDependencyInjection></A>
<H2>Forms of Dependency Injection</H2>
<P>The basic idea of the Dependency Injection is to have a separate object, an assembler, that populates a field in the lister class with an appropriate implementation for the finder interface, resulting in a dependency diagram along the lines of Figure <A href="http://www.martinfowler.com/articles/injection.html#injector.gif">2</A></P>
<DIV class=figure>
<P class=figureImage><A name=injector.gif></A><IMG alt="Figure 2" src="http://www.martinfowler.com/articles/injector.gif"></IMG></P>
<P class=figureCaption>Figure 2: The dependencies for a Dependency Injector</P></DIV>
<P>There are three main styles of dependency injection. The names I'm using for them are Constructor Injection, Setter Injection, and Interface Injection. If you read about this stuff in the current discussions about Inversion of Control you'll hear these referred to as type 1 IoC (interface injection), type 2 IoC (setter injection) and type 3 IoC (constructor injection). I find numeric names rather hard to remember, which is why I've used the names I have here.</P><A name=ConstructorInjectionWithPicocontainer></A>
<H3>Constructor Injection with PicoContainer</H3>
<P>I'll start with showing how this injection is done using a lightweight container called <A href="http://www.picocontainer.org/">PicoContainer</A>. I'm starting here primarily because several of my colleagues at ThoughtWorks are very active in the development of PicoContainer (yes, it's a sort of corporate nepotism.)</P>
<P>PicoContainer uses a constructor to decide how to inject a finder implementation into the lister class. For this to work, the movie lister class needs to declare a constructor that includes everything it needs injected.</P><PRE>class MovieLister...
    public MovieLister(MovieFinder finder) {
        this.finder = finder;       
    }
</PRE>
<P>The finder itself will also be managed by the pico container, and as such will have the filename of the text file injected into it by the container.</P><PRE>class ColonMovieFinder...
    public ColonMovieFinder(String filename) {
        this.filename = filename;
    }
</PRE>
<P>The pico container then needs to be told which implementation class to associate with each interface, and which string to inject into the finder.</P><PRE>    private MutablePicoContainer configureContainer() {
        MutablePicoContainer pico = new DefaultPicoContainer();
        Parameter[] finderParams =  {new ConstantParameter("movies1.txt")};
        pico.registerComponentImplementation(MovieFinder.class, ColonMovieFinder.class, finderParams);
        pico.registerComponentImplementation(MovieLister.class);
        return pico;
    }
</PRE>
<P>This configuration code is typically set up in a different class. For our example, each friend who uses my lister might write the appropriate configuration code in some setup class of their own. Of course it's common to hold this kind of configuration information in separate config files. You can write a class to read a config file and set up the container appropriately. Although PicoContainer doesn't contain this functionality itself, there is a closely related project called NanoContainer that provides the appropriate wrappers to allow you to have XML configuration files. Such a nano container will parse the XML and then configure an underlying pico container. The philosophy of the project is to separate the config file format from the underlying mechanism.</P>
<P>To use the container you write code something like this.</P><PRE>    public void testWithPico() {
        MutablePicoContainer pico = configureContainer();
        MovieLister lister = (MovieLister) pico.getComponentInstance(MovieLister.class);
        Movie[] movies = lister.moviesDirectedBy("Sergio Leone");
        assertEquals("Once Upon a Time in the West", movies[0].getTitle());
    }
</PRE>
<P>Although in this example I've used constructor injection, PicoContainer also supports setter injection, although it's developers do prefer constructor injection.</P><A name=SetterInjectionWithSpring></A>
<H3>Setter Injection with Spring</H3>
<P>The <A href="http://www.springframework.org/">Spring framework</A> is a wide ranging framework for enterprise Java development. It includes abstraction layers for transactions, persistence frameworks, web application development and JDBC. Like PicoContainer it supports both constructor and setter injection, but its developers tend to prefer setter injection - which makes it an appropriate choice for this example. </P>
<P>To get my movie lister to accept the injection I define a setting method for that service</P><PRE>class MovieLister...
    private MovieFinder finder;
  public void setFinder(MovieFinder finder) {
    this.finder = finder;
  }
</PRE>
<P>Similarly I define a setter for the string the finder.</P><PRE>class ColonMovieFinder...
    public void setFilename(String filename) {
        this.filename = filename;
    }
</PRE>
<P>The third step is to set up the configuration for the files. Spring supports configuration through XML files and also through code, but XML is the expected way to do it.</P><PRE>    &lt;beans&gt;
        &lt;bean id="MovieLister" class="spring.MovieLister"&gt;
            &lt;property name="finder"&gt;
                &lt;ref local="MovieFinder"/&gt;
            &lt;/property&gt;
        &lt;/bean&gt;
        &lt;bean id="MovieFinder" class="spring.ColonMovieFinder"&gt;
            &lt;property name="filename"&gt;
                &lt;value&gt;movies1.txt&lt;/value&gt;
            &lt;/property&gt;
        &lt;/bean&gt;
    &lt;/beans&gt;
</PRE>
<P>The test then looks like this.</P><PRE>    public void testWithSpring() throws Exception {
        ApplicationContext ctx = new FileSystemXmlApplicationContext("spring.xml");
        MovieLister lister = (MovieLister) ctx.getBean("MovieLister");
        Movie[] movies = lister.moviesDirectedBy("Sergio Leone");
        assertEquals("Once Upon a Time in the West", movies[0].getTitle());
    }
</PRE><A name=InterfaceInjection></A>
<H3>Interface Injection</H3>
<P>The third injection technique is to define and use interfaces for the injection. <A href="http://avalon.apache.org/">Avalon</A> is an example of a framework that uses this technique in places. I'll talk a bit more about that later, but in this case I'm going to use it with some simple sample code.</P>
<P>With this technique I begin by defining an interface that I'll use to perform the injection through. Here's the interface for injecting a movie finder into an object.</P><PRE>public interface InjectFinder {
    void injectFinder(MovieFinder finder);
}
</PRE>
<P>This interface would be defined by whoever provides the MovieFinder interface. It needs to be implemented by any class that wants to use a finder, such as the lister.</P><PRE>class MovieLister implements InjectFinder...
    public void injectFinder(MovieFinder finder) {
        this.finder = finder;
    }
</PRE>
<P>I use a similar approach to inject the filename into the finder implementation.</P><PRE>public interface InjectFinderFilename {
    void injectFilename (String filename);
}
</PRE><PRE>class ColonMovieFinder implements MovieFinder, InjectFinderFilename......
    public void injectFilename(String filename) {
        this.filename = filename;
    }
</PRE>
<P>Then, as usual, I need some configuration code to wire up the implementations. For simplicity's sake I'll do it in code.</P><PRE>class Tester...
    private Container container;

     private void configureContainer() {
       container = new Container();
       registerComponents();
       registerInjectors();
       container.start();
    }
</PRE>
<P>This configuration has two stages, registering components through lookup keys is pretty similar to the other examples.</P><PRE>class Tester...
  private void registerComponents() {
    container.registerComponent("MovieLister", MovieLister.class);
    container.registerComponent("MovieFinder", ColonMovieFinder.class);
  }
</PRE>
<P>A new step is to register the injectors that will inject the dependent components. Each injection interface needs some code to inject the dependent object. Here I do this by registering injector objects with the container. Each injector object implements the injector interface. </P><PRE>class Tester...
  private void registerInjectors() {
    container.registerInjector(InjectFinder.class, container.lookup("MovieFinder"));
    container.registerInjector(InjectFinderFilename.class, new FinderFilenameInjector());
  }
</PRE><PRE>public interface Injector {
  public void inject(Object target);

}
</PRE>
<P>When the dependent is a class written for this container, it makes sense for the component to implement the injector interface itself, as I do here with the movie finder. For generic classes, such as the string, I use an inner class within the configuration code. </P><PRE>class ColonMovieFinder implements Injector......
  public void inject(Object target) {
    ((InjectFinder) target).injectFinder(this);        
  }
</PRE><PRE>class Tester...
  public static class FinderFilenameInjector implements Injector {
    public void inject(Object target) {
      ((InjectFinderFilename)target).injectFilename("movies1.txt");      
    }
    }
</PRE>
<P>The tests then use the container.</P><PRE>class IfaceTester...
    public void testIface() {
      configureContainer();
      MovieLister lister = (MovieLister)container.lookup("MovieLister");
      Movie[] movies = lister.moviesDirectedBy("Sergio Leone");
      assertEquals("Once Upon a Time in the West", movies[0].getTitle());
    }
</PRE>
<P>The container uses the declared injection interfaces to figure out the dependendencies and the injectors to inject the correct dependents. (The specific container implementation I did here isn't important to the technique, and I won't show it because you'd only laugh.)</P>
<HR class=topSection>
</HR><A name=UsingAServiceLocator></A>
<H2>Using a Service Locator</H2>
<P>The key benefit of a Dependency Injector is that it removes the dependency that the <CODE>MovieLister</CODE> class has on the concrete <CODE>MovieFinder</CODE> implementation. This allows me to give listers to friends and for them to plug in a suitable implementation for their own environment. Injection isn't the only way to break this dependency, another is to use a <A href="http://java.sun.com/blueprints/corej2eepatterns/Patterns/ServiceLocator.html">service locator</A>.</P>
<P>The basic idea behind a service locator is to have an object that knows how to get hold of all of the services that an application might need. So a service locator for this application would have a method that returns a movie finder when one is needed. Of course this just shifts the burden a tad, we still have to get the locator into the lister, resulting in the dependencies of Figure <A href="http://www.martinfowler.com/articles/injection.html#locator.gif">3</A></P>
<DIV class=figure>
<P class=figureImage><A name=locator.gif></A><IMG alt="Figure 3" src="http://www.martinfowler.com/articles/locator.gif"></IMG></P>
<P class=figureCaption>Figure 3: The dependencies for a Service Locator</P></DIV>
<P>In this case I'll use the ServiceLocator as a singleton <A href="http://martinfowler.com/eaaCatalog/registry.html">Registry</A>. The lister can then use that to get the finder when it's instantiated.</P><PRE>class MovieLister...
    MovieFinder finder = ServiceLocator.movieFinder();
</PRE><PRE>class ServiceLocator...
    public static MovieFinder movieFinder() {
        return soleInstance.movieFinder;
    }
    private static ServiceLocator soleInstance;
    private MovieFinder movieFinder;
</PRE>
<P>As with the injection approach, we have to configure the service locator. Here I'm doing it in code, but it's not hard to use a mechanism that would read the appropriate data from a configuration file.</P><PRE>class Tester...
    private void configure() {
        ServiceLocator.load(new ServiceLocator(new ColonMovieFinder("movies1.txt")));
    }
</PRE><PRE>class ServiceLocator...
    public static void load(ServiceLocator arg) {
        soleInstance = arg;
    }

    public ServiceLocator(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }
</PRE>
<P>Here's the test code.</P><PRE>class Tester...
    public void testSimple() {
        configure();
        MovieLister lister = new MovieLister();
        Movie[] movies = lister.moviesDirectedBy("Sergio Leone");
        assertEquals("Once Upon a Time in the West", movies[0].getTitle());
    }
</PRE>
<P>I've often heard the complaint that these kinds of service locators are a bad thing because they aren't testable because you can't substitute implementations for them. Certainly you can design them badly to get into this kind of trouble, but you don't have to. In this case the service locator instance is just a simple data holder. I can easily create the locator with test implementations of my services.</P>
<P>For a more sophisticated locator I can subclass service locator and pass that subclass into the registry's class variable. I can change the static methods to call a method on the instance rather accessing instance variables directly. I can provide thread specific locators by using thread specific storage. All of this can be done without changing clients of service locator.</P>
<P>A way to think of this is that service locator is a registry not a singleton. A singleton provides a simple way of implementing a registry, but that implementation decision is easily changed. </P><A name=UsingASegregatedInterfaceForTheLocator></A>
<H3>Using a Segregated Interface for the Locator</H3>
<P>One of the issues with the simple approach above, is that the MovieLister is dependent on the full service locator class, even though it only uses one service. We can reduce this by using a <A href="http://www.objectmentor.com/resources/articles/isp.pdf">segregated interface</A>. That way, instead of using the full service locator interface, the lister can declare just the bit of interface it needs.</P>
<P>In this situation the provider of the lister would also provide a locator interface which it needs to get hold of the finder.</P><PRE>public interface MovieFinderLocator {
    public MovieFinder movieFinder();
</PRE>
<P>The locator then needs to implement this interface to provide access to a finder.</P><PRE>    MovieFinderLocator locator = ServiceLocator.locator();
    MovieFinder finder = locator.movieFinder();
</PRE><PRE>   public static ServiceLocator locator() {
        return soleInstance;
    }
    public MovieFinder movieFinder() {
        return movieFinder;
    }
    private static ServiceLocator soleInstance;
    private MovieFinder movieFinder;
</PRE>
<P>You'll notice that since we want to use an interface, we can't just access the services through static methods any more. We have to use the class to get a locator instance and then use that to get what we need. </P><A name=ADynamicServiceLocator></A>
<H3>A Dynamic Service Locator</H3>
<P>The above example was static, in that the service locator class has methods for each of the services that you need. This isn't the only way of doing it, you can also make a dynamic service locator that allows you to stash any service you need into it and make your choices at runtime.</P>
<P>In this case, the service locator uses a map instead of fields for each of the services, and provides generic methods to get and load services.</P><PRE>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) {
        services.put(key, service);
    }
</PRE>
<P>Configuring involves loading a service with an appropriate key.</P><PRE>class Tester...
    private void configure() {
        ServiceLocator locator = new ServiceLocator();
        locator.loadService("MovieFinder", new ColonMovieFinder("movies1.txt"));
        ServiceLocator.load(locator);
    }
</PRE>
<P>I use the service by using the same key string.</P><PRE>class MovieLister...
    MovieFinder finder = (MovieFinder) ServiceLocator.getService("MovieFinder");
</PRE>
<P>On the whole I dislike this approach. Although it's certainly flexible, it's not very explicit. The only way I can find out how to reach a service is through textual keys. I prefer explicit methods because it's easier to find where they are by looking at the interface definitions.</P><A name=UsingBothALocatorAndInjectionWithAvalon></A>
<H3>Using both a locator and injection with Avalon</H3>
<P>Dependency injection and a service locator aren't necessarily mutually exclusive concepts. A good example of using both together is the Avalon framework. Avalon uses a service locator, but uses injection to tell components where to find the locator.</P>
<P>Berin Loritsch sent me this simple version of my running example using Avalon.</P><PRE>public class MyMovieLister implements MovieLister, Serviceable {
    private MovieFinder finder;

    public void service( ServiceManager manager ) throws ServiceException {
        finder = (MovieFinder)manager.lookup("finder");
    } 
      </PRE>
<P>The service method is an example of interface injection, allowing the container to inject a service manager into MyMovieLister. The service manager is an example of a service locator. In this example the lister doesn't store the manager in a field, instead it immediately uses it to lookup the finder, which it does store.</P>
<HR class=topSection>
</HR><A name=DecidingWhichOptionToUse></A>
<H2>Deciding which option to use</H2>
<P>So far I've concentrated on explaining how I see these patterns and their variations. Now I can start talking about their pros and cons to help figure out which ones to use and when.</P><A name=ServiceLocatorVsDependencyInjection></A>
<H3>Service Locator vs Dependency Injection</H3>
<P>The fundamental choice is between Service Locator and Dependency Injection. The first point is that both implementations provide the fundamental decoupling that's missing in the naive example - in both cases application code is independent of the concrete implementation of the service interface. The important difference between the two patterns is about how that implementation is provided to the application class. With service locator the application class asks for it explicitly by a message to the locator. With injection there is no explicit request, the service appears in the application class - hence the inversion of control.</P>
<P>Inversion of control is a common feature of frameworks, but it's something that comes at a price. It tends to be hard to understand and leads to problems when you are trying to debug. So on the whole I prefer to avoid it unless I need it. This isn't to say it's a bad thing, just that I think it needs to justify itself over the more straightforward alternative.</P>
<P>The key difference is that with a Service Locator every user of a service has a dependency to the locator. The locator can hide dependencies to other implementations, but you do need to see the locator. So the decision between locator and injector depends on whether that dependency is a problem.</P>
<P>Using dependency injection can help make it easier to see what the component dependencies are. With dependency injector you can just look at the injection mechanism, such as the constructor, and see the dependencies. With the service locator you have to search the source code for calls to the locator. Modern IDEs with a find references feature make this easier, but it's still not as easy as looking at the constructor or setting methods.</P>
<P>A lot of this depends on the nature of the user of the service. If you are building an application with various classes that use a service, then a dependency from the application classes to the locator isn't a big deal. In my example of giving a Movie Lister to my friends, then using a service locator works quite well. All they need to do is to configure the locator to hook in the right service implementations, either through some configuration code or through a configuration file. In this kind of scenario I don't see the injector's inversion as providing anything compelling.</P>
<P>The difference comes if the lister is a component that I'm providing to an application that other people are writing. In this case I don't know much about the APIs of the service locators that my customers are going to use. Each customer might have their own incompatible service locators. I can get around around some of this by using the segregated interface. Each customer can write an adapter that matches my interface to their locator, but in any case I still need to see the first locator to lookup my specific interface. And once the adapter appears then the simplicity of the direct connection to a locator is beginning to slip.</P>
<P>Since with an injector you don't have a dependency from a component to the injector, the component cannot obtain further services from the injector once it's been configured. </P>
<P>A common reason people give for preferring dependency injection is that it makes testing easier. The point here is that to do testing, you need to easily replace real service implementations with stubs or mocks. However there is really no difference here between dependency injection and service locator: both are very amenable to stubbing. I suspect this observation comes from projects where people don't make the effort to ensure that their service locator can be easily substituted. This is where continual testing helps, if you can't easily stub services for testing, then this implies a serious problem with your design.</P>
<P>Of course the testing problem is exacerbated by component environments that are very intrusive, such as Java's EJB framework. My view is that these kinds of frameworks should minimize their impact upon application code, and particularly should not do things that slow down the edit-execute cycle. Using plugins to substitute heavyweight components does a lot help this process, which is vital for practices such as Test Driven Development.</P>
<P>So the primary issue is for people who are writing code that expects to be used in applications outside of the control of the writer. In these cases even a minimal assumption about a Service Locator is a problem.</P><A name=ConstructorVersusSetterInjection></A>
<H3>Constructor versus Setter Injection</H3>
<P>For service combination, you always have to have some convention in order to wire things together. The advantage of injection is primarily that it requires very simple conventions - at least for the constructor and setter injections. You don't have to do anything odd in your component and it's fairly straightforward for an injector to get everything configured.</P>
<P>Interface injection is more invasive since you have to write a lot of interfaces to get things all sorted out. For a small set of interfaces required by the container, such as in Avalon's approach, this isn't too bad. But it's a lot of work for assembling components and dependencies, which is why the current crop of lightweight containers go with setter and constructor injection.</P>
<P>The choice between setter and constructor injection is interesting as it mirrors are more general issue with object-oriented programming - should you fill fields in a constructor or with setters.</P>
<P>My long running default with objects is as much as possible, to create valid objects at construction time. This advice goes back to Kent Beck's <A href="http://www.amazon.com/exec/obidos/ASIN/013476904X">Smalltalk Best Practice Patterns</A>: Constructor Method and Constructor Parameter Method. Constructors with parameters give you a clear statement of what it means to create a valid object in an obvious place. If there's more than one way to do it, create multiple constructors that show the different combinations.</P>
<P>Another advantage with constructor initialization is that it allows you to clearly hide any fields that are immutable by simply not providing a setter. I think this is important - if something shouldn't change then the lack of a setter communicates this very well. If you use setters for initialization, then this can become a pain. (Indeed in these situations I prefer to avoid the usual setting convention, I'd prefer a method like <CODE>initFoo</CODE>, to stress that it's something you should only do at birth.)</P>
<P>But with any situation there are exceptions. If you have a lot of constructor parameters things can look messy, particularly in languages without keyword parameters. It's true that a long constructor is often a sign of an over-busy object that should be split, but there are cases when that's what you need.</P>
<P>If you have multiple ways to construct a valid object, it can be hard to show this through constructors, since constructors can only vary on the number and type of parameters. This is when Factory Methods come into play, these can use a combination of private constructors and setters to implement their work. The problem with classic Factory Methods for components assembly is that they are usually seen as static methods, and you can't have those on interfaces. You can make a factory class, but then that just becomes another service instance. A factory service is often a good tactic, but you still have to instantiate the factory using one of the techniques here.</P>
<P>Constructors also suffer if you have simple parameters such as strings. With setter injection you can give each setter a name to indicate what the string is supposed to do. With constructors you are just relying on the position, which is harder to follow.</P>
<P>If you have multiple constructors and inheritance, then things can get particularly awkward. In order to initialize everything you have to provide constructors to forward to each superclass constructor, while also adding you own arguments. This can lead to an even bigger explosion of constructors.</P>
<P>Despite the disadvantages my preference is to start with constructor injection, but be ready to switch to setter injection as soon as the problems I've outlined above start to become a problem. </P>
<P>This issue has led to a lot of debate between the various teams who provide dependency injectors as part of their frameworks. However it seems that most people who build these frameworks have realized that it's important to support both mechanisms, even if there's a preference for one of them.</P><A name=CodeOrConfigurationFiles></A>
<H3>Code or configuration files</H3>
<P>A separate but often conflated issue is whether to use configuration files or code on an API to wire up services. For most applications that are likely to be deployed in many places, a separate configuration file usually makes most sense. Almost all the time this will be an XML file, and this makes sense. However there are cases where it's easier to use program code to do the assembly. One case is where you have a simple application that's not got a lot of deployment variation. In this case a bit of code can be clearer than separate XML file. </P>
<P>A contrasting case is where the assembly is quite complex, involving conditional steps. Once you start getting close to programming language then XML starts breaking down and it's better to use a real language that has all the syntax to write a clear program. You then write a builder class that does the assembly. If you have distinct builder scenarios you can provide several builder classes and use a simple configuration file to select between them. </P>
<P>I often think that people are over-eager to define configuration files. Often a programming language makes a straightforward and powerful configuration mechanism. Modern languages can easily compile small assemblers that can be used to assemble plugins for larger systems. If compilation is a pain, then there are scripting languages that can work well also. </P>
<P>It's often said that configuration files shouldn't use a programing language because they need to be edited by non-programmers. But how often is this the case? Do people really expect non-programmers to alter the transaction isolation levels of complex server-side application? Non-language configuration files work well only to the extent they are simple. If they become complex then it's time to think about using a proper programming language.</P>
<P>One thing we're seeing in the Java world at the moment is a cacophony of configuration files, where every component has its own configuration files which are different to everyone else's. If you use a dozen of these components, you can easily end up with a dozen configuration files to keep in sync.</P>
<P>My advice here is to always provide a way to do all configuration easily with a programmatic interface, and then treat a separate configuration file as an optional feature. You can easily build configuration file handling to use the programmatic interface. If you are writing a component you then leave it up to your user whether to use the programmatic interface, your configuration file format, or to write their own custom configuration file format and tie it into the programmatic interface</P><A name=SeparatingConfigurationFromUse></A>
<H3>Separating Configuration from Use</H3>
<P>The important issue in all of this is to ensure that the configuration of services is separated from their use. Indeed this is a fundamental design principle that sits with the separation of interfaces from implementation. It's something we see within an object-oriented program when conditional logic decides which class to instantiate, and then future evaluations of that conditional are done through polymorphism rather than through duplicated conditional code.</P>
<P>If this separation is useful within a single code base, it's especially vital when you're using foreign elements such as components and services. The first question is whether you wish to defer the choice of implementation class to particular deployments. If so you need to use some implementation of plugin. Once you are using plugins then it's essential that the assembly of the plugins is done separately from the rest of the application so that you can substitute different configurations easily for different deployments. How you achieve this is secondary. This configuration mechanism can either configure a service locator, or use injection to configure objects directly.</P>
<HR class=topSection>
</HR><A name=SomeFurtherIssues></A>
<H2>Some further issues</H2>
<P>In this article, I've concentrated on the basic issues of service configuration using Dependency Injection and Service Locator. There are some more topics that play into this which also deserve attention, but I haven't had time yet to dig into. In particular there is the issue of life-cycle behavior. Some components have distinct life-cycle events: stop and starts for instance. Another issue is the growing interest in using aspect oriented ideas with these containers. Although I haven't considered this material in the article at the moment, I do hope to write more about this either by extending this article or by writing another.</P>
<P>You can find out a lot more about these ideas by looking at the web sites devoted to the lightweight containers. Surfing from the <A href="http://www.picocontainer.org/">picocontainer</A> and <A href="http://www.springframework.org/">spring</A> web sites will lead to you into much more discussion of these issues and a start on some of the further issues.</P>
<HR class=topSection>
</HR><A name=ConcludingThoughts></A>
<H2>Concluding Thoughts</H2>
<P>The current rush of lightweight containers all have a common underlying pattern to how they do service assembly - the dependency injector pattern. Dependency Injection is a useful alternative to Service Locator. When building application classes the two are roughly equivalent, but I think Service Locator has a slight edge due to its more straightforward behavior. However if you are building classes to used in multiple applications then Dependency Injection is a better choice.</P>
<P>If you use Dependency Injection there are a number of styles to choose between. I would suggest you follow constructor injection unless you run into into one of the specific problems with that approach, in which case switch to setter injection. If you are choosing to build or obtain a container, look for one that supports both constructor and setter injection.</P>
<P>The choice between Service Locator and Dependency Injection is less important than the principle of separating service configuration from the use of services within an application. </P>
<HR class=bodySep>
</HR></DIV>
<DIV class=appendix>
<HR class=topSection>
</HR><A name=Acknowledgements></A>
<H2>Acknowledgements</H2>
<P>My sincere thanks to the many people who've helped me with this article. Rod Johnson, Paul Hammant, Joe Walnes, Aslak Helles?on Tirs鮠and Bill Caputo helped me get to grips with these concepts and commented on the early drafts of this article. Berin Loritsch and Hamilton Verissimo de Oliveira provided some very helpful advice on how Avalon fits in. Dave W Smith persisted in asking questions about my initial interface injection configuration code and thus made me confront the fact that it was stupid.</P></DIV>
<DIV class=appendix>
<H2><A name=SignificantRevisions></A>Significant Revisions</H2>
<P><I>23 Jan 04: </I>Redid the configuration code of the interface injection example.</P>
<P><I>16 Jan 04: </I>Added a short example of both locator and injection with Avalon.</P>
<P><I>14 Jan 04: </I>First Publication</P></DIV><img src ="http://www.cnitblog.com/rukas/aggbug/4638.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/rukas/" target="_blank">Rukas - Oh, My Blog!</a> 2005-11-17 21:00 <a href="http://www.cnitblog.com/rukas/archive/2005/11/17/4638.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>A Brief Introduction to IoC</title><link>http://www.cnitblog.com/rukas/archive/2005/11/17/4607.html</link><dc:creator>Rukas - Oh, My Blog!</dc:creator><author>Rukas - Oh, My Blog!</author><pubDate>Thu, 17 Nov 2005 06:34:00 GMT</pubDate><guid>http://www.cnitblog.com/rukas/archive/2005/11/17/4607.html</guid><wfw:comment>http://www.cnitblog.com/rukas/comments/4607.html</wfw:comment><comments>http://www.cnitblog.com/rukas/archive/2005/11/17/4607.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/rukas/comments/commentRss/4607.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/rukas/services/trackbacks/4607.html</trackback:ping><description><![CDATA[<H2><IMG height=91 alt="A Brief Introduction to IoC" hspace=10 src="http://today.java.net/images/tiles/111-ioc.gif" width=111 align=left border=0> A Brief Introduction to IoC</H2>by <A href="http://today.java.net/pub/au/85">Sam Newman</A><BR>02/10/2004<BR clear=all><BR><!--  sidebar begins  --><!--  don't move sidebars  --><!--  sidebar ends  --><!--  sidebar begins  --><!--  TOC  -->
<TABLE cellSpacing=0 cellPadding=0 align=right border=0>
<TBODY>
<TR>
<TD bgColor=#000000><IMG height=1 src="http://today.java.net/im/a.gif" width=10></TD></TR>
<TR>
<TD>
<TABLE cellSpacing=0 cellPadding=6 align=right border=0>
<TBODY>
<TR>
<TD><IMG height=1 src="http://today.java.net/im/a.gif" width=10><BR><B>Contents</B></TD></TR>
<TR>
<TD><A href="http://today.java.net/pub/a/today/2004/02/10/ioc.html#The_Theory_of_IoC">The Theory of IoC</A></TD></TR>
<TR>
<TD><A href="http://today.java.net/pub/a/today/2004/02/10/ioc.html#IoC_frameworks">IoC Frameworks</A></TD></TR>
<TR>
<TD>&nbsp;&nbsp;&nbsp;<A href="http://today.java.net/pub/a/today/2004/02/10/ioc.html#Interface_Injection">Interface Injection (Type 1)</A></TD></TR>
<TR>
<TD>&nbsp;&nbsp;&nbsp;<A href="http://today.java.net/pub/a/today/2004/02/10/ioc.html#Setter_Injection">Setter Injection (Type 2)</A></TD></TR>
<TR>
<TD>&nbsp;&nbsp;&nbsp;<A href="http://today.java.net/pub/a/today/2004/02/10/ioc.html#Constructor_Injection">Constructor Injection (Type 3)</A></TD></TR>
<TR>
<TD><A href="http://today.java.net/pub/a/today/2004/02/10/ioc.html#IoC_in_action">IoC in Action: The Data Access Object Pattern</A></TD></TR>
<TR>
<TD><A href="http://today.java.net/pub/a/today/2004/02/10/ioc.html#Spring_vs_PicoContainer">Spring Vs. PicoContainer</A></TD></TR>
<TR>
<TD><A href="http://today.java.net/pub/a/today/2004/02/10/ioc.html#Conclusion">Conclusion</A></TD></TR></TBODY></TABLE></TD></TR>
<TR>
<TD bgColor=#000000><IMG height=1 src="http://today.java.net/im/a.gif" width=10></TD></TR></TBODY></TABLE><!--  sidebar ends  -->
<P>This article aims to introduce the notion of Inversion Of Control (IoC) and how it can streamline application design. We will look at the different types of IoC frameworks. By showing how IoC can result in simpler, more flexible code, you'll also be able to see why IoC has attracted so much interest of late.</P>
<H2 id=The_Theory_of_IoC>The Theory of IoC</H2>
<P>The best way to describe what IoC is about, and what benefits it can provide, is to look at a simple example. The following <CODE>JDBCDataManger</CODE> class is used to manage our application's accessing of the database. This application is currently using raw JDBC for persistence. To access the persistence store via JDBC, the <CODE>JDBCDataManger</CODE> will need a <CODE>DataSource</CODE> object. The standard approach would be to hard code this <CODE>DataSource</CODE> object into the class, like this:</P><PRE><CODE>public class JDBCDataManger {
  public void accessData() {
    DataSource dataSource = new DataSource();
    //access data
    ...
}</CODE></PRE>
<P>Given that <CODE>JDBCDataManger</CODE> is handling all data access for our application, hard coding the <CODE>DataSource</CODE> isn't that bad, but we may want to further abstract the <CODE>DataSource</CODE>, perhaps getting it via some system-wide property object:</P><PRE><CODE>public class JDBCDataManger {
  public void accessData() {
    DataSource dataSource = 
      ApplciationResources.getDataSource();
}</CODE></PRE>
<P>In either case, the <CODE>JDBCDataManger</CODE> has to fetch the <CODE>DataSource</CODE> itself.</P>
<P>IoC takes a different approach — with IoC, the <CODE>JDBCDataManger</CODE> would declare its need for a <CODE>DataSource</CODE> and have one provided to it by an IoC framework. This means that the component would no longer need to know how to get the dependency, resulting in cleaner, more focused, and more flexible code.</P>
<H2 id=IoC_frameworks>IoC Frameworks</H2>
<P>The ideas behind IoC aren't especially new; in fact, many have remarked that IoC is nothing but a new acronym for the older <A href="http://www.objectmentor.com/resources/articles/dip.pdf">Dependency Inversion Principle</A> (PDF file). What is new is the interest in IoC, and the large number of frameworks being actively developed to aid the use of IoC. </P>
<P>IoC frameworks are the facilitators for the IoC pattern — think of a framework's job as being the glue for connecting the components in an IoC system. While the general principle of IoC is fairly straightforward, there are several distinct implementations evident in the frameworks. The developers of PicoContainer originally defined the three types of IoC, in order to differentiate their approach from the other frameworks around at the time. At first, these types were simply called Types 1,2, and 3, but in Martin Fowler's recent article, "<A href="http://www.martinfowler.com/articles/injection.html">Inversion of Control Containers and the Dependency Injection Pattern</A>," he coined some more informative terms for these three types, which we will use below.</P>
<P>In the rest of the article, we'll look briefly at <A title="The Avalon Project" href="http://avalon.apache.org/framework/">Avalon</A>, and in more depth at the two most popular IoC frameworks, <A href="http://www.springframework.org/">Spring</A> and <A href="http://picocontainer.org/">PicoContainer</A>, and the types of IoC they provide.</P>
<H5 id=Interface_Injection>Interface Injection (Type 1)</H5>
<P>With Interface Injection IoC, components implement specific interfaces provided by their containers in order to be configured. Let's look at a refactor of our <CODE>JDBCDataManager</CODE> that uses the Avalon framework:</P><PRE><CODE>import org.apache.avalon.framework.*;

  public class JDBCDataManger implements Serviceable {
    DataSource dataSource;
    public void service (ServiceManager sm) 
          throws ServiceException {
      dataSource = (DataSource)sm.lookup("dataSource");
    }
    
    public void getData() {
      //use dataSource for something
    }
}</CODE></PRE>
<P>This form of IoC has been around for longer than the term IoC has been in use — many of you might have used such a form of IoC when using the EJB framework, for example. Here, your components extend and implement specified interfaces, which then get called by the framework itself.</P>
<P>The fact that the Avalon framework has been providing an IoC framework for several years now, without generating nearly as much interest in the idea as either Spring or PicoContainer, is probably due to the downsides of this approach. The requirement to implement specific interfaces can give code a "bloated" feel, while at the same time coupling your application code to the underlying framework. The benefits provided by the other two forms of IoC we will look at next far outweigh those provided by this form of IoC.</P>
<H5 id=Setter_Injection>Setter Injection (Type 2)</H5>
<P>With Setter Injection IoC, some external metadata is used to resolve dependencies. In Spring, this metadata takes the form of an XML configuration file. With this form of IoC, the <CODE>JDBCDataManager</CODE> class looks like a normal bean:</P><PRE><CODE>public class JDBCDataManger {
  private DataSource dataSource;
  
  public void setDataManager(DataSource dataSource {
    this.dataSource = dataSource;
  }
  
  public void getData() {
      //use dataSource for something
  }
}</CODE></PRE>
<P>Our <CODE>JDBCDataManger</CODE> component exposes its <CODE>dataSource</CODE> property to allow Spring to set it. Spring does this using its XML configuration. First we define a data source bean (which can be reused by multiple components):</P><PRE><CODE>&lt;bean id="myDataSource" 
  class="org.apache.commons.dbcp.BasicDataSource" &gt;
  &lt;property name="driverClassName"&gt;
    &lt;value&gt;com.mydb.jdbc.Driver&lt;/value&gt;
  &lt;/property&gt;
  &lt;property name="url"&gt;
    &lt;value&gt;jdbc:mydb://server:port/mydb&lt;/value&gt;
  &lt;/property&gt;
  &lt;property name="username"&gt;
    &lt;value&gt;root&lt;/value&gt;
  &lt;/property&gt;
&lt;/bean&gt;</CODE></PRE>
<P>Next, we define an instance of our manager and pass in a reference to the data source:</P><PRE><CODE>&lt;bean id="dataManager" 
  class="example.JDBCDataManger"&gt;
  &lt;property name="dataSource"&gt;
    &lt;ref bean="myDataSource"/&gt;
  &lt;/property&gt;
&lt;/bean&gt;</CODE></PRE>
<P>At runtime, a <CODE>JDBCDataManger</CODE> class will be instantiated with the correct <CODE>DataSource</CODE> dependency resolved, and we will be able to access the bean via the Spring framework itself.</P>
<P>The definition of dependencies in this way makes unit testing a breeze: simply define an XML file for your mock objects, replacing your normal XML file, and away you go.</P>
<P>Perhaps the main advantage of Setter Injection is that application code is not tied to the container in any way, but this is also a downside — it's not immediately clear how this <CODE>JDBCDataManger</CODE> component relates to everything else. It almost seems as though the <CODE>DataSource</CODE> is being magically passed to the <CODE>JDBCDataManger</CODE>, as the dependency management is being done outside of the Java code. Another disadvantage is that Spring requires getters and setters for its dependency resolution. You have to expose properties that you might perhaps not otherwise expose, potentially breaking data encapsulation rules and, at best, making a class' interface more complex than is needed. With Spring's metadata being described in XML, it cannot be validated at compile time during normal Java compilation, meaning issues with broken dependencies can only be spotted at runtime. </P>
<H5 id=Constructor_Injection>Constructor Injection (Type 3)</H5>
<P>Constructor Injection is based around this principle of the "Good Citizen." The Good Citizen pattern was introduced by Joshua Bloch, to describe objects that, upon creation, are fully set up and valid to use. In practice, this means that objects should not need additional methods to be called on them after instantiation in order to make them useable. The result is that you can sure that once you've created such an object, it's fit to use. This radically simplifies your code and reduces the need for defensive coding checks, while at the same time making your code more defensive as a whole. Such code is also very easy to test.</P>
<P>With Constructor Injection, you register an object with the framework, specify the parameters to use (which can in turn be created by the framework itself) and then just request an instance. The components being registered just have to implement a constructor, which can be used to inject the dependencies. Recently, Spring has introduced support for this form of IoC, but we'll look instead at PicoContainer, which has been built around this principle. Let's look at our <CODE>JDBCDataManger</CODE>, now recoded for use with a Constructor Injection framework:</P><PRE><CODE>public class JDBCDataManger {
  private DataSource dataSource;
  
  public JDBCDataManger(DataSource dataSource) {
    this.dataSource = dataSource;
  }
  
  public void getData() {
      //use dataSource for something
  }
}</CODE></PRE>
<P>Rather than using a configuration file, PicoContainer uses some good old-fashioned Java to glue everything together:</P><PRE><CODE>//create a datasource bean
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("com.mydb.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/mydb");
dataSource.setUsername("Bob");

//create the container
MutablePicoContainer pico = new DefaultPicoContainer();

//register components with container
ConstantParameter dataSourceParam =
    new ConstantParameter(dataSource);
String key = "DataManager";
Parameter[] params = {dataSourceParam};

/*
 * Now each request for a DataManager will instantiate
 * a JDBCDataManager object with our defined
 * dataSource object
 */
pico.registerComponentImplementation (key,
    JDBCDataManger.class,params);</CODE></PRE>
<P>To get instances of the <CODE>JDBCDataManager</CODE> object, we just have to reference the class by its key:</P><PRE><CODE>JDBCDataManger dm =
    (JDBCDataManger)pico.getComponentInstance(key);</CODE></PRE>
<P>Like Setter Injection IoC, our application code (apart from the Pico-specific configuration) is independent of the framework itself, and also gives you the advantages inherited from the use of the Good Citizen pattern. In addition, given that PicoContainer only requires a constructor, we have to make much less provisioning for the use of an IoC framework than with Setter Injection IoC.</P>
<P>Potential downsides with this approach are that using constructors to maintain the dependencies can become more complex when using inheritance, and it can cause issues if you use your constructors for purposes other than simply initializing the object. (Which some do!)</P>
<H2 id=IoC_in_action>IoC in Action: The Data Access Object Pattern</H2>
<P>Currently, our <CODE>JDBCDataManger</CODE> class is using SQL to access our data. What if we wanted to access data via Hibernate, or JDO? We could replace the uses of <CODE>JDBCDataManger</CODE> with a new class, but a more elegant solution would be to use the Data Access Object (DAO) pattern. In brief, the DAO pattern defines a method by which normal value objects are used to set and retrieve data (think normal JavaBeans), and this access is done via an abstract Data Access Object. (For those of you wishing to learn more on the DAO pattern, Sun's <A href="http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html">Pattern Catalog</A> is a good place to start.) </P>
<P>Our existing <CODE>JDBCDataManger</CODE> will remain unchanged. We will add an <CODE>Interface</CODE> called <CODE>DataManager</CODE>, which will implement our data access methods. For the sake of argument, we'll also add a Hibernate implementation, <CODE>HibernateDataManager</CODE>. Both <CODE>JDBCDataManger</CODE> and <CODE>HibernateDataManager</CODE> become Data Access Objects. </P>
<P>Assuming we were already using IoC, changing which DAO to use is a breeze. Assuming we use Spring with the code above, we can use Hibernate instead of JDBC by simply changing the XML config to resolve to the <CODE>HibernateDataManager</CODE> rather than the <CODE>JDBCDataManger</CODE> class. Likewise for PicoContainer: we just register the <CODE>HibernateDataManager</CODE> class instead of the <CODE>JDBCDataManger</CODE>. When switching between DAO implementations, our application code will remain unchanged, assuming they are just expecting the <CODE>DataManager</CODE> interface rather than the <CODE>JDBCDataManger</CODE> implementation. </P>
<P>By using a DAO interface with two implementations, we are combining the DAO pattern with the <A href="http://www.developer.com/java/other/article.php/626001">Abstract Factory pattern</A>. In effect, the IoC frameworks are undertaking the role of the factory itself. Using such a pattern during development makes moving to another persistence mechanism very easy indeed, and can be of great use if your development environment uses a slightly different setup than your release environment. Both implementations of the <CODE>DataManager</CODE> can be in the same codebase, and switching between them is trivial.</P>
<H2 id=Spring_vs_PicoContainer>Spring Vs. PicoContainer</H2>
<P>PicoContainer and Spring differ little in the amount of work required to set up your IoC bindings. Spring can be configured either by an XML configuration file or directly in Java, whereas PicoContainer requires a Java binding (although the PicoExtras project does provide XML configuration support). I am rapidly coming to the conclusion that XML configuration files are becoming overused (and as someone has recently noted, all of these different configuration files are almost becoming new languages in their own right), although which approach is better is very much a matter of personal taste. Given that you may require multiple configurations (say, one for development, another for release), an XML-based system may be preferable, if only for configuration management issues.</P>
<P>Both are fairly "light" frameworks — they work well with other frameworks and have the added advantage of not tying you to them. PicoContainer is by far the smaller of the two; it sticks to the job of being an IoC framework and doesn't provide many supporting classes for working with external products like Hibernate. It is also worth noting that Spring is not just an IoC framework: it also provides web application and AOP frameworks, as well as some general support classes, which adds significantly to the size of the library. Personally, I found Spring's web application framework very flexible. However, it does seem to require more in the way of configuration than a framework such as Struts, and yet doesn't have as rich a set of supporting classes. In addition, the AOP features are still being developed, and you may not find it as fully featured as "pure" AOP frameworks such as AspectWerkz or AspectJ.</P>
<P>If you are going to use the additional supporting classes provided by Spring, then you'll find it a good choice. If, however, you are happy to implement these yourself (or rely on external projects to provide them) then Pico's small footprint might be a deciding factor. Both support Constructor Injection IoC, but only Spring supports Setter Injection -- if you prefer setter injection to constructor injection, then Spring is the obvious choice.</P>
<H2 id=Conclusion>Conclusion</H2>
<P>Hopefully, I have shown that by using IoC in your application that you can end up with neater, more flexible code. Both Spring and PicoContainer can be easily introduced into existing projects as part of ongoing refactoring work, and their introduction can further aid future refactoring work. Those adopting IoC from project inception will find their application code has better defined inter-component relationships, and will be more flexible and easier to test.</P>
<P><EM><A href="http://today.java.net/pub/au/85">Sam Newman</A> is a Java programmer. Check out his blog at <A href="http://www.magpiebrain.com/">magpiebrain.com</A>.</EM></P>
<DIV class=pad3x0>
<TABLE cellSpacing=0 cellPadding=0 width="100%" bgColor=#000000 border=0>
<TBODY>
<TR>
<TD><IMG height=1 alt=" " src="http://today.java.net/im/a.gif" width=1 border=0></TD></TR></TBODY></TABLE></DIV><!--  end content  --><IMG height=1 alt=" " src="http://today.java.net/images/trans.gif" width=490><BR>
<P>View all <A href="http://today.java.net/pub/q/articles">java.net Articles</A>.</P><A name=thread></A>
<DIV class=feedback>
<DIV class=rbox>
<DIV class=rboxtop>
<DIV></DIV></DIV>
<DIV class=rbcontent><B>Does IoC make code clearer or more resilient?</B><BR>
<DIV class=clear></DIV>
<DIV class=tb_left><A href="http://today.java.net/cs/user/create/cs_msg?x-lr=cs_disc/1030&amp;x-lr2=a/73&amp;page="><IMG height=20 alt="Post Comment" src="http://today.java.net/images/button_post.gif" width=118 vspace=4 border=0></A> </DIV><!--  rbcontent & rbox closed in cs_disc/thread_header.view  -->
<DIV class=tb_right><A href="http://today.java.net/pub/a/today/2004/02/10/ioc.html?page=last&amp;x-maxdepth=0#thread"><IMG title="Display main threads only" alt="Full Threads" hspace=6 src="http://today.java.net/images/button_main_threads.gif" vspace=4 border=0></A> <A href="http://today.java.net/pub/a/today/2004/02/10/ioc.html?page=last&amp;x-order=date#thread"><IMG title="Sort oldest posts first" alt="Oldest First" src="http://today.java.net/images/button_old.gif" vspace=4 border=0></A> </DIV>
<DIV class=clear></DIV><!--  closing divs from a/print.view, et al  --></DIV>
<DIV class=rboxbot>
<DIV></DIV></DIV></DIV>
<P>Showing messages 1 through 70 of 70. </P>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL>
<LI><A name=7260></A><B>A new IoC engine: JICE</B><BR>2004-11-02 00:11:43&nbsp;yakuzuki [<A title="Reply to this message" href="http://today.java.net/cs/user/create/cs_msg?x-lr=cs_msg/7260&amp;x-lr2=a/73">Reply</A> | <A href="http://today.java.net/cs/user/view/cs_msg/7260">View</A>] <BR><BR>Has anyone heard of JICE?<BR><BR>It is a fresh XML-based configuration tool for Java which seems to support IoC as well. The XML format of JICE is more flexible than the one in Spring, for example.<BR><BR>JICE:<BR>http://jicengine.sourceforge.net </LI></UL>
<UL><!--  Trackback   --></UL>
<UL>
<LI><A name=2958></A><B>IOC article by Martin Fowler</B><BR>2004-02-20 04:03:31&nbsp;jamesthecat [<A title="Reply to this message" href="http://today.java.net/cs/user/create/cs_msg?x-lr=cs_msg/2958&amp;x-lr2=a/73">Reply</A> | <A href="http://today.java.net/cs/user/view/cs_msg/2958">View</A>] <BR><BR>http://www.martinfowler.com/articles/injection.html 
<UL>
<LI><A name=2959></A><B>IOC article by Martin Fowler</B><BR>2004-02-20 06:02:37&nbsp;samnewman [<A title="Reply to this message" href="http://today.java.net/cs/user/create/cs_msg?x-lr=cs_msg/2959&amp;x-lr2=a/73">Reply</A> | <A href="http://today.java.net/cs/user/view/cs_msg/2959">View</A>] <BR><BR>I saw the article - in fact I reference and link to it in the text. </LI></UL></LI></UL>
<UL>
<LI><A name=2799></A><B>deferred relations setup</B><BR>2004-02-11 08:35:35&nbsp;ygmarchi [<A title="Reply to this message" href="http://today.java.net/cs/user/create/cs_msg?x-lr=cs_msg/2799&amp;x-lr2=a/73">Reply</A> | <A href="http://today.java.net/cs/user/view/cs_msg/2799">View</A>] <BR><BR>Inversion of control, or as sometimes called, dependency injection, is about, in my opinion, deferring the relations setup between objects.<BR><BR>When one designs the model of an application, one usually comes up with interfaces and abstract classes on which relations are defined.<BR><BR>At runtime this relations are represented with references from a class instance to another class instance. So the problem appears of where and when instanciate the actual implementations and setup the references.<BR><BR>In my opinion IoC is about this. And so IoC must be a corner stone of every component enviroment.<BR><BR>So, we have here a management and configuration problem. Relations setup must be done through configuration and management. <BR><BR>That's why one is pointed toward jmx. And not by chance jmx in jdk1.5 has a relation services.<BR><BR>Is this the way? And how? 
<UL>
<LI><A name=2802></A><B>deferred relations setup</B><BR>2004-02-11 09:45:16&nbsp;samnewman [<A title="Reply to this message" href="http://today.java.net/cs/user/create/cs_msg?x-lr=cs_msg/2802&amp;x-lr2=a/73">Reply</A> | <A href="http://today.java.net/cs/user/view/cs_msg/2802">View</A>] <BR><BR>I do not think it is about deferred setup, although this can be achived using IoC. At its heart it is about a component saying "I need this" and being given it. IoC can also be used for lifecycle control - a component says "I have a lifecycle" and the IoC framework can then manipulate it accordingly.<BR>JMX is certainly a kind of IoC container, however it is kind of a hybrid type 1/type 2 container. Some interfaces need implementing, other operations are carried out using introspection of the classes. Some people are keeping their components (read: JMX beans) generic, and are then using a pure IoC container to wrap the component and present it as a JMX bean to the JMX server. In that way you can work with the JMX servers out there but keep your code nice and clean. </LI></UL></LI></UL>
<UL><!--  Trackback   --></UL>
<UL><!--  Trackback   --></UL>
<UL>
<LI><A name=2790></A><B>Interfaces don't need to change...</B><BR>2004-02-10 10:28:44&nbsp;jcarreira [<A title="Reply to this message" href="http://today.java.net/cs/user/create/cs_msg?x-lr=cs_msg/2790&amp;x-lr2=a/73">Reply</A> | <A href="http://today.java.net/cs/user/view/cs_msg/2790">View</A>] <BR><BR>You wrote:<BR><BR>
<BLOCKQUOTE><BR>Another disadvantage is that Spring requires getters and setters for its dependency resolution. You have to expose properties that you might perhaps not otherwise expose, potentially breaking data encapsulation rules and, at best, making a class' interface more complex than is needed.<BR></BLOCKQUOTE><BR><BR>This is not entirely accurate. Your component Interface does not need to change. It can be purely the business methods your component provides. Your implementation class, however, can have these getters and setters as purely an implementation detail. </LI></UL>
<UL>
<LI><A name=2788></A><B>Some comments</B><BR>2004-02-10 08:00:02&nbsp;mparaz [<A title="Reply to this message" href="http://today.java.net/cs/user/create/cs_msg?x-lr=cs_msg/2788&amp;x-lr2=a/73">Reply</A> | <A href="http://today.java.net/cs/user/view/cs_msg/2788">View</A>] <BR><BR>My comments here:<BR>http://migs.paraz.com/wordpress/index.php?p=94<BR><BR>(What's the trackback URL for java.net articles?) </LI></UL>
<UL>
<LI><A name=2787></A><B>Small footprint</B><BR>2004-02-10 07:37:16&nbsp;colins [<A title="Reply to this message" href="http://today.java.net/cs/user/create/cs_msg?x-lr=cs_msg/2787&amp;x-lr2=a/73">Reply</A> | <A href="http://today.java.net/cs/user/view/cs_msg/2787">View</A>] <BR><BR>Sam,<BR><BR>W/regards to your statement &lt;&lt;&lt; If you are going to use the additional supporting classes provided by Spring, then you'll find it a good choice. If, however, you are happy to implement these yourself (or rely on external projects to provide them) then Pico's small footprint might be a deciding factor &gt;&gt;&gt;, keep in mind that the Spring distro comes with jars containing different levels of functionality. If all you need is the BeanFactory support, there is a spring jar with that code, which is not significantly larger that Pico with XML config support... For a slightly larger footprint, you can use the Spring version which adds ApplicationContext support (for AOP and related functionality). As such, I would make decisions on using Spring vs. Pico on other aspects than footprint size...<BR><BR>Also, note that Spring 1.0RC1, due out in a few days, plays around with the packaging variations compared to the current 1.0M4. It doesn't however change anything w/regards to what I said in my note above. 
<UL>
<LI><A name=2789></A><B>Small footprint</B><BR>2004-02-10 08:04:47&nbsp;samnewman [<A title="Reply to this message" href="http://today.java.net/cs/user/create/cs_msg?x-lr=cs_msg/2789&amp;x-lr2=a/73">Reply</A> | <A href="http://today.java.net/cs/user/view/cs_msg/2789">View</A>] <BR><BR>Thanks for the clarification. One of the problems with this piece was the pace of change wrt Pico and Spring. I tried to make it as accurate as possible, but I was only using the latest packaged JAR's rather than the bleeding edge CVS versions. Since I finished the finally draft even more things have changed - I may well do a complete rewrite in a few months once we have a Spring 1.0 and a PicoContaoner/NanoConainer 1.0 to look at! </LI></UL></LI></UL>
<UL>
<LI><A name=2785></A><B>Avalon, IoC, and other fun</B><BR>2004-02-10 07:08:33&nbsp;jaaron [<A title="Reply to this message" href="http://today.java.net/cs/user/create/cs_msg?x-lr=cs_msg/2785&amp;x-lr2=a/73">Reply</A> | <A href="http://today.java.net/cs/user/view/cs_msg/2785">View</A>] <BR><BR>Wow, there's sure been a plethera of IoC articles going around. I don't completely agree with your analysis of Avalon (though being an avalon developer, I may be somewhat biased). There are advantages and disadavantages to each approach.<BR><BR>I would also like to point out that IoC means a lot more than just dependency management. It's a principle which covers many design patterns, dependency injection being simply one. For more information, see some of the links below:<BR><BR>http://www.jadetower.org/muses/archives/000020.html<BR>http://www.jroller.com/page/lsd/20040122#ioc_dependency_management<BR>http://www.betaversion.org/~stefano/linotype/news/38/<BR>http://www.jadetower.org/spire/mutuals/<BR>http://avalon.apache.org 
<UL>
<LI><A name=2786></A><B>re: Avalon, IoC, and other fun</B><BR>2004-02-10 07:15:12&nbsp;samnewman [<A title="Reply to this message" href="http://today.java.net/cs/user/create/cs_msg?x-lr=cs_msg/2786&amp;x-lr2=a/73">Reply</A> | <A href="http://today.java.net/cs/user/view/cs_msg/2786">View</A>] <BR><BR>The gist of why I prefer picoContainer or Spring over Avalon is purely because I dislike coupling my application code to supporting frameworks. I do appreciate that IoC is also used for lifecycle management and configuration control, however the underlying principle remains the same - don't call us, we'll call you. I will be doing and article looking at one of the IoC containers in more depth to explore some of these other uses - when I find time! </LI></UL></LI></UL></DIV><img src ="http://www.cnitblog.com/rukas/aggbug/4607.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/rukas/" target="_blank">Rukas - Oh, My Blog!</a> 2005-11-17 14:34 <a href="http://www.cnitblog.com/rukas/archive/2005/11/17/4607.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>