We have many DAOs in an existing project (currently with no interfaces, but that can change). Rather than wiring a Spring-managed bean for each DAO class and injecting them into the service layer, we have a DAO "factory" of sorts that looks like this:
public class DAOFactory {
private static DAOFactory daoFac;
static{
daoFac = new DAOFactory();
}
private DAOFactory(){}
public static DAOFactory getInstance(){
return daoFac;
}
public MyDAO1 getMyDAO1(){
return new MyDAO1();
}
public MyDAO2 getMyDAO2(){
return new MyDAO2();
}
...
(Note that MyDAO1 and MyDAO2 are concrete classes)
This allows us to easily add/call DAO methods within the Service layer, without having to 1.) add a DAO interface as a property to the service class 2.) wire the DAO implementation into service method via configuration. (And we sometimes use multiple DAOs in one service class).
DAOFactory.getInstance().getMyDAO1().doSomething();
This strategy has worked for us so far (we haven't had much need for switching implementations), but I'm wondering if there is a better method if we were able to start new? I looked at autowiring the DAOs as beans, but I'd still need to create properties in each service class to represent those DAOs being used. And in a large project, I'm hesitant to start auto-wiring beans anyway - we need to provide visibility for all developers.
It feels like I'm flip-flopping between a.) being tightly-coupled to an implementation, but less code/config overhead and b.) being loosely coupled to interfaces, but requiring plenty of code/configuration overhead.
Is there a better way I'm missing? Something in-between? Opinions welcomed.
I will have all the DAO s as Spring managed components and inject them into services for loose coupling. Why do you think autowiring beans is bad in a big project.?
Just annotate each DAO class with #Component
and replace MyDao mydao = factory.getmyDao() with
#Autowired
MyDao myDao;
I dont see much coding/configuration overhead with it.
I've taken a couple of different approaches so far with my projects, and haven't really settled on what's "best." And there may not be a "best" but perhaps a "best for your needs."
First, I went with a base service class.
public abstract BaseService {
#Autowired FooDAO fooDao;
#Autowired BarDAO barDao;
. . .
. . .
protected getFooDAO() {
return this.fooDao;
}
}
Then in my service classes, I can write simply
Foo foo = getFooDAO().uniqueById(id);
This works, and it keeps my services tidy from all the autowiring and accessor classes for the dao instance variables. Problem is, I've now got a copy of this base class in each of my services, which frankly, meh, not that big of a deal. But it also sort of produces a code smell because it's not using composition over inheritance where, in essence, a reason for DI is to encourage composition.
A coworker suggested a factory such as yours, and called it ServiceProvider. We autowire this into our services.
#Component
public class ServiceProvider {
#Autowired FooDAO fooDao;
public FooDAO getFooDAO() {
return this.fooDao;
}
. . .
// yadda yadda
}
Then we have something like what you have:
Foo foo = getServiceProvider().getFooDAO().uniqueById(id);
And that's pretty darned ugly and really doesn't lend itself to clarity. So, we've dabbled with using just the instance of the provider, and naming it something short and sweet like sp. Then we get
Foo foo = this.sp.getFooDAO().uniqueById(id);
And again, it works. And it's probably a better design. And we only autowire the DAOs in one place, rather than into each Service, even though that's not really much of a problem either way. But it makes me feel better even though Me Feeling Better isn't a project requirement (but don't cha think it oughta be?)
I've been thinking we'd combine the two. We'd change BaseService to autowire the ServiceProvider, and then wrap the ugly calls.
public abstract BaseService {
#Autowired ServiceProvider serviceProvider;
protected getFooDAO() {
return this.serviceProvider.getFooDAO();
}
protected getBarDAO() {
return this.serviceProvider.getBarDAO();
}
}
Makes for nicer shorthand in my services, doesn't require me to autowire each DAO into each service which just gets clunky, in my opinion, but also doesn't have a copy of all those references in each service which, you know, is an utterly ridiculous concern.
The problem that I'm left with is stepping through code in the debugger. Stepping in and out of each of those getWhateverDAO() calls is tedious, and adding a possible step through getServiceProvider() doesn't help things either.
But that's where I'm at with this issue. Frankly, I think I spend so much time thinking about this because it's a great way of avoiding all the truly hard problems our application poses.
Good question.
I think that is is very pity that you started to use DAOFactory. Spring is a super flexible factory, so I really do not understand why do you need other one. Autowiring in spring has a lot of advantages and do not reqire interfaces, so you can easily switch to using spring to access DAOs. IMHO it does not reduce but improves the visibility for other developers.
Moreover if you are thinking about refactoring of DAO layer take a look on GenericDAO from google code: http://code.google.com/p/hibernate-generic-dao/
I had a very good experience with this library. It saves your time. You actually do not need many DAOs. You need exactly one DAO. You obviously can wrap the generic DAO from google code and add your application specific terminology and functionality. But do not add entity specific code there. The entity specific code should be at service layer. No more fragile HQL, no coupling with hibernate if you are using Hibernate criteria API. This library supports both Hibernate and JPA and its API is very simple and strong.
If you use too many DAOs in 1 service you should think about to split 1 service into more lower lever (fine grained) services
If you don't want to annotate your DAO classes or have configuration annotations like #Value polluting them, I see two options:
1. Create a #Configuration with DAO #Beans
#Configuration
public class DaoConfiguration {
#Value("${db.name}")
private String dbName;
#Value("${foo.table}")
private String fooTable;
#Value("${bar.table}")
private String barTable;
#Bean
private FooDao fooDao() {
return new FooDao(dbName, fooTable);
}
#Bean
private BarDao barDao() {
return new BarDao(dbName, barTable);
}
}
Then create an #Autowired field for the DAO you need:
#Autowired
private FooDao fooDao;
2. Create a DAO factory #Component
Useful if you need to do some cleanup when the DAOs are destroyed.
#Component
public class DaoFactory {
#Value("${db.name}")
private String dbName;
#Value("${foo.table}")
private String fooTable;
#Value("${bar.table}")
private String barTable;
private FooDao fooDao;
private BarDao barDao;
#PostConstruct
public void init() {
fooDao = new FooDao(dbName, fooTable);
barDao = new BarDao(dbName, barTable);
}
#PreDestroy
public void destroy() {
try {
fooDao.close();
} catch (Exception e) {
log.error("Failed to clean up FooDao", e);
}
try {
barDao.close();
} catch (Exception e) {
log.error("Failed to clean up BarDao", e);
}
}
public FooDao fooDao() {
return fooDao;
}
public BarDao barDao() {
return barDao;
}
}
Then create an #Autowired field for the factory in the classes you need DAOs:
#Autowired
private DaoFactory daoFactory;
And use it as:
daoFactory.barDao().findAll();
Related
I have a set of classes that all extend from my ReportConfig abstract class. Once created, they are currently immutable and not managed by Spring.
However, I'm finding that sometimes I need to perform an action that requires the use of a particular service, but I'm struggling to find the best way to inject these services into my non-managed ReportConfig instances. See below:
#Service
public class ReportService() {
#Autowired
private SchemaService schemaService;
#Autowired
private ExecutionService executionService;
#Autowired
private ReportConfigFactory reportConfigFactory;
public Result executeReport(ReportRequest request) {
ReportConfig reportConfig = reportConfigFactory.getReportConfig(request);
reportConfig.validateAgainstSchema(schemaService.getSchemaForDataset(reportConfig.getDataset()));
executionService.execute(reportConfig.getQuery());
}
Now I have no issue with the dataService.execute() line, but I do have an issue with the reportConfig.validateAgainstSchema() line and I feel an alternative would be something like:
reportConfig.validateAgainstSchema(schemaService);
But I feel that maybe represents tight coupling.
I'm imagining there's also a way to inject SchemaService straight into ReportConfigs, but not sure if this defeats the object...
Keen to hear your thoughts.
Thanks
From what I understood from the current design of your application given in question and I am guessing the functionality and thinking about an alternative design,
reportConfig.validateAgainstSchema(schemaService.getSchemaForDataset(reportConfig.getDataset()));
What you can think of is, if reportconfig is the right place to do validateAgainstSchema if not think about changing it.
Is schemaService the right place to do validateAgainstSchema(I think not) if that is also not the right place to do it, then create a SchemaValidator or something similar.
This is something that I could think of with the information you have given me.
If validateAgainstSchema is not overridden by any child classes of ReportConfig and possibility is very rare then you should definitely think of moving it to a different class. The reason I say this is that if the schema changes then you should not have to change the reportConfig class
If its overridden and there are multiple implementations then one way would be to use a validator factory to get the validator and do validation. I don't even know if this suits your use case but this is all I can come up with the information in the question.
Hope it helps you in someway.
Why do you have to inject services into config classes ? Could you just not pass what config need directly ?
Alternatively if you must you can use setter based injection to autowire the service into ReportConfig abstract class or you can use method injection.
Something like
Setter based Injection
public abstract class ReportConfig {
protected SchemaService schemaService;
protected final setSchemaService(SchemaService schemaService) {
this.schemaService = schemaService;
}
}
Method Injection
public class BeanUtility implements ApplicationContextAware {
private ApplicationContext applicationContext;
protected SchemaService getSchemaService() {
return this.applicationContext.getBean("schemaService", SchemaService.class);
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
Your logical is a bit strange.
The correct is another service receive ReportConfig. You doing the opposite.
You can work with bean inside another object not spring managed but you need to recreate it.
YourService container = (YourService) context.getBean("yourService");
container.load();
But it's wrong. The right way is change your logical. Create a generic service with rules to specific reportConfig. Autowire your service and pass your report config and work with that specific data inside the service. (sry my english)
You could think of wrapping your services in static holder classes
public class SchemaServiceHolder {
private static final SchemaServiceHolder INSTANCE = new SchemaServiceHolder();
#Autowired
private SchemaService schemaService;
private SchemaServiceHolder () {
}
public static SchemaServiceHolder instance() {
return INSTANCE;
}
public SchemaService getSchemaService() {
return schemaService;
}
}
You then need to create a bean of this type so Spring can inject the service into the singleton SchemaServiceHolder.INSTANCE
#Configuration
public class AppConfig {
#Bean
public SchemaServiceHolder schemaServiceHolder () {
return SchemaServiceHolder.instance();
}
}
And finally, your objects can reference the schemaService statically
SchemaService schemaService = SchemaServiceHolder.instance().getSchemaService();
The simplest solution in your case to " also a way to inject SchemaService straight into ReportConfigs, but not sure if this defeats the object..." is to pass the object to the factory.
So basically this line reportConfigFactory.getReportConfig(request);
would be changed to this
reportConfigFactory.getReportConfig(request, schemaService);
It is totally fine to pass the spring managed bean in a constructor of a non managed spring class. In your case is not the constructor directly but to a factory method.
I have quite some JpaRepository extended Repository interfaces due to the design of the database.
In order to construct a simple object i.e Person I have to make method calls to about 4 - 5 repositories just because the data is spread like that throughout the database. Something like this (pardon for pseudocode):
#Service
public class PersonConstructService {
public PersonConstructService(Repository repository,
RepositoryTwo repositoryTwo,
RepositoryThree repositoryThree) {
public Person constructPerson() {
person
.add(GetDataFromRepositoryOne())
.add(GetDataFromRepositoryTwo())
.add(GetDataFromRepositoryThree());
return person;
}
private SomeDataTypeReturnedOne GetDataFromRepositoryOne() {
repository.doSomething();
}
private SomeDataTypeReturnedTwo GetDataFromRepositoryTwo() {
repositoryTwo.doSomething();
}
private SomeDataTypeReturnedThree GetDataFromRepositoryThree() {
repositoryThree.doSomething();
}
}
}
PersonConstructService class uses all these interfaces just to construct a simple Person object. I am calling these repositories from different methods inside the PersonConstructService class. I have thought about spreading this class into multiple classes, but I do not think this is correct.
Instead I would like to use a repositoryService which would include all the repositories listed necessary for creation of a Person object. Is that a good approach? Is it possible in Spring?
The reason I am asking is that sometimes the count of injected Services into a class is about 7-8. This is definitely not good.
I do not think you can / shoudl create a meta-repository like abstraction. Repositories have a well defined meaning, conceptually, they are CRUD services (and a bit more sometimes :-)) for your Hibernate/JPA/Datastore entities. And I guess this is enough for them. Anything more is confusing.
Now what I would propose is a "smart" way of building your "Person" objects that is automa(g)tically aware of any new services that contribute to the meaning of the Person object.
The crux of it would be that :
you could have your Repositories implement a given Interface, say PersonDataProvider, which would have a method, say public PersonPart contributeDataToPersonBuidler(PersonBuilder).
You would make your #Service implement Spring's BeanFactoryPostProcessor interface, allowing you to inspect the container for all such PersonDataProvider instances, and inject them to your service (see accepted answer at How to collect and inject all beans of a given type in Spring XML configuration)
Your #Service implementation would then be to ask all the PersonDataProviders in turn to ask them to contribute their data.
I could expand a bit, but this seems to me like the way to go.
One could argue that this is not clean (it makes your Repositories aware of "something" that happens at the service layer, and they should not have to), and one could work around that, but it's simpler to expose the gist of the solution that way.
EDIT : since this post was first written, I came aware that Spring can auto-detect and inject all beans of a certain type, without the need of PostProcessors. See the accepted answer here : Autowire reference beans into list by type
I see it as a quite reasonable and practical data aggregation on Service layer.
It's perfectly achievable in Spring. If you have access to repositories code you can name them all like:
#Repository("repoOne")
public class RepositoryOne {
#Repository("repoTwo")
public class RepositoryTwo {
And inject them into the aggregation service as necessary:
#Service
public class MultipleRepoService {
#Autowired
#Qualifier("repoOne")
private RepositoryOne repositoryOne;
#Autowired
#Qualifier("repoTwo")
private RepositoryTwo repositoryTwo;
public void doMultipleBusiness() {
repositoryOne.one();
repositoryTwo.two();
}
}
In fact, you even don't need to name and Qualify them if they are different classes, but if they are in hierarchy or have the same interface...
Also, you can inject directly to constructing method if autowiring is not a case:
public void construct(#Qualifier("repoOne")RepositoryOne repoOne,
#Qualifier("repoTwo")RepositoryTwo repoTwo) {
repoOne.one();
repoTwo.two();
}
My project manager wants me to use DAO/DTO objects to access and retrieve data from database. Project is written in Java SE without using any framework or ORM. His arguments is to make code more testable and to improve code design. Does it make sense?
How about initializing DAO object? Should it be initialized when the instance of class having DAO field is created:
private PersonDao personDao = new PersonDaoImpl();
or rather initialized when it is necessary?
public class A {
private PersonDao person;
public List<Person> findAll() {
person = new PersonDaoImpl();
return person.getAll();
}
}
It allows to mock this interface easily, but is it right to the DAO pattern usage convention?
The Data Access Object is basically an object or an interface that provides access to an underlying database or any other persistence storage.
That definition from: http://en.wikipedia.org/wiki/Data_access_object
Maybe a simple example can help you understand the concept:
Let's say we have an entity to represent an employee:
public class Employee {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
The employee entities will be persisted into a corresponding Employee table in a database. A simple DAO interface to handle the database operation required to manipulate an employee entity will be like:
interface EmployeeDAO {
List<Employee> findAll();
List<Employee> findById();
List<Employee> findByName();
boolean insertEmployee(Employee employee);
boolean updateEmployee(Employee employee);
boolean deleteEmployee(Employee employee);
}
Next we have to provide a concrete implementation for that interface to deal with SQL server, and another to deal with flat files, etc...
Hope that helps
To maximimze the benefits of testability and separation of concerns you should introduce the concept of Inversion of Control (IoC). When applying IoC to the management of object lifecycles the term Dependency Injection is used. What this means is that your class A should be completely agnostic of which implementation is instantiated when.
In order to achieve this you need an extra component to bootstrap your application and inject all classes with the correct implementations.
You could set up your dependency-receiving class like this (setter injection, you can also use constructors)
public class PersonServiceImpl implements PersonService {
private PersonDao personDao;
public List<Person> findAll() {
return personDao.getAll();
}
public setPersonDaoA(PersonDao personDao) {
this.personDao = personDao;
}
}
And a component to do the dependency injection:
public class ApplicationContext {
private PersonService personService;
private PersonDao personDao ;
public PersonService getPersonService() {
if (personService == null) {
personService= new PersonServiceImpl();
personService.setPersonDao(getPersonDao());
}
return personService;
}
public PersonDao getPersonDao() {
if (personDao == null) {
personDao = new PersonDaoIml();
}
return personDao ;
}
}
Then application startup would involve this:
public class Main {
public static void main(String[] args) {
ApplicationContext ctx = new ApplicationContext();
PersonService personService = ctx.getPersonService();
personService.findAll();
}
}
As you can see, the ApplicationContext encapsulates knowlegde about:
which implementations to use
in which order to set a chain of dependencies
which dependencies are already instantiated or not
The PersonServiceImpl class is now completely testable and all concerns regarding object lifecycle management have been extracted from it.
In real life this if often done using a framework like Spring or CDI (which is becoming more and more popular recently). But in your situation, starting off with an approach like above might be a good first step. It will reap the immediate benefits mentioned by your project manager without incurring the overhead of introducing Spring, possibly changing your build too and having to learn how that works (e.g. with an XML context, source code context and/or annotations).
Introducing Spring at a later stage will be easy because all classes are already prepared for Dependency Injection. Just keep in mind that your factory (ApplicationContext in my example) should not take on any extra responsibilities like configuration management.
Also keep in mind that the above example of ApplicationContext is not a singleton. You yourself should make sure only one instance of it is created when your application starts, and all injections are handled by it. Creating duplicate instances could cause confusing bugs.
The DAO pattern is not an "enterprise" pattern. It's mostly seen in "enterprise" applications, but you can absolutely use in a an application written in SE only.
It's not because you're writing an SE application that you don't have to test, so indeed, your code will be more testable using the DAO pattern and IOC rather than using straight JDBC in your application.
The way you're implementing your class using the DAO is problematic because your class cannot be tested properly because of the tight coupling between your class A and your DAO implementation. You're better off using the IOC pattern as well with a framework like Guice or Dagger (both designed with SE in mind).
For a code example, look at slnowak's answer.
The way you are using it, it is still tightly coupled with your class A.
You should provide your DAO as a dependency, using constructor or setter. Probably the most preferable way is to use some kind of Inversion of Control (for example dependency injection framework).
Your class A should be something like:
public class A {
private PersonDao personDao;
// possibly an #Inject annotation
public A(PersonDao personDao) {
this.personDao = personDao;
}
public List<Person> findAll() {
return personDao.getAll();
}
}
And actually, I would consider it an antipattern this way. It depends on how you are about to use your class A.
If it contains different business logic - fine.
If it just dispatches a call to DAO (I don't like this name, maybe use Repository instead ;)) then it is just unnecessary layer of abstraction.
Another thing - you mentioned DTO. So a Person class is just a DTO in this case? Here we could have another antipattern. DTO is fine for example if you need to transform your business object(s) into something that is visible on the screen. Or to separate perstistence model from business model.
What I'm trying to say is: don't make a Person class just a data structure. Give it some behaviour.
Probably i'll get a lot of downvotes, but it's so confusing for me all this fact of whether use beans or not. Lets suppose this example
interface ICurrency {
String getSymbol();
}
public class CurrencyProcessor {
private ICurrency currency ;
public CurrencyProcessor(ICurrency currency) {
this.currency = currency;
}
public void doOperation(){
String symbol = currency.getSymbol();
System.out.println("Doing process with " + symbol + " currency");
// Some process...
}
}
So, to inject the ICurrency impl injection i think that i can do it by two ways:
Way 1: Without Spring beans
public class CurrencyOperator {
private ICurrency currency ;
private CurrencyProcessor processor;
public void operateDefault(){
currency = new USDollarCurrency();
processor = new CurrencyProcessor(currency)
this.processor.doOperation();
}
}
Where USDollarCurrency is an ICurrency interface implementation
Way 2: Using Spring beans
#ContextConfiguration(classes = CurrencyConfig.class)
public class CurrencyOperator {
#Autowired private ICurrency currency ;
#Autowired private CurrencyProcessor processor;
public void operateDefault(){
this.processor.doOperation();
}
}
#Configuration
public class CurrencyConfig {
#Bean
public CurrencyProcessor currencyProcessor() {
return new CurrencyProcessor(currency());
}
#Bean
public ICurrency currency() {
return new USDollarCurrency();
}
I really don't understand what would be the benefits of using Spring's beans. I read some things but what i most found was about the benefits of using DI, and as i understand, both ways are injecting the dependency that CurrencyProcessor require, what is changing is the way that i am creating and using objets, am i wrong? So in concrete, my questions are:
1. What are the benefits of using Beans at this case?
2. Why should i use Spring instead of doing it manually like first way?
3. Talking about performance, which of this cases is better?
Suppose you have 2 DAO classes one for Oracle, the seconde for MySQL, and both classes are implementing a DAO interface. You define an implementation as a bean in Spring configuration file. In the business class you have an attribut of type DAO, while in the spring configuration file you choose the real type wheather Oracle or MySQL to inject or using spring annotation #Autowired
This reduce coupling and it will be easy to move from Oracle to MySQL.
#Service
public class Business {
#Autowired
private Dao daoImpl;
//Business methods that invoks Dao methods
}
In the Spring configuration file (XML file) you use the following:
<bean id="daoImpl" class="app.com.MySQLDaoImpl OR app.com.OracleDaoImpl"/>
By just changing the class attribut of your bean you change the whole implementation, without any change in your business class ! Good luck.
Your example without Spring doesn't dependency injection!
With dependency injection, the actual implementation of the interface is determined outside the code itself in order to reduce the coupling!
You should be able to need another implementation (you could for example switch from one JMS client to another...).
To answer to your last question, using Spring is (a very little bit) less performant but much more flexible.
EDIT :
Spring is not the only tool that can be used for DI but it is the most popular and it contains a lot of features. Note that many Java standards also (such as JPA) use DI.
I am often confused by these three terms. These three look similar to me. Can someone please explain them to me clearly, with examples.
I have seen similar posts and don't understand completely.
Dependency Injection refers to the pattern of telling a class what its dependencies will be, rather than requiring the class to know where to find all of its dependencies.
So, for example, you go from this:
public class UserFetcher {
private final DbConnection conn =
new DbConnection("10.167.1.25", "username", "password");
public List<User> getUsers() {
return conn.fetch(...);
}
}
to something like this:
public class UserFetcher {
private final DbConnection conn;
public UserFetcher(DbConnection conn) {
this.conn = conn;
}
public List<User> getUsers() {
return conn.fetch(...);
}
}
This reduces coupling in the code, which is especially useful if you want to unit test UserFetcher. Now, instead of UserFetcher always running against a database found at 10.167.1.25, you can pass in a DbConnection to a test database. Or, even more useful in a fast test, you can pass in an implementation or subclass of DbConnection that doesn't even connect to a database, it just discards the requests!
However, this sort of primitive dependency injection makes wiring (providing an object with its dependencies) more difficult, because you've replaced accessing the dependency using a global variable (or a locally instantiated object) with passing the dependency around through the whole object graph.
Think of a case where UserFetcher is a dependency of AccountManager, which is a dependency of AdminConsole. Then AdminConsole needs to pass the DbConnection instance to AccountManager, and AccountManager needs to pass it to UserFetcher...even if neither AdminConsole nor AccountManager need to use the DbConnection directly!
An inversion of control container (Spring, Guice, etc) aims to make dependency injection easier by automatically wiring (providing) the dependencies. To do this, you tell your IoC container once how to provide an object (in Spring, this is called a bean) and whenever another object asks for that dependency, it will be provided by the container.
So our last example might look like this with Guice, if we used constructor injection:
public class UserFetcher {
private final DbConnection conn;
#Inject //or #Autowired for Spring
public UserFetcher(DbConnection conn) {
this.conn = conn;
}
public List<User> getUsers() {
return conn.fetch(...);
}
}
And we have to configure the IoC container. In Guice this is done via an implementation of Module; in Spring you configure an application context, often through XML.
public class MyGuiceModule extends AbstractModule {
#Override
public void configure() {
bind(DbConnection.class).toInstance(
new DbConnection("localhost", "username", "password"));
}
}
Now when UserFetcher is constructed by Guice or Spring, the DbConnection is automatically provided.
Guice has a really good Wiki article on the motivation behind dependency injection, and further using an IoC container. It's worth reading all the way through.
The strategy pattern is just a special case of dependency injection, where you inject logic instead of an object (even though in Java, the logic will be encapsulated in an object). It's a way of decoupling independent business logic.
For example, you might have code like this:
public Currency computeTotal(List<Product> products) {
Currency beforeTax = computeBeforeTax(products);
Currency afterTax = beforeTax.times(1.10);
}
But what if you wanted to extend this code to a new jurisdiction, with a different sales tax scheme? You could inject the logic to compute the tax, like this:
public interface TaxScheme {
public Currency applyTax(Currency beforeTax);
}
public class TenPercentTax implements TaxScheme {
public Currency applyTax(Currency beforeTax) {
return beforeTax.times(1.10);
}
}
public Currency computeTotal(List<Product> products, TaxScheme taxScheme) {
Currency beforeTax = computeBeforeTax(products);
Currency afterTax = taxScheme.applyTax(beforeTax);
return afterTax;
}
Inversion of control means that a runtime framework wires all components together (for example Spring). Dependency injection is a form of IoC (I don't know if another form of IoC exists) (see: http://en.wikipedia.org/wiki/Inversion_of_control).
Strategy pattern is a design pattern (defined by the GoF) where the algorithm can be replaced by another (see: http://en.wikipedia.org/wiki/Strategy_pattern). This is archived by provided several implementation of a same interface. When using an IoC like Spring, if you have several implementations of an interface, and if you can switch from an implementation to another by configuration, you are using the strategy pattern.
I also recommend reading the introduction chapter of Spring's documentation, which focuses on this issue: Introduction to Spring Framework
The first few paragraphs should do.
And this also links to: Inversion of Control Containers and the Dependency Injection pattern
Which also provides a motivational view of these very important core concepts.