I am reading Head First Design pattern and just stuck on the Hollywood Principle. Earlier I read about Inversion of Control and what I understood was, it's a design principle (some also call it pattern) through which conventional flow of program changes from "Higher level module calling Lower level module" to "Lower level module calling Higher level module" (generally through abstractions), so we can have very low dependency on specific low-level module and changing low-level modules does not have any impact on our higher level or near to business modules.
But I got confused when the author said the following line regarding the Hollywood principle:-
On page 296
With the Hollywood Principle, we allow low-level components
to hook themselves into a system, but the high-level
components determine when they are needed, and how. In
other words, the high-level components give the low-level
components a “don’t call us, we’ll call you” treatment.
In the last line, it is said that The high-level components give the low-level
components a “don’t call us, we’ll call you” treatment. This means our high-level components are actually calling low-level components and hence
this seems to break the Inversion of control principle and also Dependency Inversion principle.
Please clarify on this.
The seeming contradiction is cleared up if we focus on a different part of the Dependency Inversion Principle:
A. High level modules should not depend on low level modules. Both should depend upon abstractions.
B. Abstractions should not depend upon details. Details should depend upon abstractions.
That adds some context that clears up the potential confusion created by this statement:
The high-level components give the low-level components a “don’t call us, we’ll call you” treatment.
The high-level components don't directly deal with the low-level components at all. They deal with abstractions that represent the purpose or function of the low-level components.
So it doesn't "break" the Dependency Inversion Principle. Rather, it just needs to be understood in harmony with that principle. They are two different principles, so we could apply one and break the other. But if components communicate with each other as represented by abstractions then we can apply both.
They could have added that clarification into the sentence in question, but it would have made it wordier and more confusing.
FWIW I often find the terms "high level" and "low level" confusing because we don't tend to use them except when discussing the Dependency Inversion Principle. Whether a component is "high level" or "low level" the recommendation is to depend on abstractions. In other words, depend on abstractions. We can apply the principle without classifying components as high level or low level.
When we design software we implement two things API and Framework.
An API publish some endpoint so that caller uses those endpoints to get some useful information, so the caller doesn't have any action point to take, only endpoints and outputs.
The framework takes the strategy or business implementation from the caller and calls it when required.
In Hollywood Principle, we can feed our strategy or business implementation, denoting the framework implementation, which calls the fed strategy when required.
Inversion of control and Dependency Injection is to remove dependencies of an application. This makes the system more decoupled and maintainable.
If you go back to old computer programming days, program flow used to run in its own control.
if you analyze the program flow closely, it’s sequential. The program is in control of himself. Inversion of the control means the program delegates control to someone else who will drive the flow.
class Customer {
public function getCustomers() {
$conn = new MySQLConnection();
return $conn->getCustomers();
}
public function iocCustomers(MySQLConnection $conn) {
return $conn->getCustomers();
}
}
In the case of getCustomers(), we are creating the Database object inside Customer classes function - deeply coupled. Whenever the Customer object is created, the MySQLConnection object also will be created, which is not required.
If you consider the iocCustomers(), when we call the function we are passing the Database object as well. Here the Customer class is not concerned about the database till it need the data, it will use it when it required. Like, you no need to be in Hollywood to get a chance, when you needed they will call you, like, MySQLConnection object is injected to the function where it required by the class Customer.
Here two things are happening.
Customer class no need to worry/know about who provides the data. In other words, the client/calling class Customer doesn't have control over the data. [SRP in SOLID principles]
The connection object gets the control over the data and it can decide from which database(MySQL or SQLite) it need to provide data. If we create the object MySQLConnection in the getCustomers(), it will not get the flexibility to switch. This is called Inversion of Control. Taking the control from the caller to the class who generates the data.
Note: In the case of second function there are some advantages.
We can pass an interface called DBConnectionContract to iocCustomers() instead of MySQLConnection. So that we can pass any database object(MySQL, Sqlite, Postgres) which implements DBConnectionContract interface. This will help us to switch the database to one another with minimum modifications.
Modifications can be like below:
interface DBConnectionContract {}
class MySQLConnection implements DBConnectionContract {}
class SQLiteConnection implements DBConnectionContract {}
class Customer {
public function iocCustomers(DBConnectionContract $conn) {}
}
Another advantage is related to Unit testing. To the iocCustomers() we can pass mock database object while unit testing. Because to do the unit test of a function we need to make the environment needed for that function to execute.
The Hollywood Principle is not at odds with the Inversion of Control, although it can be programmed ignoring it.
In the book the Coffee example (I guess one page later, I have another edition) sub-classes two methods that get called via the Hollywood Principle. If the sub-classes just overwrites some abstract methods from the base class it does not really uses the Inversion of Control.
However since the called sub-class can adjust members of the base class it can take control that way. In the Q and A in my book one page earlier it explains a bit in the question: What are hooks really supposed to be used for. I will try to explain.
Say if you have a base class with an unsorted list and a call to print() the list. If you have a sub-class which via a hook can be called to overwrite print() that sub-class might decide to first sort the actual list of the base class and than call other functions if needed. In this way the low level function can take over control from the high level function.
IoC is sometimes referred to as the Hollywood Principle. They are the same... but, like all idiomatic expressions, it is always subject to semantics. The principle of controlling low-level dependencies from higher level abstractions is not "a pattern", it is a principle. It is also not exemplified well by associating that principle solely with sub-classing, though there it does most naturally exist.
More commonly it is accomplished through composition/aggregation by holding a reference to some Interface or abstract type in a low-level object and injecting dependencies into that class. It has no control or responsibility for what it receives, it only knows how to process it.
In other words, it (low-level) must wait by the phone, rather than call for its next screening, audition? what ever they call that in Hollywood.
Related
I'm taking further intro java classes at the moment and this is how the class briefly defined this:
Cohesion: Aim for high cohesion, in this case cohesion meaning that a single module is tightly focused on its task.
Coupling: Aim for low coupling, in this case coupling meaning the level of extent in how intertwined two or more modules are.
How does one determine the level of cohesiveness as well as coupling?
For instance, some of my methods call other methods that are in the same class. This means that the method that calls other methods are dependent on the other methods in order for the "calling" method to finish its code block. Does this mean that I have low cohesion and high coupling on the methods of the same class? Or do these concepts refer more to different classes and different packages?
Cohesion and decoupling are important at all levels: each line of code should have a specific meaning and purpose, each method should have a specific meaning and purpose, each class should have a specific meaning and purpose, each package should have a specific meaning and purpose, each code repository should have a specific meaning and purpose.
This doesn't mean that a method shouldn't call another method, that a class shouldn't use another class, etc.; rather, it means that ideally, you should be able to read and understand a method without reading every other method it calls, to read and understand a class without reading every other class it uses, etc.
That said, we expect greater cohesion and decoupling for larger units: classes need to be much more cohesive and much less tightly coupled than methods do, for example, because assuming your classes are a reasonable size, you can much more easily go back and forth between methods than between classes when you're reading and maintaining the code.
There are metrics for cohesion / coupling; see https://softwareengineering.stackexchange.com/questions/151004/are-there-metrics-for-cohesion-and-coupling.
So the way to "determine" the level of cohesion / coupling is to implement a tool that measures the respective metrics. (Or find an existing tool that does this. For example, Sonar.)
How does one determine the threshold for the level of cohesion and/or coupling?
I assume you mean ... how do you decide when you will call values of the respective metrics "unacceptable" in your codebase.
Basically, that is up to you to decide. I would do it by looking at examples where the tool is reporting a "bad" value, and decide how bad I thought it really was. Alternatively, stick with the default thresholds in the tool that you are using.
I might be wrong, but here is just my humble input.
Cohesion is often time mentioned along with coupling, but they have an inverse relationship. High cohesion == low coupling.
Let me quote you
Aim for high cohesion, in this case cohesion meaning that a single
module is tightly focused on its task.
So it just means like that. Something that only does one thing and does it well. For example, a method to save an entity to the database should only focus on how to save that entity to the database, it should not worry about the correctness of that entity (Do all of that entity instance attributes pass all the database schema validations, in which case this validation should be handled maybe by an interceptor).
Coupling refers to the degree to which 2 modules depend on each other, the least the better because it promotes maintenance, and re-usability, etc. Often time, low coupling is achieved by using events, we have event emitters and event consumers, and they don't have to know anything about each other. Even emitters just fire-and-forget, and the consumers will take of the events when the system delivers the events to them.
Situation: Suppose we're designing the UI of Windows 9 using Java API. We need to build up 3 classes main, BuildInWindow and ApplicationWindow.
main - the window for rendering the system UI (i.e. the start botton & wallpaper page)
BuildInWindow- windows for rendering buildt-in apps (e.g. IE)
ApplicationWindow- windows for rendering apps from third party (e.g. eclipse)
all of them have to implement 3 Java API interfaces, WindowFocusListener, WindowListener and WindowStateListener and have the methods onExit() and onCrushing().
onExit() performs when the system/built-in app/ third-party app is shut down normally
onCrushing() captures any system/application crush and send system state back to server
This is the original design:
http://i.stack.imgur.com/JAJiY.png
I have some ideas of how to design it in a OO manner, but I am not sure if that's the right way. Here's my thoughts:
Create an abstract class with method onExit() and onCrushing(). Since the code of onExit()would vary from 3 classes, it should be an abstract method & onCrushing()would be same fo all classes, so it would be an concrete method
tHE MAIN WINdow should use singleton design to ensure user only create one instance of main.
Use the facade design to save the trouble of implementing 3 interfaces to three classes
My question is I don't really understand facade design, so I am not sure if it can be applied in this case. Also I am not really sure if onExit() would be different for 3 classes and onCrushing() would perform the same function.
I tried my best to explain the question clearly...if you don't understand free free to comment. Thank you very much!
I've left some questions in a comment linked to your question but here's some guidance for you:
You shouldn't create an abstract class on the basis of both BuildInwindow and ApplicationWindow both having to have methods #onExit and #onCrushing if they are not to share any implementation. Abstract classes are most useful where there is a common implementation. An interface containing these methods would be sufficient. That said, your two windows may share other functionality and, if so, it could be shared through a common superclass (abstract if it relies on subclass implementation detail). You may find the Template Method pattern useful for managing the overall window mechanism with specific tailoring for different window types. You may also find the Factory Method means of instance creation (for your window classes) will help separate the object creation and set-up from the creation mechanism.
A single shared instance would seem sensible and a singleton would serve this purpose (so long as you're able to handle termination, etc). Alternatively, your application may just launch a single Main instance - you may even just hide the constructor through package access to ensure no others are created.
The facade pattern just serves to simplify a complex interface. It mainly does this by rolling calls to collaborating instances together under a single (coarser) interface. This wouldn't normally be a done to hide which interfaces a class supports. Indeed, publishing which interfaces a class extends is important to API users. You could roll the three interfaces into a single interface for "convenience" but I think this is unnecessary. If you do settle on a common superclass then that would "extend" the three interfaces (if all subclasses were expected to support them). It may also implement some default implementation of these interfaces (again, watch access modifiers to ensure those you intend to be can be overridden while others may be final).
Edit: Guidance
You just have to identify the classes and relationships:
I suggest you just grab some paper and draw. You already have your nouns and verbs (you can otherwise go noun and verb spotting to identify classes and methods on them).
So, why not draw a simple diagram containing all the info (A, B, C, Main, etc) and draw the relationships between them. This is your start point. You may have some confusion when working out how Main links to the window classes (given there are two kinds). Just write a note on it and move on to clarify the rest of the picture.
Next, refine your diagram to start moving common features into a single place (abstraction). You know this exists with regards to your interfaces and the methods you suggest but you may need to decide which (if any) have any common functionality. Then decide if interfaces satisfies your needs (methods are common but implementations are different) or if the implementation itself is the same and so a parent superclass may be useful (this addresses abstraction [who is responsible for what], encapsulation [individual implementations at the appropriate level] and polymorphism [which classes support common methods]). Note that, even if you settle on an superclass, you'd be wise to back it with an interface (it makes introduction of sibling or replacement classes easier in time - think maintenance).
Next, work on the issues you found. Has your draft design clarified any of them? For instance, your Main needs to know about its windows but - what type are they? So, has any of your refinement made this clearer?
Do any patterns present themselves? for this you need to already have a feel for design patterns I'm afraid so buy and absorb the GoF Design Patterns book. It'll put you in good stead for spotting patterns as you go. I'd also recommend reading this specific book before taking on any others as it's technology agnostic (and some other books arebloated with tech-specific workarounds). Perhaps study the two patterns I pointed out and see if they fit your requirement.
On the whole though, your ideas seem to be going in the right direction.
Here's the scenario. As a creator of publicly licensed, open source APIs, my group has created a Java-based web user interface framework (so what else is new?). To keep things nice and organized as one should in Java, we have used packages with naming convention
org.mygroup.myframework.x, with the x being things like components, validators, converters, utilities, and so on (again, what else is new?).
Now, somewhere in class org.mygroup.myframework.foo.Bar is a method void doStuff() that I need to perform logic specific to my framework, and I need to be able to call it from a few other places in my framework, for example org.mygroup.myframework.far.Boo. Given that Boo is neither a subclass of Bar nor in the exact same package, the method doStuff() must be declared public to be callable by Boo.
However, my framework exists as a tool to allow other developers to create simpler more elegant R.I.A.s for their clients. But if com.yourcompany.yourapplication.YourComponent calls doStuff(), it could have unexpected and undesirable consequences. I would
prefer that this never be allowed to happen. Note that Bar contains other methods that are genuinely public.
In an ivory tower world, we would re-write the Java language and insert a tokenized analogue to default access, that would allow any class in a package structure of our choice to access my method, maybe looking similar to:
[org.mygroup.myframework.*] void doStuff() { .... }
where the wildcard would mean any class whose package begins with org.mygroup.myframework can call, but no one else.
Given that this world does not exist, what other good options might we have?
Note that this is motivated by a real-life scenario; names have been changed to protect the guilty. There exists a real framework where peppered throughout its Javadoc one will find public methods commented as "THIS METHOD IS INTERNAL TO MYFRAMEWORK AND NOT
PART OF ITS PUBLIC API. DO NOT CALL!!!!!!" A little research shows these methods are called from elsewhere within the framework.
In truth, I am a developer using the framework in question. Although our application is deployed and is a success, my team experienced so many challenges that we want to convince our bosses to never use this framework again. We want to do this in a well thought out presentation of the poor design decisions made by the framework's developers, and not just as a rant. This issue would be one (of several) of our points, but we just can't put a finger on how we might have done it differently. There has already been some lively discussion here at my workplace, so I wondered what the rest of the world would think.
Update: No offense to the two answerers so far, but I think you've missed the mark, or I didn't express it well. Either way allow me to try to illuminate things. Put as simply as I can, how should the framework's developers have refactored the following. Note this is a really rough example.
package org.mygroup.myframework.foo;
public class Bar {
/** Adds a Bar component to application UI */
public boolean addComponentHTML() {
// Code that adds the HTML for a Bar component to a UI screen
// returns true if successful
// I need users of my framework to be able to call this method, so
// they can actually add a Bar component to their application's UI
}
/** Not really public, do not call */
public void doStuff() {
// Code that performs internal logic to my framework
// If other users call it, Really Bad Things could happen!
// But I need it to be public so org.mygroup.myframework.far.Boo can call
}
}
Another update: So I just learned that C# has the "internal" access modifier. So perhaps a better way to have phrased this question might have been, "How to simulate/ emulate internal access in Java?" Nevertheless, I am not in search of new answers. Our boss ultimately agreed with the concerns mentioned above
You get closest to the answer when you mention the documentation problem. The real issue isn't that you can't "protect" your internal methods; rather, it is that the internal methods pollute your documentation and introduce the risk that a client module may call an internal method by mistake.
Of course, even if you did have fine grained permissions, you still aren't going to be able to prevent a client module from calling internal methods---the jvm doesn't protect against reflection based calls to private methods anyway.
The approach I use is to define an interface for each problematic class, and have the class implement it. The interface can be documented solely in terms of client modules, while the implementing class can provide what internal documentation you desire. You don't even have to include the implementation javadoc in your distribution bundle if you don't want to, but either way the boundary is clearly demarcated.
As long as you ensure that at runtime only one implementation is loaded per documentation-interface, a modern jvm will guarantee you don't suffer any performance penalty for using it; and, you can load harness/stub versions during testing for an added bonus.
The only idea that I can think in order to supply this missing "Framework level access modifier" is CDI and a better design.
If you have to use a method from very different classes and packages in various (but few) situations THERE WILL BE certainly a way to redesign those classes in order to make those methods "private" and inacessible.
There is no support in Java language for such kind of access level (you would like something like "internal" with namespace). You can only restrict access to package level (or the known inheritance public-protected-private model).
From my experience, you can use Eclipse convention:
create a package called "internal" that all class hierarchy (including sub-packages) of this package will be considered as non-API code and could be changed anytime with no guarantee for your users. In that non-API code, use public methods whenever you like. Since it is only a convention and it is not enforced by the JVM or Java compiler, you cannot prevent users from using the code, but at least let them know that these classes were not meant to be used by 3rd parties.
By the way, in Eclipse platform source code, there is a complex plugin model that enforces you not to use internal code of other plugins by implementing custom class loader for each plugin that prevents loading classes that should be "internal" in these plugins.
Interfaces and dynamic proxies are sometimes used to make sure you only expose methods that you do want to expose.
However that comes at a fairly hefty performance cost, if your methods are called very often.
Using the #Deprecated annotation might also be an option, although it won't stop external users invoking your "framework private" methods, they can't say they hadn't been warned.
In general I don't think you should worry about your users deliberately shooting themselves in the foot too much, so long as you made it clear to them that they shouldn't use something.
I've been programming in Java for a few courses in the University and I have the following question:
Is it methodologically accepted that every class should implement an interface? Is it considered bad practice not to do so? Can you describe a situation where it's not a good idea to use interfaces?
Edit: Personally, I like the notion of using Interfaces for everything as a methodology and habit, even if it's not clearly beneficial. Eclipse automatically created a class file with all the methods, so it doesn't waste any time anyway.
You don't need to create an interface if you are not going to use it.
Typically you need an interface when:
Your program will provide several implementations for your component. For example, a default implementation which is part of your code, and a mock implementation which is used in a JUnit test. Some tools automate creating a mock implementation, like for instance EasyMock.
You want to use dependency injection for this class, with a framework such as Spring or the JBoss Micro-Container. In this case it is a good idea to specify the dependencies from one class with other classes using an interface.
Following the YAGNI principle a class should implement an interface if you really need it. Otherwise what do you gain from it?
Edit: Interfaces provide a sort of abstraction. They are particularly useful if you want to interchange between different implementations(many classes implementing the same interface). If it is just a single class, then there is no gain.
No, it's not necessary for every class to implement an interface. Use interfaces only if they make your code cleaner and easier to write.
If your program has no current need for to have more than 1 implementation for a given class, then you don't need an interface. For example, in a simple chess program I wrote, I only need 1 type of Board object. A chess board is a chess board is a chess board. Making a Board interface and implementing that would have just required more code to write and maintain.
It's so easy to switch to an interface if you eventually need it.
Every class does implement an interface (i.e. contract) insofar as it provides a non-private API. Whether you should choose to represent the interface separately as a Java interface depends on whether the implementation is "a concept that varies".
If you are absolutely certain that there is only one reasonable implementation then there is no need for an interface. Otherwise an interface will allow you to change the implementation without changing client code.
Some people will shout "YAGNI", assuming that you have complete control over changing the code should you discover a new requirement later on. Other people will be justly afraid that they will need to change the unchangeable - a published API.
If you don't implement an interface (and use some kind of factory for object creation) then certain kinds of changes will force you to break the Open-Closed Principle. In some situations this is commercially acceptable, in others it isn't.
Can you describe a situation where it's not a good idea to use interfaces?
In some languages (e.g. C++, C#, but not Java) you can get a performance benefit if your class contains no virtual methods.
In small programs, or applications without published APIs, then you might see a small cost to maintaining separate interfaces.
If you see a significant increase in complexity due to separating interface and implementation then you are probably not using interfaces as contracts. Interfaces reduce complexity. From the consumer's perspective, components become commodities that fulfil the terms of a contract instead of entities that have sophisticated implementation details in their own right.
Creating an interface for every class is unnecessary. Some commonly cited reasons include mocking (unneeded with modern mocking frameworks like Mockito) and for dependency injection (e.g. Spring, also unneeded in modern implementations).
Create an interface if you need one, especially to formally document public interfaces. There are a couple of nifty edge cases (e.g. marker interfaces).
For what it's worth, on a recent project we used interfaces for everything (both DI and mocking were cited as reasons) and it turned out to be a complete waste and added a lot of complexity - it was just as easy to add an interface when actually needed to mock something out in the rare cases it was needed. In the end, I'm sure someone will wind up going in and deleting all of the extraneous interfaces some weekend.
I do notice that C programmers first moving to Java tend to like lots of interfaces ("it's like headers"). The current version of Eclipse supports this, by allowing control-click navigation to generate a pop-up asking for interface or implementation.
To answer the OP's question in a very blunt way: no, not all classes need to implement an interface. Like for all design questions, this boils down to one's best judgment. Here are a few rule of thumbs I normally follow:
Purely functional objects probably
don't need to (e.g. Pattern,
CharMatcher – even though the
latter does implement Predicate, it
is secondary to its core function)
Pure data holders probably don't need
to (e.g. LogRecord, Locale)
If you can
envision a different implementation
of a given functionality (say, in-memory
Cache vs. disk-based Cache), try to
isolate the functionality into an interface. But don't go too far trying to predict the future either.
For testing purposes, it's
very convenient when classes that do
I/O or start threads are easily mockable, so
that users don't pay a penalty when
running their tests.
There's nothing
worse than a interface that leaks its
underlying implementation. Pay attention where you draw the line and make sure your interface's Javadoc is neutral in that way. If it's not, you probably don't need an interface.
Generally
speaking, it is preferable for
classes meant for public consumption
outside your package/project to
implement interfaces so that your
users are less coupled to your
implementation du jour.
Note that you can probably find counter-examples for each of the bullets in that list. Interfaces are very powerful, so they need to be used and created with care, especially if you're providing external APIs (watch this video to convince yourself). If you're too quick in putting an interface in front of everything, you'll probably end up leaking your single implementation, and you are only making things more complicated for the people following you. If you don't use them enough, you might end up with a codebase that is equally hard to maintain because everything is statically bound and very hard to change. The non-exhaustive list above is where I try to draw the line.
I've found that it is beneficial to define the public methods of a class in a corresponding interface and when defining references to other classes strictly use an interface reference. This allows for easy inversion of control, and it also facilitates unit testing with mocking and stubbing. It also gives you the liberty of replacing the implementation with some other class that implements that interface, so if you are into TDD it may make things easier (or more contrived if you are a critic of TDD)
Interfaces are the way to get an polymorphism. So if You have only one implementation, one class of particularly type, You don't need an interface.
A good way of learning what are considered good methodologies, especially when it comes to code structure design, is to look at freely available code. With Java, the obvious example is to take a look at the JDK system libraries.
You will find many examples of classes that do not implement any interfaces, or that are meant to be used directly, such as java.util.StringTokenizer.
If you use Service Provider Interface pattern in your application interfaces are harder to extend than abstract classes. If you add method to interface, all service providers must be rewritten. But if you add non-abstract method to the abstract class, none of the service providers must be rewritten.
Interfaces also make programming harder if only small part of the interface methods usually have meaningfull implementation.
When I design a new system from scratch I use a component oriented approach, each component (10 or more classes) provide an interface, this allows me (sometimes) to reuse them.
When designing a Tool (Or a simple system) I think this must not necessarily be an extensible framework I introduce interfaces when I need a second implementation as an option.
I saw some products which exposed nearly every functionality by an interface, it took simply too much time to understand unnecessary complexity.
An interface is like a contract between a service provider (server) and the user of such a service (client).
If we are developing a Webservice and we are exposing the rest routes
via controller classes, controller classes can implement interfaces
and those interfaces act as the agreement between web service and the
other applications which use this web service.
Java interfaces like Serializable, Clonnable and Remote
used to indicate something to compiler or JVM.When JVM sees a class
that implement these interfaces, it performs some operation on the to
support Serialization, cloning or Remote Method Invocation. If your class needs these features, then you will have to implement these interfaces.
Using Interface is about to make your application framework resilient to change. Since as I mentioned here (Multiple Inheritance Debates II: according to Stroustrup) multiple inheritance was cancelled in java and c# which I regret, one should always use Interface because you never know what the future will be.
I have tried to understand AOP, Dependency Injection and Inversion of Control SPRING related concepts but I am having hard time understanding it.
Can anyone explain this in simple English ?
I understand your confusion and it took me some time to understand how these concepts were related together. So here is my (somehow personal) explanation of all this:
1. Inversion of Control
Inversion of control is a design principle rather generic that refers to the decoupling of the specification of a behavior from when it is actually executed. Compare for instance,
myDependency.doThis();
with
myDependency.onEventX += doThis();
In the latter, there is no direct invocation which is more flexible. In its general form, inversion of control relates to the observer pattern, events, or callbacks.
2. Dependency inversion
Dependency inversion is another design principle. Roughly speaking, it says that higher-level abstraction should not depend directly on lower-level abstractions; this results indeed in a design where higher-level abstraction can not be reused without the lower-level abstractions.
class MyHighLevelClass {
MyLowLevelClass dep = new MyLowLeverClass();
}
class App {
void main() { new HighLevelClass().doStuff(); }
}
Here, MyHighLevelClass can not compile without access to MyLowLevelClass. To break this coupling, we need to abstract the low level class with an interface, and remove the direct instantiation.
class MyLowLevelClass implements MyUsefulAbstraction { ... }
class MyHighLevelClass {
MyUsefulAbstraction dep;
MyHighLevelClass( MyUsefulAbstraction dep ) {
this.dep = dep;
}
}
class App {
void main() { new HighLevelClass( new LowLevelClass() ).doStuff(); }
}
Note that you don't need anything special like a container to enforce dependency inversion, which is a principle. A good reading is The Dependency Inversion Principle by Uncle Bob.
3. Dependency injection
Now comes dependency injection. To me dependency injection = IoC + dependency inversion:
dependencies are provided externally so we enforce the dependency inversion principle
the container sets the dependencies (not us) so we speak of inversion of control
In the example I provided above, dependency injection can be done if a container is used to instantiate objects and automatically inject the dependency in the constructor (we speak then frequently of DI container):
class App {
void main() { DI.getHighLevelObject().doStuff(); }
}
Note that there are various form of injections. Note also that under this perspective, setter injection can be seen as a form of callback -- the DI container creates the object then calls back the setter. The flow of control is effectively inverted.
4. AOP
Strictly speaking, AOP has little to do with the 3 previous points. The seminal paper on AOP is very generic and present the idea of weaving various sources together (possibly expressed with different languages) to produce a working software.
I won't expand more on AOP. What is important here, is that dependency injection and AOP do effectively plays nicely together because it makes the weaving very easy. If an IoC container and dependency injection is used to abstract away the instantiation of objects, the IoC container can easily be used to weave the aspects before injecting the dependencies. This would otherwise requires a special compilation or a special ClassLoader.
Hope this helps.
Dependency injection was explained very well in How to explain dependency injection to a 5-year-old?:
When you go and get things out of the
refrigerator for yourself, you can
cause problems. You might leave the
door open, you might get something
Mommy or Daddy doesn't want you to
have. You might even be looking for
something we don't even have or which
has expired.
What you should be doing is stating a
need, "I need something to drink with
lunch," and then we will make sure you
have something when you sit down to
eat.
AOP - Aspect Oriented Programming - basically means that the source you write is modified with other code, based on rules located ELSEWHERE. This means that you can e.g. say "as the first line of every method I want a 'log.debug("entering method()")' in a central place and each and every method you compile with that rule in place will then have that line included. The "aspect" is the name of looking on code in other ways than simply from first source line to last.
Inversion of Control basically means that you do not have a central piece of code controlling everything (like a giant switch in main()) but have a lot of pieces of code that "somehow" get called. The subject is discussed at Wikipedia: http://en.wikipedia.org/wiki/Inversion_of_control
These three are all different concepts, but they all work well together, and so Spring apps often make use of all of it at once. I'll give you an example.
Let's say that we have a web application that can do many different things. We could construct this application in many ways, but one way is to create a class that is in charge of doing each of these things. We need to invoke and create these classes from somewhere. One option is to have a big main class that creates one of each of these services, opens up a socket, and passes calls to these services as they come in. Unfortunately, we've gone and created ourselves a god class, which has way too much logic and knows way too much about how everything in our program works. If we change anything about our program, we're probably going to need to modify this class.
Also, it's difficult to test. We can't test any class in isolation if it runs around instantiating and invoking the other classes directly. Unit tests become much, much harder to write.
A way to get around this is to use inversion of control. We say "okay, these are service classes. Who instatiates them? Not me." Usually, each one defines an interface, like LoginService or BillingService. There might be more than one implementation of that interface, but your app doesn't care. It just knows that it can ask for a certain kind of a service or a service with a certain name, and it'll get something nice back.
Dependency injection allows us to wire all of our litle pieces together. Classes have accessible fields, constructor arguments, or setter methods that are references to the other components that they'll need to access. That makes unit testing much easier. You can create the object under test, throw a mock or stub dependency at it, and then test that the object behaved correctly in isolation.
Now, our real application is a complex jumble of pieces that all need to be wired together just so. There are many ways to accomplish this, including allowing the application to make guesses ("this class wants a UserService, there is exactly one other class I'm in charge of that implements UserService") or by carefully explaining how they wire together in XML or Java. Spring, at its core, is a service that takes care of wiring these classes together.
Now we get to AOP. Let us say that we have all of these classes that are wired to each other in elaborate ways. There are some cross-cutting concerns that we might want to describe in very generic ways. For instance, perhaps you'd like to start a database transaction whenever any service is invoked, and commit that transaction so long as the service doesn't throw an exception. It turns out that Spring is in a unique position to perform such a task. Spring can create proxy classes on the fly that implement whatever interface your classes need, and it can wrap your class in its proxy. Now, IoC and dependency injection certainly aren't necessary to do aspect-oriented programming, but it's an extremely convenient way to accomplish it.
The difference between Dependency Injection and Inversion of Control is explained very well in
http://martinfowler.com/articles/dipInTheWild.html
("You mean Dependency Inversion, Right?" section)
The summary:
DI is about how one object acquires a dependency. When a dependency
is provided externally, then the system is using DI.
IoC is about who initiates the call. If your code initiates a call,
it is not IoC, if the container/system/library calls back into code
that you provided it, is it IoC.
let me tell you some word about AOP, hope it make it simplier to understand.
The very base principle of AOP is finding common tasks/aspects which returns in
many places in the code and dont belong to the concerete business of the code. For example
write to log on every entrance to any function, or when an object is created wrapp it, or send email to admin when calling to specific function.
So instead of the programmers will handle these non businuss aspect we take it from them and
we manage these aspects behond the scene.
That all the basic of AOP on 1 leg....
A simple comparison from Spring in Action:
Whereas DI helps you decouple your application
objects from each other, AOP helps you decouple cross-cutting concerns from the
objects that they affect.