After reading the official doc of Spring, I got this impression:
"Spring, specifically its IoC container, suits better for apps that requires only one instance of most classes".
For example we have an online shopping app. Its business logic is divided into
Order process
Payment process
and encapsulating these two parts into classes is for better code organisation rather than for implementing any functionalities, and Spring makes it easier to inject the same instance to whichever object needs it, to avoid frequent and redundant new.
However, in a Mario-like game, we might have a class Coin that requires hundreds of individual instances, and hence Spring can't be applied in this case ('cause I think #qualifier makes more mess than the good part brought by IoC).
Is the above correct?
You're correct in thinking that you wouldn't inject an object that only applies in a narrow scope.
I could see objects with Request scope that are not Singleton. Spring has supported that from the beginning.
Method scope variables should not be under Spring's control. There's nothing wrong with calling new.
You should understand Spring better before you make judgements about its efficacy.
Related
I'm starting to develop website that use the spring framework.I have three controller.There are newCustomerController,editCustomerController and deleteCustomerController.These controllers are mapped with view that use for create update and delete, but I create only customer.
So, I would like to know.Is it appropriate to declare the controllers like this.
Thank
The answer to this question is subjective and maybe more a topic for https://softwareengineering.stackexchange.com/. However, there is something very spring related about it that I would like to comment.
There are a few principles that attempt at guiding developers of how to strike a good balance when thinking about designing the classes. One of those is the Single responsibility principle.
In object-oriented programming, the single responsibility principle
states that every class should have a single responsibility, and that
responsibility should be entirely encapsulated by the class. All its
services should be narrowly aligned with that responsibility
A catchier explanation is
A class or module should have one, and only one, reason to change.
However, its still often hard to reason about it properly.
Nevertheless, Spring gives you means for it (think of this statement as a poetic freedom of interpretation). Embrace constructor based dependency injection. There are quite a few reasons why you should consider constructor based dependency injection, but the part relevent to your question is adressed in the quote from the blog
An often faced argument I get is: “Constructors just get too verbose
if I have 6 or 7 dependencies. With fields only, this is fine”.
Awesome, you’ve effectively worked around a clear indicator that the
code you write is doing way too much. An increase in the number of
dependencies a type has should hurt, as it makes you think about
whether you should split up the component into multiple ones.
In other words, if you stick to constructor based injection, and your constructor turns a bit ugly, the class is most likely doing too much and you should consider redesigning.
The same works the other way around, if your operations are a part of the logical whole (like CRUD operations), and they use the same dependencies (now "measurable" by the count and the type of the injected deps) with no clear ideas of what can cause the operations to evolve independently of each other, than no reason to split to separate classes/components.
It should be better if you define one controller for Customer class and in that class you should have all methods related to customer operations (edit,delete,create and read).
I'm currently "updating" my development knowledge especially on TDD principles by reading books, articles on the web and watching videos. Something that pops up everywhere is the warning, not to use global state variables as they make the system fragile and less easy to test and since singletons are not much better or rather the same, not to use those either.
Now I'm wondering: Can I actually be consistent about this?
What about a cache, that the application uses so it doesn't have to look up frequently used database objects again and again? I NEED a single instance of that cache to be passed around, otherwise what would be the point?
Another example are DAOs or as we call them providers. They do nothing but provide JPA database access for us but otherwise have no state. So why not make them singleton?
And controllers in the web frontend? All they do is react to requests - again with no internal state.
Wouldn't it waste a lot of performance instantiating the latter two again and again? I'm sure there are a few more examples where this applies.
Maybe it's okay to use singletons, as long as they don't have any member variables except for finals?
And even if they have member variables but all of them are injected into them, it should be save to use them, as any object, singleton or not, can modify injected objects so it really doesn't make any difference.
I'm a bit confused about this whole "avoid singletons" business, I'm not even sure I fully understand the risks involved. But most of all I'd like to hear thoughts on the above examples, as those are the most common places in our application where we use singletons.
Thanks!
btw: we're using springs dependency injection, so how to do it is not my question, rather why avoid it and where it is okay.
The issue with Singletons is not so much the Singleton design pattern per se as their being overused under the covers as stateful global God objects all over applications.
That way of using them has 2 major drawbacks :
Dependencies on singletons are hidden dependencies, and objects are tightly coupled to them, which hampers discoverability, maintainability and testability of the code.
Objects depend on singletons they don't have any idea which state they're in. The order in which a singleton's behaviors are used here and there starts to become important, and you start seeing "MySingleton.Initialize()"s all over the place, which is dangerous and defeats the whole purpose of having a single instance.
Only singletons that trump these pitfalls are IMO worth considering - that means stateless, immutable objects that somehow get injected into their consumers and can be replaced with other instances with the same contract.
Other than that, Singleton-ification is most often premature optimization applied on the wrong objects.
This blog post pretty much sums it up : http://blogs.msdn.com/b/scottdensmore/archive/2004/05/25/140827.aspx
You are absolutely correct -- there are cases when single instance is needed. However "avoid singletons" business does not tell that they are not needed. In my understanding it states that singleton behavior should be added by Dependency Container, not by static instance.
That would allow you to mock it in your unittests while having only one instance in production. you may find this link useful: Object Scopes in Ninject
The problem with singletons and global variables is that we need them but that most programming languages offer only one "global" context.
Imagine that you could do this:
Global g1 = new Global();
g1.run( ... some code ... );
Global g2 = new Global();
g2.run( ... some code ... );
When the code is run by g2, none of the singletons and globals from the run of g1 are visible. This is actually what we want: A efficient way to say "okay, I'm done with the globals and stuff, get rid of them".
The solution is a factory which can build all your singletons and globals for you and put them into the code in the right place. Then you can create new instances of this factory (along with new singletons and globals) in your tests as you need it.
This is what "dependency injection" is all about. Here is a short introduction.
I googled and read some good answers/posts on IOC and do understand the overall concept. I have an existing framework (not very well designed) and TDD is an after thought to write some NUNIT test fixtures. Can I use IOC on an existing code base with out changing the existing code base? Or IOC is used when we are designing application from scratch?
I use this technique for converting legacy code to dependency injected beauty:
If I create just one object for a class, make it a field and create it in the constructor.
If I create more than one object, make a factory for that object and create the factory in the constructor.
Put interfaces on the objects (I like the "IDoThisForYou" style as it allows me to understand the roles of classes easily, but whatever works for you).
Cascade the constructors - make one constructor new up the objects and pass them into the other by the interface.
Now you can mock and DI the interfaces in your tests. The actual cascade is simple enough that you can get by with inspection. Eventually you'll get to the point where you can use a container and then you'll delete the first constructor; this is an easy first step towards that.
(Don't mock out domain objects with heavy data - it's not worth it.)
Good luck!
It doesn't have to be from scratch, but obviously you would structure things to allow IOC to be pretty painless if you did,
But it can be patched in.... depending on how decoupled your system is, that may or may not be a big job. Essentially its an object creation pattern, so it only effect the points of creation.... if thats done willy nilly all over the place, then it will take a bit of clean up.
I'd start with getting unit tests in place first. Worry about IOC as a second concern, its not actually needed to do TDD
Warning acronym overload approaching!!! I'm doing TDD and DDD with an MVP passive view pattern and DI. I'm finding myself adding dependency after dependency to the constructor of my presenter class as I write each new test. Most are domain objects. I'm using factories for dependency injection though I will likely be moving to an IoC container eventually.
When using constructor injection (as apposed to property injection) its easy to see where your dependencies are. A large number of dependencies is usually an indicator that a class has too much responsibility but in the case of a presenter, I fail to see how to avoid this.
I've thought of wrapping all the domain objects into a single "Domain" class which would act as a middle man but I have this gut feeling that I'd only be moving the problem instead of fixing it.
Am I missing something or is this unavoidable?
Often a large number of arguments to a method (constructor, function, etc) is a code smell. It can be hard to understand what all the arguments are. This is especially the case if you have large numbers of arguments of the same type. It is very easy for them to get confused which can introduce subtle bugs.
The refactoring is called "Introduce Parameter Object". Whether that's really a domain object or not, it is basically a data transfer object that minimizes the number of parameters passed to a method and gives them a bit more context.
I only use DI on the Constructor if I need something to be there from the start. Otherwise I use properties and have lazy loading for the other items. For TDD/DI as long as you can inject the item when you need it you don't need to add it to your constructor.
I recommend always following the Law of Demeter and not following the DI myth of everything needs to be in the constructor. Misko Hevery (Agile Coach at Google) describes it well on his blog http://misko.hevery.com/2008/10/21/dependency-injection-myth-reference-passing/
Having a Layer Supertype might not be a bad idea, but I think your code smell might be indicating something else. Geofflane mentioned the refactor pattern, Introduce Parameter Object. While it's a good pattern for this sort of problem, I'm not entirely sure it's the way to go for this situation.
Question: Why are you passing in Domain Model objects to the constructor?
There is such a thing as having too much abstraction. If there's one solid layer of code you should be able to trust, it's your Domain Model. You don't need to reference 3 IEntity objects when you're dealing with Customer, Vendor, and Product classes if those are part of your basic Domain Model and you don't necessarily need polymorphism.
My advice: Pass in application and domain services. Trust your Domain Model.
EDIT:
Re-reading the problem when it's not horribly late at night, I realize your "Domain class" is already the Introduce Parameter Object refactoring and not, in fact, a Layer Supertype, as I thought at 3AM.
I also realize that perhaps you need to reference the Model objects in the application code, outside the Presenter. Perhaps you're doing some initial setup of your Model objects before passing them in to the Presenter. If this is the case, your "Domain class" idea might be best. If there is some initial setup, when moving to an IoC, you'll want to look at something like Factory Support in Castle Windsor. (Other IoC containers have similar concepts.)
I am building an application using Spring MVC. I want to make certain changes to my Model for every Controller in the application. In particular, I want to insert certain extra data into the model which will be present for all pages of the application.
I could do this several ways: just add the data at the end of every Controller, use a subclass of Model that adds my extra data, use a subclass of ModelAndView that wraps my Model, use a subclass of VelocityView that wraps the Model before using it... I'm sure there are other options.
But I have an "elegance" constraint: I don't want to write code in each and every Controller, I want this behavior defined in one-and-only-one place. Ideally, it would be controlled by my IOC bean config file.
Does anyone have a recommendation of how to achieve this elegantly?
Aspects are a good approach, but Spring MVC makes it even easier -- you can define a HandlerInterceptor that will be called before or after every time a request is handled. In the HandlerInterceptor postHandle method (in your class that implements the HandlerInterceptor interface) you can add your data to the ModelAndView. You define which handlers should be intercepted in your config file.
You could take a look at using Aspects. Spring even has an AOP extension that you could use.
In brief an aspect would allow you to define code once that would then get "woven" into your classes either when you compile the classes or when they are loaded by the classloader. It's relatively advanced stuff and isn't the most intuitive thing for new programmers to pick up, but it's intended to solve exactly the problem you're referring to.
I might be wrong, but I suspect that you may have described your requirements incorrectly.
You seem to be saying 'I want certain data to be added to my model, for all controllers'.
I suspect that you mean 'I want certain data to be available for all views'.
If my suspicions are correct, then adding the data to you model is polluting your model and violating the single responsibility principle. This is especially true if the same data is to be added to several models. Be careful that you are not just using your model as a convenient 'carrier' of the data - where the data doesn't really have anything to do with the model.
Admittedly, I'm not completely familiar with the Spring MVC way of doing things, but a more detailed example of what you're trying to achieve may allow for a more informed discussion.