How can i perform dependency injection without breaking encapsulation?
Using a Dependency Injection example from Wikipedia:
public Car {
public f
-
This is where I think you must use dependency injection containers that let you encapsulate the creation of your car, without letting your client callers need to know how to create it whatsoever. Here's how symfony solved this problem (even though it is not the same language, principles remain the same):
http://components.symfony-project.org/dependency-injection/documentation
there is a section on dependency injection containers.
To make it short and summarize it all quoted from the documentation page directly:
When using the container, we just ask
for a mailer object [This would be your car in your example], and we don't need
to know anything about how to create
it anymore; all the knowledge about
how to create an instance of the
mailer [car] is now embedded into the
container.
It the hope that it helps you
讨论(0)
-
I haven't used Delphi in a long time. The way DI works in Spring, your setters and constructor aren't part of the interface. So you can have multiple implementations of an interface, one might use constructor-based injection and another might use setter-based injection, your code that uses the interface doesn't care. What's injected is in the application-context xml, and that is the only place that your dependencies are exposed.
EDIT:
If you use a framework or not you're doing the same thing, you have a factory that wires together your objects. So your objects expose these details in the constructor or in setters, but your application code (outside of the factory, and not counting tests) never uses them. Either way you choose to get your object graph from the factory rather than instantiate stuff on the fly, and you choose to not do things like use setters in the code that are there to be injected into. It is a mind-shift from the "nail-everything-down" philosophy I see from some people's code.
讨论(0)
-
I think you're breaking encapsulation with your Car
constructor. Specifically you're dictating that an Engine
must be injected to the Car
instead of some type of interface used to determine your speed (IVelocity
in the below example.)
With an interface, the Car
is able to get it's current speed independent of what's determining that speed. For example:
public Interface IVelocity {
public float getSpeed();
}
public class Car {
private m_velocityObject;
public constructor(IVelocity velocityObject) {
m_velocityObject = velocityObject;
}
public float getSpeed() { return m_velocityObject.getSpeed(); }
}
public class Engine : IVelocity {
private float m_rpm;
private float m_currentGearRatio;
public float getSpeed( return m_rpm * m_currentGearRatio; );
}
public class GPS : IVelocity {
private float m_foo;
private float m_bar;
public float getSpeed( return m_foo * m_bar; );
}
An Engine or GPS can then have multiple interfaces based upon the type of work that it does. The interface is key to DI, without it DI does break encapsulation.
讨论(0)
- 热议问题