How can i perform dependency injection without breaking encapsulation?
Using a Dependency Injection example from Wikipedia:
public Car {
public float getSpeed();
}
Note: Other methods and properties (e.g. PushBrake(), PushGas(),
SetWheelPosition() ) omitted for
clarity
This works well; you don't know how my object implements getSpeed - it is "encapsulated".
In reality my object implements getSpeed as:
public Car {
private m_speed;
public float getSpeed( return m_speed; );
}
And all is well. Someone constructs my Car object, mashes pedals, the horn, the steering wheel, and the car responds.
Now lets say i change an internal implementation detail of my car:
public Car {
private Engine m_engine;
private float m_currentGearRatio;
public float getSpeed( return m_engine.getRpm*m_currentGearRatio; );
}
All is well. The Car is following proper OO-principles, hiding details of how something is done. This frees the caller to solve his problems, rather than trying to understand how a car works. It also gives me the freedom to change my implementation as i see fit.
But dependency injection would force me to expose my class to an Engine object that i didn't create or initialize. Even worse is that I've now exposed that my Car even has an engine:
public Car {
public constructor(Engine engine);
public float getSpeed();
}
And now the outside word is aware that i use an Engine. I didn't always use an engine, i may want to not use an Engine in the future, but i can no longer change my internal implementation:
public Car {
private Gps m_gps;
public float getSpeed( return m_gps.CurrentVelocity.Speed; )
}
without breaking the caller:
public Car {
public constructor(Gps gps);
public float getSpeed();
}
But dependency injection opens a whole can of worms: by opening the whole can of worms. Dependency Injection requires that all my objects private implementation details be exposed. The consumer of my Car class now has to understand, and deal with, all of the previously hidden internal intricacies of my class:
public Car {
public constructor(
Gps gps,
Engine engine,
Transmission transmission,
Tire frontLeftTire, Tire frontRightTire, Tire rearLeftTire, Tire rearRightTire,
Seat driversSeat, Seat passengersSeat, Seat rearBenchSeat,
SeatbeltPretensioner seatBeltPretensioner,
Alternator alternator,
Distributor distributor,
Chime chime,
ECM computer,
TireMonitoringSystem tireMonitor
);
public float getSpeed();
}
How can i use the virtues of Dependency Injection to help unit testing, while not breaking the virtues of encapsulation to help usability?
See also
Must Dependency Injection come at the expense of Encapsulation? (Must, rather than how)
For the sake of fun, i can trim down the getSpeed example to just what is needed:
public Car {
public constructor(
Engine engine,
Transmission transmission,
Tire frontLeftTire, Tire frontRightTire
TireMonitoringSystem tireMonitor,
UnitConverter unitsConverter
);
public float getSpeed()
{
float tireRpm = m_engine.CurrentRpm *
m_transmission.GetGearRatio( m_transmission.CurrentGear);
float effectiveTireRadius =
(
(m_frontLeftTire.RimSize + m_frontLeftTire.TireHeight / 25.4)
+
(m_frontRightTire.RimSize + m_frontRightTire.TireHeight / 25.4)
) / 2.0;
//account for over/under inflated tires
effectiveTireRadius = effectiveTireRadius *
((m_tireMonitor.FrontLeftInflation + m_tireMontitor.FrontRightInflation) / 2.0);
//speed in inches/minute
float speed = tireRpm * effetiveTireRadius * 2 * Math.pi;
//convert to mph
return m_UnitConverter.InchesPerMinuteToMilesPerHour(speed);
}
}
Update: Perhaps some answer can follow the question's lead, and give sample code?
public Car {
public float getSpeed();
}
Another example is when my class depends on another object:
public Car {
private float m_speed;
}
In this case float is a class that is used to represent a floating-point value. From what i read, every dependant class should be injected - in case i want to mock the float class. This raises the spectre of having to inject every private member, since everything is fundamentally an object:
public Car {
public Constructor(
float speed,
float weight,
float wheelBase,
float width,
float length,
float height,
float headRoom,
float legRoom,
DateTime manufactureDate,
DateTime designDate,
DateTime carStarted,
DateTime runningTime,
Gps gps,
Engine engine,
Transmission transmission,
Tire frontLeftTire, Tire frontRightTire, Tire rearLeftTire, Tire rearRightTire,
Seat driversSeat, Seat passengersSeat, Seat rearBenchSeat,
SeatbeltPretensioner seatBeltPretensioner,
Alternator alternator,
Distributor distributor,
Chime chime,
ECM computer,
TireMonitoringSystem tireMonitor,
...
}
These really are implementation details that i don't want the customer to have to look at.
Many of the other answers hint at it, but I'm going to more explicitly say that yes, naive implementations of dependency injection can break encapsulation.
The key to avoiding this is that calling code should not directly instantiate the dependencies (if it doesn't care about them). This can be done in a number of ways.
The simplest is simply have a default constructor that does the injecting with default values. As long as calling code is only using the default constructor you can change the dependencies behind the scenes without affecting calling code.
This can start to get out of hand if your dependencies themselves have dependencies and so forth. At that point the Factory pattern could come into place (or you can use it from the get-go so that calling code is already using the factory). If you introduce the factory and don't want to break existing users of your code, you could always just call into the factory from your default constructor.
Beyond that there's using Inversion of Control. I haven't used IoC enough to speak too much about it, but there's plenty of questions here on it as well as articles online that explain it much better than I could.
If it should be truly encapsulated to where calling code cannot know about the dependencies then there's the option of either making the injecting (either the constructor with the dependency parameters or the setters) internal if the language supports it, or making them private and have your unit tests use something like Reflection if your language supports it. If you language supports neither then I suppose a possibility might be to have the class that calling code is instantiating a dummy class that just encapsulates the class the does the real work (I believe this is the Facade pattern, but I never remember the names correctly):
public Car {
private RealCar _car;
public constructor(){ _car = new RealCar(new Engine) };
public float getSpeed() { return _car.getSpeed(); }
}
If I understand your concerns correctly, you're trying to prevent any class that needs to instantiate a new Car object from having to inject all those dependencies manually.
I've used a couple patterns to do this. In languages with constructor chaining, I've specified a default constructor that injects the concrete types into another, dependency-injected constructor. I think this is a pretty standard manual DI technique.
Another approach I've used, which allows some looser coupling, is to create a factory object that will configure the DI'ed object with the appropriate dependencies. Then I inject this factory into any object that needs to "new" up some Cars at runtime; this allows you to inject completely faked Car implementations during your tests, too.
And there's always the setter-injection approach. The object would have reasonable defaults for its properties, which could be replaced with test-doubles as needed. I do prefer constructor-injection, though.
Edit to show a code example:
interface ICar { float getSpeed(); }
interface ICarFactory { ICar CreateCar(); }
class Car : ICar {
private Engine _engine;
private float _currentGearRatio;
public constructor(Engine engine, float gearRatio){
_engine = engine;
_currentGearRatio = gearRatio;
}
public float getSpeed() { return return _engine.getRpm*_currentGearRatio; }
}
class CarFactory : ICarFactory {
public ICar CreateCar() { ...inject real dependencies... }
}
And then consumer classes just interact with it through the interface, completely hiding any constructors.
class CarUser {
private ICarFactory _factory;
public constructor(ICarFactory factory) { ... }
void do_something_with_speed(){
ICar car = _factory.CreateCar();
float speed = car.getSpeed();
//...do something else...
}
}
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.
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
Factories and interfaces.
You've got a couple of questions here.
How can I have multiple implementations of the same operations?
How can I hide construction details of an object from the consumer of an object?
So, what you need is to hide the real code behind an ICar interface, create a separate EnginelessCar if you ever need one, and use an ICarFactory interface and a CarFactory class to hide the construction details from the consumer of the car.
This will likely end up looking a lot like a dependency injection framework, but you do not have to use one.
As per my answer in the other question, whether or not this breaks encapsulation depends entirely on how you define encapsulation. There are two common definitions of encapsulation that I've seen:
All operations on a logical entity are exposed as class members, and a consumer of the class doesn't need to use anything else.
A class has a single responsibility, and the code to manage that responsibility is contained within the class. That is, when coding the class, you can effectively isolate it from its environment and reduce the scope of the code you're working with.
(Code like the first definition can exist in a codebase that works with the second condition - it just tends to be limited to facades, and those facades tend to have minimal or no logic).
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.
I don't think a car is a particularly good example of the real world usefulness of dependency injection.
I think in the case of your last code example, the purpose of the Car class is not clear. Is is a class that holds data/state? Is it a service to calculate things like speed? Or is it a mix, allowing you to construct its state and then call services on it to make calculations based on that state?
The way I see it, the Car class itself would likely be a stateful object, whose purpose is to hold the details of its composition, and the service to calculate speed (which could be injected, if desired) would be a separate class (with a method like "getSpeed(ICar car)"). Many developers who use DI tend to separate stateful and service objects--although there are cases where an object will have both state and service, the majority tend to be separated. In addition, the vast majority of DI usage tends to be on the service side.
The next question would be: how should the car class be composed? Is the intent that every specific car is just an instance of a Car class, or is there a separate class for each make and model that inherit from CarBase or ICar? If it's the former, then there must be some means of setting/injecting these values into the car--there is no way around this, even if you'd never heard of dependency inversion. If it's the latter, then these values are simply part of the car, and I would see no reason to ever want to make them settable/injectable. It comes down to whether things like Engine and Tires are specific to the implementation (hard dependencies) or if they are composable (loosely coupled dependencies).
I understand the car is just an example, but in the real world you are going to be the one who knows whether inverting dependencies on your classes violates encapsulation. If it does, the question you should be asking is "why?" and not "how?" (which is what you are doing, of course).
You should break your code into two phases:
Construction of the object graph for a particular lifetime via factory or DI solution
Running these objects (which will involve input and output)
At the car factory, they need to know how to build a car. They know what sort of engine it has, how the horn is wired in etc. This is phase 1 above. The car factory can build different cars.
When you are driving the car, you can drive anything that meets the car interface you expect. e.g. pedals, steering wheel, horn. When you're driving you don't know the internal details when you press the brake. You can, however, see the result (change in speed).
Encapsulation is maintained as no one driving a car needs to know how it was built. Therefore, you can use the same driver with many different cars. When the drive needs a car, they should be given one. If they build their own when they realise they need one, then encapsulation will be broken.
Now, for something completely different...
You want the virtues of dependency injection without breaking encapsulation. A dependency injection framework will do that for you, but there is also a "poor man's dependency injection" available to you through some creative use of virtual constructors, meta class registration and selective inclusion of units in your projects.
It does have a serious limitation though: you can only have a single specific Engine class in each project. There is no picking an choosing engine's, though come to think of it, you could probably mess with the value of the meta class variable to achieve just that. But I am getting ahead of myself.
Another limitation is a single line of inheritance: just a trunk, no branches. At least with regard to the units included in a single project.
You seem to be using Delphi and therefore the method below will work as it is something that we have been using since D5 in projects that need a single instance of class TBaseX, but different projects need different descendants of that base class and we want to be able to swap classes by simply chucking out one unit and adding another. The solution isn't restricted to Delphi though. It will work with any language that supports virtual constructors and meta classes.
So what do you need?
Well, every class that you want to be able to swap depending on units included per project, needs to have a variable somewhere in which you can store the class type to instantiate:
var
_EngineClass: TClass;
Every class that implements an Engine should register itself in the _EngineClass variable using a method that prevents ancestors from taking the place of a descendant (so you can avoid dependence on unit initialisation order):
procedure RegisterMetaClass(var aMetaClassVar: TClass; const aMetaClassToRegister: TClass);
begin
if Assigned(aMetaClassVar) and aMetaClassVar.InheritsFrom(aMetaClassToRegister) then
Exit;
aMetaClassVar := aMetaClassToRegister;
end;
Registration of the classes can be done in a common base class:
TBaseEngine
protected
class procedure RegisterClass;
class procedure TBaseEngine.RegisterClass;
begin
RegisterMetaClass(_EngineClass, Self);
end;
Each descendant registers itself by calling the registration method in its unit's initialization section:
type
TConcreteEngine = class(TBaseEngine)
...
end;
initialization
TConcreteEngine.RegisterClass;
Now all you need is something to instantiate the "descendent most" registered class instead of a hard coded specific class.
TBaseEngine
public
class function CreateRegisteredClass: TBaseEngine;
class function TBaseEngine.CreateRegisteredClass: TBaseEngine;
begin
Result := _EngineClass.Create;
end;
Of course you should now always use this class function to instantiate engines and not the normal constructor.
If you do that, your code will now always instantiate the "most descendant" engine class present in your project. And you can switch between classes by including and not including the specific units. For example you can ensure your test projects use the mock classes by making the mock class an ancestor of the actual class and not including the actual class in the test project; or by making the mock class a descendant of the actual class and not including the mock in your normal code; or - even simpler - by including either the mock or the actual class in your projects.
Mock and actual classes have a parameter-less constructor in this implementation example. Doesn't need to be the case, but you will need to use a specific meta class (instead of TClass) and some casting in the call to the RegisterMetaClass procedure because of the var parameter.
type
TBaseEngine = class; // forward
TEngineClass = class of TBaseEngine;
var
_EngineClass: TEngineClass
type
TBaseEngine = class
protected
class procedure RegisterClass;
public
class function CreateRegisteredClass(...): TBaseEngine;
constructor Create(...); virtual;
TConcreteEngine = class(TBaseEngine)
...
end;
TMockEngine = class(TBaseEngine)
...
end;
class procedure TBaseEngine.RegisterClass;
begin
RegisterMetaClass({var}TClass(_EngineClass), Self);
end;
class function TBaseEngine.CreateRegisteredClass(...): TBaseEngine;
begin
Result := _EngineClass.Create(...);
end;
constructor TBaseEngine.Create(...);
begin
// use parameters in creating an instance.
end;
Have fun!
Related
I'm building a component system where an abstract type Component is inherited from to make components. So far, I have drawable, physical, movable and other components. All seems to go well, and in the Game class I perform the following:
void Game::init()
{
pPlayer->addComponent(pMovable);
}
void Game::processEvents()
{
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
pMovable->moveUp(2.f);
// etc..
pPlayer->setVelocity(pMovable->getVelocity());
}
void Game::update()
{
pPlayer->update(0);
}
void Game::play()
{
while (pWindow->isOpen())
{
// ...
processEvents();
}
}
So far, the component system is really basic and simple. The player is of type Object and whenever I call the player's update function, I also have the Object's update function also called. This should really be automated, but that will change in the future. What the real problem is this:
pPlayer can still access pMovable's velocity even if it has not added pMovable as a component. This is problematic because it means anyone can simply get the velocity from pMovable and then plug it into their object without having to add pMovable as part of their component. Now, what does tend to happen is that the movement becomes unmanaged since there is no movable component to regulate it. I term this unauthorised use of the component, and I want to develop a way by which a component can 'deny' usage of its functionality to an object it is not owned by. There are many solutions to this problem, and I need one which is efficient and practical for use. Here are mine:
Throw an exception if the client attempts to allocate a component function into its own without adding it;
Create a system by which objects and components are identified and the component keeps track of the objects it is owned by, and the objects keep track of the components it owns. Because this is a many-to-many relationship, an intermediate class that manages all this would have to be created; it also avoids a circular header inclusion.
Have a function NOT part of an object simply 'deactivated'. This would require the use of a boolean like 'componentAdded' and all functions would have to check whether the component was added or not, else the function won't do what it ought to be doing.
If you have other solutions to prevent the unauthorised use of components, please share them as I'm keen to learn from others as to how they implemented/or would implement a component system as I have done here.
You can't prevent specific classes from inheritance. It's an all or nothing proposition: any class inherits from the base or none.
The best you can hope for is to narrow the interface. For example, instead of allowing decendents of Object in a function, you may want to have a class Stationary_Object or Enemy_Object to refine the interface. This allows you to write functions that take any Enemy_Object and won't take a Stationary_Object (like a tree or wall).
Edit 1: Cheating with friends
You can allow member access by declaring the members as private and granting access to specific classes using the friend class. The problem is that the class with data will need to be modified whenever a new type of friend is created. I believe this use of friendship defeats the purpose of reusability.
Edit 2: detecting ownership
Let's say we have three classes:
class Engine;
class Car
{
Engine car_engine;
};
class Boat
{
Engine boat_engine;
};
And a function:
void Fix_Car_Engine(Engine& e)
{
}
There is no method in C++ for the Fix_Car_Engine to know that it is fixing a car engine or a boat engine. The function only knows that it has been given a generic engine to fix (or it only knows about the common Engine stuff of the variable).
This issue can be mitigated by refining or narrowing the interface:
class Car_Engine : public Engine;
class Boat_Engine : public Engine;
class Car
{
Car_Engine diesel_engine;
};
class Boat
{
Boat_Engine propellor_engine;
};
In the above example, the Engine class has two specializations: Car_Engine and Boat_Engine. The Car now has a Car_Engine member and the Boat has a Boat_Engine.
The functions can now be created to operate on special engines:
void fix_boat_engine(Boat_Engine& be);
void fix_car_engine(Car_Engine& ce);
The fix_car_engine will now only work with Car Engines. You could say that it works on any class that has-a Car Engine (as long as you pass the Car Engine member). Likewise, the fix_boat_engine function only operates on Boat Engines.
Given:
class Rocket_Engine : public Engine;
Also, this specialization prevents a Rocket_Engine from being passed to either function. The functions require specific engine types.
if I have a class with a helper (private member) class within it, like this
class Obj;
class Helper {
friend class Obj;
private:
int m_count;
Helper(){ m_count = 0;}; // Note this is a private constructor
void incrementCount(){
++m_count;
};
};
class Obj {
Helper *m_pHelper;
// note that this is a private getter
int getHelperCount() { return m_pHelper->m_count; };
// the public API starts here
public:
Obj() { m_pHelper = new Helper(); };
void incrementCount(){ m_pHelper->incrementCount(); };
};
So how may I TDD such a system?
auto obj = new Obj();
obj->incrementCount();
// what to assert???
That is my question and the following is just some background.
Response to some answers and comments.
If noone outside the class should be interested, then your tests should not be interested either. – Arne Mertz
If nobody is interested in the value outside the class, why are you – utnapistim
Even if no one outside needs the value, I may still want to know that if it's set correctly, as it is used by other self contained internal method of the class that use that value. Maybe the value is the speed where the controller will use it to update the model. Or maybe it's the position where the view will use it to draw something on the screen. And in fact all other components of Obj would be able to access that variable. It may be a bad design issue, and in this case I would like to know what better alternatives I can have. The design is listed in the background section at the bottom of this post.
define private public - Marson Mao
Love this ingenious abuse of keywords haha. But may not be concluded as the best solution just yet.
You need to "expose" the friendship relation in the header of your class. Thus you have to acknowledge there the existence of a class used to test yours.
If you use the pImpl idiom, you could make the members of the pImpl itself all public, the pImpl itself private and give your unit tests access to the pImpl - CashCow
Does this mean that I should friend the test in my original class? Or add extra "test" methods to it?
I just started TDD very recently. Is it common (or better is it good) to intrude the original class with test class dependency? I don't think I have the appropriate knowledge to judge. Any advice on this?
Miscellaneous: AFAIK TDD is not just writing test, but instead a development process. I have read that I should only write tests to the public interface. But the problem is, like the situation in question, most of the codes etc are contained within private class. How may I use TDD to create these codes?
Background
FYI if you would like to know why I am making a private class:
I am developing a game from cocos2dx. The game engine adopts a Node tree structure for the updates, rendering etc and every game object would inherit from a Node class provided in the engine. Now I want to implement the MVC pattern on a game object. So for each object I basically created a Object class with 3 helper classes corresponding to each of the MVC components named ObjectModel, ObjectView, ObjectController. Theoretically no one should access the MVC classes directly and would only be accessed somehow through the Object class so I make the 3 of them private. The reason of making the MVC components explicitly as classes is because the View and Controller are updating at different rates (more specifically the Controller performs frame dependent updates, while the View do a simple interpolation based on the model data). The Model class is created purely for religious reasons lol.
Thanks in advance.
How to test friend functions of private class?
Thou shalt not!
A class (or module or library or whatever) exposes a public interface for a reason. You have the public interface (which is geared for client use, so it has invariants, preconditions, postconditions, side-effects, whatever - which can and should be tested) and implementation details, that allow you to implement the public interface, easier.
The point of having a private implementation, is that you are allowed to change it as you please, without affecting other code (without affecting even tests). All tests should pass after you change your private implementation, and client (and test) code should (by design) not care at all that you changed the private implementation.
So how may I TDD such a system?
TDD your public interface only. Testing implementation details means you end up coding to an implementation, instead of an interface.
Regarding your comment:
The problem is I don't even have a getter in the public interface. So how can my test check that the value is 0 or 1? And the getter is intentionally made private as no one should be interested in the value outside the class
If nobody is interested in the value outside the class, why are you (i.e. why would you wish to test for it?)
The #define private public trick can have side effects with the way some compiler are mangling function symbols (Visual c++ compiler is including access specifier in its name mangling)
You can also change visibility with the using statement :
struct ObjTest : public Obj
{
using Obj::incrementCount;
}
But like other people said, try to not test private stuff if possible.
I have encounter such problem when I was writing unit test as well.
After some searching I decided the most effective way is to add this in your Test.cpp:
#define private public
NOTE: add this before your desired include file, maybe your Obj.h, for example.
I think this method looks crazy but it's actually reasonable, because this #define only affect your test file, so all other people using your Obj.h is totally fine.
Some reference:
Unit testing of private methods
I vote, as #Marson Mao says, for #define private public.
If you want to control what to make private or public a bit more, you can do this in yourtests.cpp
#define private public
#include "IWantAccessViolationForThis.h"
#undef private
#include "NormalFile.h"
This way you can have a bit more control and try to do this trick in as few places as possible.
Another nice property of this approach is that it is non-intrusive, meaning that you don't need to clutter your real implementation and header files with #ifdefs for testing and not testing modes.
Your friend has full access to the class that it is a friend of. This might be done for many reasons and one of those could well be for unit-testing purpose, i.e. you want to be able to write a unit test that can call private members of the class and check the internal variables show what you would expect them to show, but you do not want that to be part of the public API.
You need to "expose" the friendship relation in the header of your class. Thus you have to acknowledge there the existence of a class used to test yours. No worries, you develop in the real world and classes are tested.
In order to write a unit test you will want to implement that class to provide protected member functions (probably static ones) that call all the relevant private functions or get the private members, and then you write classes that derive from yours. Note that those will not have direct access as friendship is not inherited, thus the static protected members.
If you use the pImpl idiom, you could make the members of the pImpl itself all public, the pImpl itself private and give your unit tests access to the pImpl (through the same model as above). This is now simpler as you only need to create one method for your "tester".
With regards to data members of a class, in recent years I have been known to put all these into a struct, i.e. have them all public, and then for the class to have a private instance of that struct. It can be easier for handling this kind of thing, and also serialisation / factories to your class, where they can create the struct which is all public, then construct your class from it.
I'm trying to get dependency inversion, or at least understand how to apply it, but the problem I have at the moment is how to deal with dependencies that are pervasive. The classic example of this is trace logging, but in my application I have many services that most if not all code will depend on (trace logging, string manipulation, user message logging etc).
None of the solutions to this would appear to be particularly palatable:
Using constructor dependency injection would mean that most of the constructors would have several, many, standard injected dependencies because most classes explicitly require those dependencies (they are not just passing them down to objects that they construct).
Service locator pattern just drives the dependencies underground, removing them from the constructor but hiding them so that it's not even explicit that the dependencies are required
Singleton services are, well, Singletons, and also serve to hide the dependencies
Lumping all those common services together into a single CommonServices interface and injecting that aswell a) violates the Law of Demeter and b) is really just another name for a Service Locator, albeit a specific rather than a generic one.
Does anyone have any other suggestions for how to structure these kinds of dependencies, or indeed any experience of any of the above solutions?
Note that I don't have a particular DI framework in mind, in fact we're programming in C++ and would be doing any injection manually (if indeed dependencies are injected).
Service locator pattern just drives the dependencies underground,
Singleton services are, well, Singletons, and also serve to hide the
dependencies
This is a good observation. Hiding the dependencies doesn't remove them. Instead you should address the number of dependencies a class needs.
Using constructor dependency injection would mean that most of the
constructors would have several, many, standard injected dependencies
because most classes explicitly require those dependencies
If this is the case, you are probably violating the Single Responsibility Principle. In other words, those classes are probably too big and do too much. Since you are talking about logging and tracing, you should ask yourself if you aren't logging too much. But in general, logging and tracing are cross-cutting concerns and you should not have to add them to many classes in the system. If you correctly apply the SOLID principles, this problem goes away (as explained here).
The Dependency Inversion principle is part of the SOLID Principles and is an important principle for among other things, to promote testability and reuse of the higher-level algorithm.
Background:
As indicated on Uncle Bob's web page, Dependency Inversion is about depend on abstractions, not on concretions.
In practice, what happens is that some places where your class instantiates another class directly, need to be changed such that the implementation of the inner class can be specified by the caller.
For instance, if I have a Model class, I should not hard code it to use a specific database class. If I do that, I cannot use the Model class to use a different database implementation. This might be useful if you have a different database provider, or you may want to replace the database provider with a fake database for testing purposes.
Rather than the Model doing a "new" on the Database class, it will simply use an IDatabase interface that the Database class implements. The Model never refers to a concrete Database class. But then who instantiates the Database class? One solution is Constructor Injection (part of Dependency Injection). For this example, the Model class is given a new constructor that takes an IDatabase instance which it is to use, rather than instantiate one itself.
This solves the original problem of the Model no longer references the concrete Database class and uses the database through the IDatabase abstraction. But it introduces the problem mentioned in the Question, which is that it goes against Law of Demeter. That is, in this case, the caller of Model now has to know about IDatabase, when previously it did not. The Model is now exposing to its clients some detail about how it gets its job done.
Even if you were okay with this, there's another issue that seems to confuse a lot of people, including some trainers. There's as an assumption that any time a class, such as Model, instantiates another class concretely, then it's breaking the Dependency Inversion principle and therefore it is bad. But in practice, you can't follow these types of hard-and-fast rules. There are times when you need to use concrete classes. For instance, if you're going to throw an exception you have to "new it up" (eg. threw new BadArgumentException(...)). Or use classes from the base system such as strings, dictionaries, etc.
There's no simple rule that works in all cases. You have to understand what it is that you're trying to accomplish. If you're after testability, then the fact that the Model classes references the Database class directly is not itself a problem. The problem is the fact that the Model class has no other means of using another Database class. You solve this problem by implementing the Model class such that it uses IDatabase, and allows a client to specify an IDatabase implementation. If one is not specified by the client, the Model can then use a concrete implementation.
This is similar to the design of the many libraries, including C++ Standard Library. For instance, looking at the declaration std::set container:
template < class T, // set::key_type/value_type
class Compare = less<T>, // set::key_compare/value_compare
class Alloc = allocator<T> > // set::allocator_type
> class set;
You can see that it allows you to specify a comparer and an allocator, but most of the time, you take the default, especially the allocator. The STL has many such facets, especially in the IO library where detailed aspects of streaming can be augmented for localization, endianness, locales, etc.
In addition to testability, this allows the reuse of the higher-level algorithm with entirely different implementation of the classes that the algorithm internally uses.
And finally, back to the assertion I made previously with regard to scenarios where you would not want to invert the dependency. That is, there are times when you need to instantiate a concrete class, such as when instantiating the exception class, BadArgumentException. But, if you're after testability, you can also make the argument that you do, in fact, want to invert dependency of this as well. You may want to design the Model class such that all instantiations of exceptions are delegated to a class and invoked through an abstract interface. That way, code that tests the Model class can provide its own exception class whose usage the test can then monitor.
I've had colleagues give me examples where they abstract instantiation of even system calls, such as "getsystemtime" simply so they can test daylight savings and time-zone scenarios through their unit-testing.
Follow the YAGNI principle -- don't add abstractions simply because you think you might need it. If you're practicing test-first development, the right abstractions becomes apparent and only just enough abstraction is implemented to pass the test.
class Base {
public:
void doX() {
doA();
doB();
}
virtual void doA() {/*does A*/}
virtual void doB() {/*does B*/}
};
class LoggedBase public : Base {
public:
LoggedBase(Logger& logger) : l(logger) {}
virtual void doA() {l.log("start A"); Base::doA(); l.log("Stop A");}
virtual void doB() {l.log("start B"); Base::doB(); l.log("Stop B");}
private:
Logger& l;
};
Now you can create the LoggedBase using an abstract factory that knows about the logger. Nobody else has to know about the logger, nor do they need to know about LoggedBase.
class BaseFactory {
public:
virtual Base& makeBase() = 0;
};
class BaseFactoryImp public : BaseFactory {
public:
BaseFactoryImp(Logger& logger) : l(logger) {}
virtual Base& makeBase() {return *(new LoggedBase(l));}
};
The factory implementation is held in a global variable:
BaseFactory* baseFactory;
And is initialized to an instance of BaseFactoryImp by 'main' or some function close to main. Only that function knows about BaseFactoryImp and LoggedBase. Everyone else is blissfully ignorant of them all.
Currently my project is composed of various concrete classes. Now as I'm getting into unit testing it looks like I'm supposed to create an interface for each and every class (effectively doubling the number of classes in my project)? I happen to be using Google Mock as a mocking framework. See Google Mock CookBook on Interfaces. While before I might have just classes Car and Engine, now I would have abstract classes (aka C++ interfaces) Car and Engine and then the implementation classes CarImplementation and EngineImpl or whatever. This would allow me to stub out Car's dependency on Engine.
There are two lines of thought I have come across in researching this:
Only use interfaces when you may have the need for more than one
implementation of a given abstraction and/or for use in public APIs,
so otherwise don't create interfaces unnecessarily.
Unit tests stubs/mocks
often are the "other implementation", and so, yes, you should create
intefaces.
When unit testing, should I create an interface for each class in my project? (I'm leaning towards creating interfaces for ease of testing)
Think you've got a number of options. As you say, one option is to create interfaces. Say you have classes
class Engine:
{
public:
void start(){ };
};
class Car
{
public:
void start()
{
// do car specific stuff
e_.start();
private:
Engine e;
};
To introduce interfaces - you would have to change Car to take an Engine
class Car
{
public:
Car(Engine* engine) :
e_(engine)
{}
void start()
{
// do car specific stuff
e_->start();
private:
Engine *e_;
};
If you've only got one type of engine - you've suddenly made your Car objects harder to use (who creates the engines, who owns the engines). Cars have a lot of parts - so this problem will continue to increase.
If you want seperate implementations, another way would be with templates. This removes the need for interfaces.
class Car<type EngineType = Engine>
{
public:
void start()
{
// do car specific stuff
e_.start();
private:
EngineType e;
};
In your mocks, you could then create Cars with specialised engines:
Car<MockEngine> testEngine;
Another, different approach, would be to add methods to Engine to allow it to be tested, something like:
class Engine:
{
public:
void start();
bool hasStarted() const;
};
You could then either add a check method to Car, or inherit from Car to test.
class TestCar : public Car
{
public:
bool hasEngineStarted() { return e_.hasStarted(); }
};
This would require Engine to be changed from private to protected in the Car class.
Depending on the real world situation, will depend on which solution is best. Also, each developer will have their own holy grail of how they believe code should be unit tested. My personal views is to keep the client/customer in mind. Lets assume your clients (perhaps other developers in your team) will be creating Cars and don't care about Engines. I would therefore not want to expose the concepts of Engines (a class internal to my library) just so I can unit test the thing. I would opt for not creating interfaces and testing the two classes together (third option I gave).
there are two categories of testing regarding implementation visibility: black-box testing and white-box testing
black-box testing focuses on testing implementation through their interfaces, and validating the adjust to their spec.
white-box testing tests granular details about the implementation that SHOULD NOT in general be accessible from the outside. This sort of testing will validate that the implementation components work as intended. So their results are mostly of interest to developers trying to figure out what is broken, or needs mantainance
mocks by their definition fit into modular architectures, but it doesn't follow that all classes in a project need to be entirely modular out themselves. Its perfectly fine to draw some line when a group of classes will know about each other. They as a group can present to other modules from the persepective of some facade interface class. However, you'll still want to have white-box test drivers inside this module with knowledge about the implementation details. Hence this sort of testing is not a good fit for mocks.
It follows trivially from this that you don't need to have mocks or interfaces for everything. Just take the high-level design components that implement facade interfaces and create mocks for them. It will give you the sweet spot where mock testing pays off IMHO
having said that, try to use the tool to your needs, rather than letting the tool force you into changes you think will not be beneficial in the long run
Creating interfaces for every class within your project may or may not be necessary. This is entirely a design decision. I've found that it mostly isn't. Often in n-tier design you wish you abstract the layer between data access and logic. I would argue that you should work towards this as it aids in testing the logic without much infrastructure necessary for the tests. Methods of abstraction like dependency injection and IoC would require you to do something like this and would make it easier to test said logic.
I would examine what you are trying to test and focus on the areas that you view as most prone to error. This can help you decide whether interfaces are necessary.
Assume i have a private routine that performs some calculation:
private function TCar.Speed: float
{
Result = m_furlogs * 23;
}
But now i want to begin testing this calculation more thoroughly, so i refactor it out to a separate function:
public function TCar.Speed: float
{
Result = CalculateSpeed(m_furlogs);
}
private function TCar.CalculateSpeed(single furlogs): float
{
Result = furlogs * 23;
}
Now i can perform all kinds of tests on CalculateSpeed:
Check( CalculateSpeed(0) = 0);
Check( CalculateSpeed(1) = 23);
Check( CalculateSpeed(2) = 46);
Check( CalculateSpeed(88) = -1);
Except that i can't perform these tests, because CalculateSpeed is private to TCar. An abstract tennant of unit-testing is that you never test private code - only public interfaces. As a practical matter, *x*Unit is not normally structured to be able to access private methods of the separate class being tested.
The issue is that none of the rest of the class is setup to handle unit-tests. This is the very first routine that will have testing of any kind. And it is very difficult to configure the host class a set of initial conditions that will allow me to test calling CalculateSpeed with every set of inputs that i would like.
The only alternative i can see, is moving this private calculation out into it's own TCarCalculateSpeed class:
public class TCarCalculateSpeed
{
public function CalculateSpeed(float furlogs)
{
Result = furlogs * 23;
}
}
A whole class, dedicated to exposing one method, that's supposed to be private, just so i can test it?
Class explosion.
Plus it's private. If i wanted it to be public, i'd rather promote it to public visibility - at least that way i save a separate class being created.
i'd like to add some unit-testing; but it can only be done in small pieces, as code changes. i can't completely redesign functioning 12 year old software, possibly breaking everything, because i wanted to test one internal calculation.
My current, best, thinking is to add a Test method to my Car class, and just call that:
TCar Car = new TCar();
Car.RunTests;
public procedure TCar.RunTests
{
Check( CalculateSpeed(0) = 0);
Check( CalculateSpeed(1) = 23);
Check( CalculateSpeed(2) = 46);
Check( CalculateSpeed(88) = -1);
}
But now i have to figure out how to have TCar.RunTests get trigged by the external TestRunner, which is only designed to use TestCase classes.
Note: i've tried my damnest to mix syntax from a bunch of languages. In other words: language agnostic.
This can't really be quite language-agnostic, as the protection mechanisms and the tactics to bypass them vary quite widely with language.
But most languages do provide bypasses in some form, and as others have noted, there are sometimes protections midway between private and public that make testing easier.
In Java, for example, reflection can be used to private stuff if you really need to, and things can be made protected or package-private so that you don't need reflection.
Generally speaking, if something is complex enough to require testing it should not be buried as a private method or class in something else. It is doing something that warrants its own class.
Rather than worrying about the number of classes, worry about their size and complexity. Many small classes adhering to the Single Responsibility Principle are better than a small number of classes doing complex things internally.
If a method is complicated (and risky) enough to test on its own, it's worth creating a class for it or making it a public member of the existing class - whichever is more suitable, given the characteristics of the existing class.
Can you create multiple instances of the TCar class with different initial values of m_furlogs? Do you have a getter on speed anywhere? You could validate against that if so.
If it's only internally used, and you really want to test it, you could create a utilities class that holds the logic for the simple calculations. I know it's refactoring, but it's not the class explosion you might be envisioning.
In some languages, there is middle ground between private and public. You can expose a logically private method to a unit test without exposing it to the world.
In method documentation, you can document that the method is intended private, but accessible for the purpose of unit-testing.
In Java, for example, you could make the private method package protected, and place the unit test in the same package. In C#, if I recall correctly, you could make it internal. In C++, the unit-test could be a friend.
If your language supports compiler defines, you could use these to your advantage.
(Example code in Delphi)
In your unit test project, set a compiler conditional define, either using the project options or in an include file that you include in each and every unit in that project.
{$DEFINE UNIT_TESTS}
In your class code, check the conditional define and switch between public or protected and private accordingly:
{$IFDEF UNIT_TESTS}
public // or protected
{$ELSE}
private
{$ENDIF}
function CalculateSpeed: float;
This means your unit tests will have the access they need to your method, while in production code it will still be private.