3

In the tutorial I'm doing it uses interfaces to inject things, for example it uses a IHotDrink interface, then creates a Tea class that implements IHotDrink. It then has a third class called Restaurant that has a IHotDrink field inside the class and assigns a value to it in the constructor. It then goes on by injecting a Tea Class into the Restaurant class's constructor (which takes a IHotDrink interface argument)

So basically my question is: Does every field that is going to be injected need to be an interface?

Lets say I have a bunch of food items that all implement a IHotFoods interface, and a bunch of drinks that all implement the IHotDrink Interface, would it be okay If I have a meal class that doesn't implement anything and takes in a IHotFood interface and a IHotDrink Interface as arguments into its constructor (that will later be injected by different food/drinks classes ) and then have a meal field in the restaurant class that I can inject with different meal objects? Would this be okay? Or would I have to: Make a meals interface, have meal implement meals, and have Restaurant have a meals interface field that I can inject meal into?

Edit: I'm not asking whether every class should implement an interface, I'm asking whether they should always have interface fields to inject other classes into them that also implement the interface. (like in the example in the tutorial)

2

1 Answer 1

5

What you're observing is actually called "coding to an interface."

Like dependency injection, it's a technique for keeping your code loosely coupled. That's why you tend to see them used together.

Now, to answer your question: No, you don't always need to store injected dependencies as interfaces. You can store them as their concrete types, but that does tightly couple your dependent class to its dependency (which is generally a bad thing).

I often store my dependencies as their concrete types while I'm in the early stages of coding my application. I do this, because the structure of my code is still likely to change a lot, so extracting an interface and keeping it up to date can be a pain. But, once the structure of my code stabilises, I tend go through again and replace references to concrete types with references to interfaces where I think loose coupling is important.

In your specific example the interface might actually be implemented by many different hot drinks. The reason the Restaurant class stores it as an IHotDrink is because it doesn't care which specific hot drink it receives. I just needs to know that what it receives behaves like (read: has the interface of) a hot drink. So, storing it as a concrete type in this case doesn't make sense. It would unnecessarily restrict what your Restaurant can offer.

And regarding your Meal class idea, that might make sense, but depending on what your Restaurant class' responsibilities are it might be too restricting. Does a Restaurant only offer set meals? Or does it allow patrons to pick and choose how to combine hot food and hot drinks? Furthermore, will a Restaurant allow patrons to buy single items as well as entire meals? It would be a shame to have to buy a hamburger if all I wanted was a coffee :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.