Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Android Build a Simple Android App (retired 2014) Learning the Language Simple Refactoring

Paolo Scamardella
Paolo Scamardella
24,828 Points

Dependency Injection

I haven't gotten too far with these series of videos dealing with android development, so I don't know if this has been already covered or not in the future. I have a solid understanding of OOP, and I'm trying to learn android development and improve my OOP skills as well. While watching this video, I have noticed on line 14 in the MainActivity class that Ben wrote "private CrystalBall mCrystalBall = new CrystalBall();", and to me this means the MainActivity class is tightly coupled with the CrystallBall class. Wouldn't it be better to somehow pass the crystalball as a parameter? Either pass it to a method in the MainActivity or in the constructor(not sure if it is a good android practice to add a constructor to an activity since onCreate method "acts" like a constructor)

4 Answers

Let me see if I can elaborate.

Code abstraction is a strong part of object oriented programming. On one end of the spectrum, where you would have little code abstraction, all your code would be in the same file. Obviously, this wouldn't be very maintainable and making changes would require a lot of effort.

On the other end of the spectrum of code abstraction, everything is broken down into it's smaller components. The code would be factored out into classes which would focuse on as narrow a task as possible and would make use of design patterns. (see here for design patterns) This would make it easier to read and maintain your code, because everything has a place and is easier to test and find. And if the code is broken down into parts (abstracted) properly, the different parts would be loosely coupled and it becomes easier to change code in one place without affecting code in other classes. This last point is still desireable in android programming. But, as mentionned before, if you push this to the extreme, you can negatively impact your user experience due to the lack of memory resource on certain mobile devices. Abstraction tends to create more code and that increase in code will have to reside in a larger amount of memory to execute. Google seems to recommend using abstractions only if there is a clear benefit.

Programming to interfaces is an easy way to decouple your code in such a way that you can limit the impact of changes. No parameters in constructors required. For example, let's say I wanted to program to an interface to decouple your example. I would create an interface called CrystalBall that would only have method declarations (that is, just the method signatures and member variables). Then I would create a class called CrystalBallImpl (impl=implementation, it's a convention). This implementation would 'implement' the interface.

public interface CrystalBall {

     // no code blocks here, just declare and close with ;
    public String getAnswer();
}
public class CrystalBallImpl implements CrystalBall{

    public String getAnswer() {
        // The actual code that implements the behavior of the method
    }
}

Then in my MainActivity I would now call the object like this:

CrystalBall mCrystalBall = new CrystalBallImpl();

This allows you to swap the implementing class with any other class, as long as it respects the interface declaration by implementing the method public String getAnswer() as some point down the line. The only code you would have to change in MainActivity, is that one initialization of mCrystalBall to instantiate the new class. As long as the interface doesn't change, the code inside MainActivity will be isolated from any changes occuring inside the implementing classes. We haven't completely removed code dependency, but replaced it with a dependency on an interface, which is an improvement.

I hope this helps.

Excellent question. Normally, if I wanted to decouple my code a bit, I would program to interfaces and/or use some sort of dependency injection framework to assist me.

However, in my reading of Android documentation, I came accross an article on memory considerations for apps from this link.

Two sections caught my eye that might help shed some light on your question:

" Be careful with code abstractions

Often, developers use abstractions simply as a "good programming practice," because abstractions can improve code flexibility and maintenance. However, abstractions come at a significant cost: generally they require a fair amount more code that needs to be executed, requiring more time and more RAM for that code to be mapped into memory. So if your abstractions aren't supplying a significant benefit, you should avoid them."

" Avoid dependency injection frameworks

Using a dependency injection framework such as Guice or RoboGuice may be attractive because they can simplify the code you write and provide an adaptive environment that's useful for testing and other configuration changes. However, these frameworks tend to perform a lot of process initialization by scanning your code for annotations, which can require significant amounts of your code to be mapped into RAM even though you don't need it. These mapped pages are allocated into clean memory so Android can drop them, but that won't happen until the pages have been left in memory for a long period of time."

In short, dependency injection frameworks are not recommended and code abstraction should be kept to a minimum. From a memory point of view, it makes sense as some of the devices out there are extremely limited on resources.

I'd be interested to hear if anyone else has any feedback on this. I've programmed java applications at the enterprise level where memory is not as much of a limiting factor and where maintainability is more important. But developing for a mobile device is a different matter altogether.

Paolo Scamardella
Paolo Scamardella
24,828 Points

Thank you Shawn for your response! I did a quick google search on "program to interfaces", and I read some of the answers on stackoverflow. I need to keep reading on the subject and let it sink in. Fortunately, I do not use any kind of dependency injection framework, so I'm good there for now. So, if I understood correctly, I should use an interface to avoid classes to be tightly coupled between each other. If that is the case, in android development, I should create a method in the MainActivity that passes an interface as a parameter...is that correct? Also, what do you mean by "code abstraction should be kept to a minimum?"

Once again, Thanks for your answer

Paolo Scamardella
Paolo Scamardella
24,828 Points

Thank you so much Shawn! Your comment made my day! Easy to read and easy to understand. I'm going to give your code a try and practice a little. I was hoping to hear other people's opinion too, but I guess this was the wrong place to ask about dependency injection with android development or programming in general. Also, do you know if treehouse goes over design patterns? I'm hoping that treehouse goes over design patterns with their projects...if not, maybe in the future.