DDD - Rehydrate aggregate roots? - oop

All my entities are implementation of interfaces. Most of their properties are read-only.
My repository holds a reference to the library project where i hold all the interfaces, so technically speaking, the repository can save the aggregate root without knowing anything about it's de-facto implementation (something i believe to be a +1).
The problem here is: if most of the properties are read-only, how can I rehydrate a aggregate root without breaking OOP principles? should the repository hold a reference to the domain project and be aware of the concrete implementation of interfaces?

should the repository hold a reference to the domain project and be aware of the concrete implementation of interfaces?
As Evans describes in the Blue Book; the Repository is a role played by an implementation, to keep the application from mutating the underlying data directly. Similarly, the Aggregate Root is a role -- we don't let the application touch the actual entity, but instead just a limited part of it.
The implementation of the repository is part of the model, so it can know more about the specific entities being represented; including knowing how to extract from them a representation of state that can be handed off to your persistence component for storage.
To choose a specific context, let's pretend that we are modeling a TradeBook, and one of the interesting use cases is that of a customer placing orders.
In Java, the implementation of the Repository interface -- the bit that the application knows about, might look like
interface API.TradeBookRepository<TradeBook extends API.TradeBook> {
TradeBook getById(...);
void save(TradeBook);
}
interface API.TradeBook {
void placeOrder(...);
}
So the application knows that it has an access to a repository, but it doesn't know anything about the implementation but the promise that it
will provide something that supports placeOrder.
So the application code looks like:
API.TradeBookRepository<? extends API.TradeBook> repo = ....
API.TradeBook book = repo.getById(...);
book.placeOrder(...)
repo.save(book)
But a given repository implementation is usually coupled to a specific implementation of the book; they are paired together.
class LIFO.TradeBook implements API.TradeBook {
...
}
class LIFO.TradeBookRepository implements API.TradeBookRepository<LIFO.TradeBook> {
...
}
how can I rehydrate a aggregate root without breaking OOP principles?
To some degree, you can't. The good news is, at the boundaries, applications are not object oriented.
The thing you are putting into your durable store isn't an aggregate root; it's some representation of state. I tend to think of it as a Memento. What you really have are two functions - one converts a specific aggregate root implementation (ex: LIFO.TradeBook) to a Memento, the other converts a Memento to an aggregate root.
Key idea: you are probably going to want to change your domain model a lot more often than you are going to want to migrate the database. So the Memento needs to be designed to be stable -- in effect, the Memento is a message sent from the old domain model to the new one, so many of the lessons of message verioning apply.

Simply put, something somewhere in your application has to know about concrete implementations. If you really want to shield the repository implementation (not the contract) from knowing the concrete entities then that responsibility will simply have to fall on another collaborator (e.g. repository would delegate the rehydration to an abstract factory).
However, it's quite uncommon to have separate contracts for aggregates because you usually have a single implementation of these business concepts and there's usually no scenario where you would want to mock them in unit tests. Therefore, repository contracts and implementation are most of the time defined in terms of concrete aggregates.

Related

How to use and create DTOs is OOP world?

What is the right way to create DTOs from business objects?
Who should be responsible for creating them? BO/DTO itself from BO/some static factory?
Where should they reside in code if I have, f.e. some core library and a specific service API library that I need DTO for? In core library next to BO(which seems incorrect)/in specific library?
If I have encapsulated fields in my BO how do DTO grab them? (obviously in case when BO is not responsible for creating DTOs)
As an example assume that I have some Person BO like this:
class Person
{
private int age;
public bool isBigEnough => age > 10;
}
I want age to be an internal state of Person but still I need to communicate my BO to some api. Or having private field in my class that I want to send somewhere already means that it should be public?
Are there any general considerations of how to use DTOs alongside business classes with encapsulated data?
___ Update:
In addition to approaches that #Alexey Groshev mentioned I came accross another one: we separate data of our BO class into some Data class with public accessors. BO wraps this data with its api(probably using composition) and when needed it can return its state as Data class as clone. So dto converter will be able to access Domain object's state but won't be able to modify it(since it will be just a copy).
There're multiple options available, but it would be difficult to recommend anything, because I don't know the details about your project/product. Anyway I'll name a few.
You can use AutoMapper to map BOs to DTOs and vise versa. I personally dislike this approach, because it's quite difficult (but possible) to keep it under control in medium/large sized projects. People don't usually bother to configure mappings properly and just expose internal state of their objects. For example, your isBigEnough would disappear and age would become public. Another potential risk is that people can map DTOs to/from EF/Hibernate objects. You can find some articles which explain why it's considered to be a bad practice.
As you suggested, a BO can create DTO by itself, but how would you implement this approach? You can add methods or factory methods to your entities, e.g. public PersonDto ToDto(). Or you can add an interface, e.g. public interface IDtoConvertable<T> { T ToDto(); }, and choose which entity or aggregate root will implement it. Your Person class would look like this class Person : IDtoConvertable<PersonDto> {... public PersonDto ToDto() {...} }. In both cases DTO namespace/assembly must to accessible by entities which sometimes can be a problem, but usually it's not a biggie. (Make sure that DTOs cannot access entities which is much worse.)
(C#) Another option is to return a delegate which creates DTO. I decided to separate it from (2), because entity doesn't really create DTO by itself, but rather exposes a functionality which creates DTO. So, you could have something like this public Func<PersonDto> ToDto() {...}. You might want to have an interface as in (2), but you get the idea, don't you? Do I like this approach? No, because it makes code unreadable.
As you see, there are more questions than answers. I'd recommend you to make a few experiments and check what works for you (your project) and what doesn't.
I think the answer to question 5 will address the other questions too.
Are there any general considerations of how to use DTOs alongside business classes with encapsulated data?
Remember, a DTO is solely to transfer data. Do not concern yourself with implementing any kind of rules in the DTO. All it is used for is to move data from one subsystem to another (NOT between classes of the same subsystem). How that data is used in the destination system is out of your control -- although as the God programmer you inherently know how it is going to be used, DO NOT let that knowledge influence your design -- and therefore there should be no assumptions expressed as behaviour or knowledge accessors -- so, no isBigEnough.

Is Martin Fowler's POEAA implementation of Unit of Work an anti-pattern?

Well from the book POEAA, Martin Fowler introduced this idea of Unit of Work. It works very well if you want to have auto-commit system, in which your domain model uses Unit of work to label itself as new, dirty, removed or clean. Then you only need to call UnitofWork.commit() and all changes of models will be saved. Below is a domain model class with such methods:
public abstract class DomainModel{
protected void markNew(){
UnitOfWork.getCurrent().registerNew(this);
}
protected void markDirty(){
UnitOfWork.getCurrent().registerDirty(this);
}
protected void markRemoved(){
UnitOfWork.getCurrent().registerRemoved(this);
}
protected void markClean(){
UnitOfWork.getCurrent().registerClean(this);
}
}
With this implementation, you can mark a domain model as any save state through business logic method:
public class Message extends DomainModel{
public void updateContent(User user, string content){
// This method update message content if the the message posted time is not longer than 24 hrs, and the user has permission to update messate content.
if(!canUpdateContent(user) && timeExpired()) throw new IllegalOperationException("An error occurred, cannot update content.");
this.content = content;
markDirty();
}
}
At first glance, it looks marvelous, since you dont have to manually call insert, save and delete method on your repository/data mapper. However, I see two problems with this approach:
Tight coupling of domain model with Unit of work: This implementation of Unit of Work will make domain models dependent on UnitOfWork class. UnitOfWork has to come from somewhere, the implementation of static class/method is bad. To improve this, we need to switch to dependency injection, and pass an instance of UnitOfWork to the constructor of Domain Model. But this still couples domain model with Unit of work. Also ideally a domain model should only accept parameters for its data fields(ie. Message domain model's constructor should only accept whats relevant to message, such as title, content, dateposted, etc). If it will need to accept a parameter of UnitOfWork, it will pollute the constructor.
The domain model now becomes persistent-aware: In modern application design, especially DDD, we strive for persistent-ignorant model. The domain model shouldnt care about whether it is being persisted or not, it should not even care about whether there's persistence layer at all. By having those markNew(), markDirty(), etc methods on domain model, our domain models now have the responsibility of informing the rest of our application that it needs to be persisted. Although it does not handle the persistence logic, the model still is aware of the existence of persistence layer. I am not sure if this is a good idea, to me it seems to have violate the single responsibility principle. There's also an article talking about this:
http://blog.sapiensworks.com/post/2014/06/04/Unit-Of-Work-is-the-new-Singleton.aspx/
So what do you think? Does the original Unit of Work pattern described in Martin Fowler violate good OO design principles? If so, do you consider it an antipattern?
To be entirely accurate, there is no one "Martin Fowler's implementation of Unit of Work". In the book he distinguishes between two types of registration of a modified object into a UoW.
Caller registration where only the calling object knows about the UoW and has to mark the (callee) domain object as dirty with it. No anti pattern or bad practice here as far as I can tell.
Object registration where the domain object registers itself with the UoW. Here again there are two options :
For this scheme to work the Unit of Work needs either to be passed to
the object or to be in a well-known place. Passing the Unit of Work
around is tedious but usually no problem to have it present in some
kind of session object.
The code sample is using UnitOfWork.GetCurrent() which is closer to the latter option and admittedly widely considered an anti-pattern today because of the tightly coupled, implicit dependency (Service Locator style).
However, if the first option was chosen, i.e. passing the UoW over to the domain object, and let's assume a Unit of Work abstraction, would it be bad practice ? From a dependency management perspective, clearly not.
Now remains the persistence ignorance aspect. Can we say about an object which can signal another object it's just been edited/created/removed that it is persistence-aware ? Highly debatable.
In comparison, if we look at more recent domain object implementations out there, for instance ones in Event Sourcing, we can see that aggregates can be responsible for keeping a list of their own uncommitted changes which is more or less the same idea. Does this violate persistence ignorance ? I don't think so.
Bottom line : the specific code Fowler chose to illustrate one of many UoW possibilities would clearly be considered bad practice now, but much more so with regard to problem #1 you pointed out and not really problem #2. And this doesn't disqualify other implementations he writes about, nor the whole UoW pattern whose change-tracking mechanics are anyway most of the time hidden away in third party library magic (read: ORM) nowadays and not hardcoded as in the book's example.
From a DDD perspective, this is something you shouldn't do.
DDD contains the following rule:
An application service should only modify one aggregate per transaction.
If you follow this rule, it's clear which aggregate changed during an app service operation. This aggregate then in turn needs to be passed to a repository for saving to the DB:
repository.update(theAggregate);
No other call is required. This defeats the gain from the pattern in the form you describe it.
On the other hand, the pattern you describe introduces a dependency from the domain to the persistence mechanism (depending on the design either a real dependency or just a conceptual dependency). Now this is something you should avoid, because it increases the complexity of your model a lot (not only internally, also for clients).
As a result, you shouldn't use the pattern in this form together with DDD.
Outside of DDD
Having that said, I think the pattern is one of many solutions to a certain problem. That solution has pros and cons, some of which you describe in the question. In some situations, the pattern may be the best trade-off, so
No, this is not an anti-pattern.
I don't think the model should not have a dependency on the UoW. It would be more like a repository that would depend on the UoW and, in turn, the repository would depend on the model.
If your repositories only depend on an abstract UoW, then the only piece of the puzzle that knows about the persistence technology is the concrete UoW.
The only classes I tend to allow the model to depend on are other pieces of the model: domain services, factories, etc.

Type separation (API design)

Say you design an API for some library.
You want to expose some data type (say Person) in the API (e.g. getAllPeople()).
Consider the following goals:
make it easy to add members to the Person (extensible)
don't introduce a dependency between the client of the library, and your implementation (coupling)
Person is likely to include internal state information that is not interesting to the client of the library
How would you go about it?
Define the Person in the library header / API package; have both the client of the library and the implementation depend on it (high coupling; very easy to extend)
Define Person in the API/header; define PersonModel extends Person in your library implementation (easy to extend; still some coupling)
Define PersonModel in the impl.; define Person extends PersonModel in the API (awful dependencies)
Define PersonModel in the impl; define Person in the API and copy the contents when needed (hard to extend; no coupling)
anything else?
In fact, Person is part of the API. It is the responsibility of the library user to choose how to decouple your API in the context of his architecture. You should not impose it.
If the user does not want to use your Person object, he has to encapsulate / copy your object.
Of course you can design Person to be extensible, but in any case it is part of the API. A user of this API is coupled to it. He has to choose when and where he needs to decouple from it and the way to do it. If Person is well designed, he might just use it everywhere. If it is poorly designed or not easy to use/extend, well he will copy the interesting part and redesign it.
When you design an API, the 'Person' kind of object should be an interface e.g. the user should not have access to the implementation. If person is an input to a service of your API, any implementation should work (Liskov principle). If Person is an output parameter, the user should get a reference, with any underlying internal implementation, there will be no coupling with the client code. It is hard when dealing with object construction, but using the *factory design patterns, you can manage even that. If there is no concrete implementation visible to the client code, you have a good API :-)

How does the Repository Pattern Differ from a Simple Data Access Layer?

I've been confused by what I've been reading during my research on the repository pattern. I'm wondering if folks are (incorrectly?) using that word when they simply mean a data access layer.
Since "repository" is not found in the index of Design Patterns (GoF), I've turned to Patterns of Enterprise Application Architecture (Fowler). Fowler seems pretty clear (page 323) when he states that clients create a criteria object and pass it to the repository to get the results. It looks something like this:
public class Person
{
public List<Person> Dependents()
{
Repository repository = Registry.personRepository();
Criteria criteria = new Criteria();
criteria.equal(Person.BENEFACTOR, this);
return repository.matching(criteria);
}
}
Is the criteria object what makes the repository a repository? If not, what does? If abstracting the persistence mechanism (and therefore constructing queries) is the goal, in what way does the repository differ from a simpe DAL/ORM call like this:
public class PersonLogic
{
public List<Person> GetDependents()
{
IPersonData personData = DependencyContainer.Resolve<IPersonData>();
return personData.GetDependents();
}
}
To me, the difference looks like this:
* With the repository pattern, the client constructs different criteria objects and calls the Matching() method on it.
* With the simple DAL, clients just call different methods based on what they want.
Is there more to it than this? Are programmers mistakenly using the term "repository" when they really mean DAL?
EDIT
David Osborne sent this link to Persistence Patterns. It states:
Basically, the Repository pattern just means putting a façade over
your persistence system so that you can shield the rest of your
application code from having to know how persistence works.
That's really what a data access layer is. It really appears to me that a repository and a DAL are the same thing, and maybe a "true" repository uses the criteria object.
Take a look at the "Using the IQueryable interface" section and beyond at Extending and Enhancing the Orders and Registrations Bounded Context. It provides an insightful and balanced discussion of DAO/Repository implementations.
As subsequently highlighted by Bob Horn, the Persistence Patterns articles summarises that:
Basically, the Repository pattern just means putting a façade over your persistence system so that you can shield the rest of your application code from having to know how persistence works.
In general I agree with author's statements, but I'd like to add some details
Difference between Repository and DAL/ORM that first not only abstracts the persistence mechanism, but also provides collection-like interface for accessing domain objects … and isolates domain objects from details of the database access code:
Differences
For external layers, such as Business Logic:
Helps to avoid leaky abstraction. External layers depend on abstraction of Repository, rather than a specific implementation of DAL/ORM. Thus you could avoid all infrastructure and logical dependencies while working with Repository.
operates with domain objects, rather then a instances of POJO/POCO/DTO
CRUD operations applied to collection-like interface provided by Repository, rather then specific DAL/ORM methods. For example .net: working with collection that implements IEnumerable, rather then entity-framework context or nhibernate session
Similarities
Repository contains DAL/ORM underneath and serves same purpose

Must Dependency Injection come at the expense of Encapsulation?

If I understand correctly, the typical mechanism for Dependency Injection is to inject either through a class' constructor or through a public property (member) of the class.
This exposes the dependency being injected and violates the OOP principle of encapsulation.
Am I correct in identifying this tradeoff? How do you deal with this issue?
Please also see my answer to my own question below.
There is another way of looking at this issue that you might find interesting.
When we use IoC/dependency injection, we're not using OOP concepts. Admittedly we're using an OO language as the 'host', but the ideas behind IoC come from component-oriented software engineering, not OO.
Component software is all about managing dependencies - an example in common use is .NET's Assembly mechanism. Each assembly publishes the list of assemblies that it references, and this makes it much easier to pull together (and validate) the pieces needed for a running application.
By applying similar techniques in our OO programs via IoC, we aim to make programs easier to configure and maintain. Publishing dependencies (as constructor parameters or whatever) is a key part of this. Encapsulation doesn't really apply, as in the component/service oriented world, there is no 'implementation type' for details to leak from.
Unfortunately our languages don't currently segregate the fine-grained, object-oriented concepts from the coarser-grained component-oriented ones, so this is a distinction that you have to hold in your mind only :)
It's a good question - but at some point, encapsulation in its purest form needs to be violated if the object is ever to have its dependency fulfilled. Some provider of the dependency must know both that the object in question requires a Foo, and the provider has to have a way of providing the Foo to the object.
Classically this latter case is handled as you say, through constructor arguments or setter methods. However, this is not necessarily true - I know that the latest versions of the Spring DI framework in Java, for example, let you annotate private fields (e.g. with #Autowired) and the dependency will be set via reflection without you needing to expose the dependency through any of the classes public methods/constructors. This might be the kind of solution you were looking for.
That said, I don't think that constructor injection is much of a problem, either. I've always felt that objects should be fully valid after construction, such that anything they need in order to perform their role (i.e. be in a valid state) should be supplied through the constructor anyway. If you have an object that requires a collaborator to work, it seems fine to me that the constructor publically advertises this requirement and ensures it is fulfilled when a new instance of the class is created.
Ideally when dealing with objects, you interact with them through an interface anyway, and the more you do this (and have dependencies wired through DI), the less you actually have to deal with constructors yourself. In the ideal situation, your code doesn't deal with or even ever create concrete instances of classes; so it just gets given an IFoo through DI, without worrying about what the constructor of FooImpl indicates it needs to do its job, and in fact without even being aware of FooImpl's existance. From this point of view, the encapsulation is perfect.
This is an opinion of course, but to my mind DI doesn't necessarily violate encapsulation and in fact can help it by centralising all of the necessary knowledge of internals into one place. Not only is this a good thing in itself, but even better this place is outside your own codebase, so none of the code you write needs to know about classes' dependencies.
This exposes the dependency being injected and violates the OOP principle of encapsulation.
Well, frankly speaking, everything violates encapsulation. :) It's a kind of a tender principle that must be treated well.
So, what violates encapsulation?
Inheritance does.
"Because inheritance exposes a subclass to details of its parent's implementation, it's often said that 'inheritance breaks encapsulation'". (Gang of Four 1995:19)
Aspect-oriented programming does. For example, you register onMethodCall() callback and that gives you a great opportunity to inject code to the normal method evaluation, adding strange side-effects etc.
Friend declaration in C++ does.
Class extention in Ruby does. Just redefine a string method somewhere after a string class was fully defined.
Well, a lot of stuff does.
Encapsulation is a good and important principle. But not the only one.
switch (principle)
{
case encapsulation:
if (there_is_a_reason)
break!
}
Yes, DI violates encapsulation (also known as "information hiding").
But the real problem comes when developers use it as an excuse to violate the KISS (Keep It Short and Simple) and YAGNI (You Ain't Gonna Need It) principles.
Personally, I prefer simple and effective solutions. I mostly use the "new" operator to instantiate stateful dependencies whenever and wherever they are needed. It is simple, well encapsulated, easy to understand, and easy to test. So, why not?
A good depenancy injection container/system will allow for constructor injection. The dependant objects will be encapsulated, and need not be exposed publicly at all. Further, by using a DP system, none of your code even "knows" the details of how the object is constructed, possibly even including the object being constructed. There is more encapsulation in this case since nearly all of your code not only is shielded from knowledge of the encapsulated objects, but does not even participate in the objects construction.
Now, I am assuming you are comparing against the case where the created object creates its own encapsulated objects, most likely in its constructor. My understanding of DP is that we want to take this responsibility away from the object and give it to someone else. To that end, the "someone else", which is the DP container in this case, does have intimate knowledge which "violates" encapsulation; the benefit is that it pulls that knowledge out of the object, iteself. Someone has to have it. The rest of your application does not.
I would think of it this way: The dependancy injection container/system violates encapsulation, but your code does not. In fact, your code is more "encapsulated" then ever.
This is similar to the upvoted answer but I want to think out loud - perhaps others see things this way as well.
Classical OO uses constructors to define the public "initialization" contract for consumers of the class (hiding ALL implementation details; aka encapsulation). This contract can ensure that after instantiation you have a ready-to-use object (i.e. no additional initialization steps to be remembered (er, forgotten) by the user).
(constructor) DI undeniably breaks encapsulation by bleeding implemenation detail through this public constructor interface. As long as we still consider the public constructor responsible for defining the initialization contract for users, we have created a horrible violation of encapsulation.
Theoretical Example:
Class Foo has 4 methods and needs an integer for initialization, so its constructor looks like Foo(int size) and it's immediately clear to users of class Foo that they must provide a size at instantiation in order for Foo to work.
Say this particular implementation of Foo may also need a IWidget to do its job. Constructor injection of this dependency would have us create a constructor like Foo(int size, IWidget widget)
What irks me about this is now we have a constructor that's blending initialization data with dependencies - one input is of interest to the user of the class (size), the other is an internal dependency that only serves to confuse the user and is an implementation detail (widget).
The size parameter is NOT a dependency - it's simple a per-instance initialization value. IoC is dandy for external dependencies (like widget) but not for internal state initialization.
Even worse, what if the Widget is only necessary for 2 of the 4 methods on this class; I may be incurring instantiation overhead for Widget even though it may not be used!
How to compromise/reconcile this?
One approach is to switch exclusively to interfaces to define the operation contract; and abolish the use of constructors by users.
To be consistent, all objects would have to be accessed through interfaces only, and instantiated only through some form of resolver (like an IOC/DI container). Only the container gets to instantiate things.
That takes care of the Widget dependency, but how do we initialize "size" without resorting to a separate initialization method on the Foo interface? Using this solution, we lost the ability to ensure that an instance of Foo is fully initialized by the time you get the instance. Bummer, because I really like the idea and simplicity of constructor injection.
How do I achieve guaranteed initialization in this DI world, when initialization is MORE than ONLY external dependencies?
As Jeff Sternal pointed out in a comment to the question, the answer is entirely dependent on how you define encapsulation.
There seem to be two main camps of what encapsulation means:
Everything related to the object is a method on an object. So, a File object may have methods to Save, Print, Display, ModifyText, etc.
An object is its own little world, and does not depend on outside behavior.
These two definitions are in direct contradiction to each other. If a File object can print itself, it will depend heavily on the printer's behavior. On the other hand, if it merely knows about something that can print for it (an IFilePrinter or some such interface), then the File object doesn't have to know anything about printing, and so working with it will bring less dependencies into the object.
So, dependency injection will break encapsulation if you use the first definition. But, frankly I don't know if I like the first definition - it clearly doesn't scale (if it did, MS Word would be one big class).
On the other hand, dependency injection is nearly mandatory if you're using the second definition of encapsulation.
It doesn't violate encapsulation. You're providing a collaborator, but the class gets to decide how it is used. As long as you follow Tell don't ask things are fine. I find constructer injection preferable, but setters can be fine as well as long as they're smart. That is they contain logic to maintain the invariants the class represents.
Pure encapsulation is an ideal that can never be achieved. If all dependencies were hidden then you wouldn't have the need for DI at all. Think about it this way, if you truly have private values that can be internalized within the object, say for instance the integer value of the speed of a car object, then you have no external dependency and no need to invert or inject that dependency. These sorts of internal state values that are operated on purely by private functions are what you want to encapsulate always.
But if you're building a car that wants a certain kind of engine object then you have an external dependency. You can either instantiate that engine -- for instance new GMOverHeadCamEngine() -- internally within the car object's constructor, preserving encapsulation but creating a much more insidious coupling to a concrete class GMOverHeadCamEngine, or you can inject it, allowing your Car object to operate agnostically (and much more robustly) on for example an interface IEngine without the concrete dependency. Whether you use an IOC container or simple DI to achieve this is not the point -- the point is that you've got a Car that can use many kinds of engines without being coupled to any of them, thus making your codebase more flexible and less prone to side effects.
DI is not a violation of encapsulation, it is a way of minimizing the coupling when encapsulation is necessarily broken as a matter of course within virtually every OOP project. Injecting a dependency into an interface externally minimizes coupling side effects and allows your classes to remain agnostic about implementation.
It depends on whether the dependency is really an implementation detail or something that the client would want/need to know about in some way or another. One thing that is relevant is what level of abstraction the class is targeting. Here are some examples:
If you have a method that uses caching under the hood to speed up calls, then the cache object should be a Singleton or something and should not be injected. The fact that the cache is being used at all is an implementation detail that the clients of your class should not have to care about.
If your class needs to output streams of data, it probably makes sense to inject the output stream so that the class can easily output the results to an array, a file, or wherever else someone else might want to send the data.
For a gray area, let's say you have a class that does some monte carlo simulation. It needs a source of randomness. On the one hand, the fact that it needs this is an implementation detail in that the client really doesn't care exactly where the randomness comes from. On the other hand, since real-world random number generators make tradeoffs between degree of randomness, speed, etc. that the client may want to control, and the client may want to control seeding to get repeatable behavior, injection may make sense. In this case, I'd suggest offering a way of creating the class without specifying a random number generator, and use a thread-local Singleton as the default. If/when the need for finer control arises, provide another constructor that allows for a source of randomness to be injected.
Having struggled with the issue a little further, I am now in the opinion that Dependency Injection does (at this time) violate encapsulation to some degree. Don't get me wrong though - I think that using dependency injection is well worth the tradeoff in most cases.
The case for why DI violates encapsulation becomes clear when the component you are working on is to be delivered to an "external" party (think of writing a library for a customer).
When my component requires sub-components to be injected via the constructor (or public properties) there's no guarantee for
"preventing users from setting the internal data of the component into an invalid or inconsistent state".
At the same time it cannot be said that
"users of the component (other pieces of software) only need to know what the component does, and cannot make themselves dependent on the details of how it does it".
Both quotes are from wikipedia.
To give a specific example: I need to deliver a client-side DLL that simplifies and hides communication to a WCF service (essentially a remote facade). Because it depends on 3 different WCF proxy classes, if I take the DI approach I am forced to expose them via the constructor. With that I expose the internals of my communication layer which I am trying to hide.
Generally I am all for DI. In this particular (extreme) example, it strikes me as dangerous.
I struggled with this notion as well. At first, the 'requirement' to use the DI container (like Spring) to instantiate an object felt like jumping thru hoops. But in reality, it's really not a hoop - it's just another 'published' way to create objects I need. Sure, encapsulation is 'broken' becuase someone 'outside the class' knows what it needs, but it really isn't the rest of the system that knows that - it's the DI container. Nothing magical happens differently because DI 'knows' one object needs another.
In fact it gets even better - by focusing on Factories and Repositories I don't even have to know DI is involved at all! That to me puts the lid back on encapsulation. Whew!
I belive in simplicity. Applying IOC/Dependecy Injection in Domain classes does not make any improvement except making the code much more harder to main by having an external xml files describing the relation. Many technologies like EJB 1.0/2.0 & struts 1.1 are reversing back by reducing the stuff the put in XML and try put them in code as annoation etc. So applying IOC for all the classes you develope will make the code non-sense.
IOC has it benefits when the dependent object is not ready for creation at compile time. This can happend in most of the infrasture abstract level architecture components, trying establish a common base framework which may need to work for different scenarios. In those places usage IOC makes more sense. Still this does not make the code more simple / maintainable.
As all the other technologies, this too has PROs & CONs. My worry is, we implement latest technologies in all the places irrespective of their best context usage.
Encapsulation is only broken if a class has both the responsibility to create the object (which requires knowledge of implementation details) and then uses the class (which does not require knowledge of these details). I'll explain why, but first a quick car anaology:
When I was driving my old 1971 Kombi,
I could press the accelerator and it
went (slightly) quicker. I did not
need to know why, but the guys who
built the Kombi at the factory knew
exactly why.
But back to the coding. Encapsulation is "hiding an implementation detail from something using that implementation." Encapsulation is a good thing because the implementation details can change without the user of the class knowing.
When using dependency injection, constructor injection is used to construct service type objects (as opposed to entity/value objects which model state). Any member variables in service type object represent implementation details that should not leak out. e.g. socket port number, database credentials, another class to call to perform encryption, a cache, etc.
The constructor is relevant when the class is being initially created. This happens during the construction-phase while your DI container (or factory) wires together all the service objects. The DI container only knows about implementation details. It knows all about implementation details like the guys at the Kombi factory know about spark plugs.
At run-time, the service object that was created is called apon to do some real work. At this time, the caller of the object knows nothing of the implementation details.
That's me driving my Kombi to the beach.
Now, back to encapsulation. If implementation details change, then the class using that implementation at run-time does not need to change. Encapsulation is not broken.
I can drive my new car to the beach too. Encapsulation is not broken.
If implementation details change, the DI container (or factory) does need to change. You were never trying to hide implementation details from the factory in the first place.
DI violates Encapsulation for NON-Shared objects - period. Shared objects have a lifespan outside of the object being created, and thus must be AGGREGATED into the object being created. Objects that are private to the object being created should be COMPOSED into the created object - when the created object is destroyed, it takes the composed object with it.
Let's take the human body as an example. What's composed and what's aggregated. If we were to use DI, the human body constructor would have 100's of objects. Many of the organs, for example, are (potentially) replaceable. But, they are still composed into the body. Blood cells are created in the body (and destroyed) everyday, without the need for external influences (other than protein). Thus, blood cells are created internally by the body - new BloodCell().
Advocators of DI argue that an object should NEVER use the new operator.
That "purist" approach not only violates encapsulation but also the Liskov Substitution Principle for whoever is creating the object.
PS. By providing Dependency Injection you do not necessarily break Encapsulation. Example:
obj.inject_dependency( factory.get_instance_of_unknown_class(x) );
Client code does not know implementation details still.
Maybe this is a naive way of thinking about it, but what is the difference between a constructor that takes in an integer parameter and a constructor that takes in a service as a parameter? Does this mean that defining an integer outside the new object and feeding it into the object breaks encapsulation? If the service is only used within the new object, I don't see how that would break encapsulation.
Also, by using some sort of autowiring feature (Autofac for C#, for example), it makes the code extremely clean. By building extension methods for the Autofac builder, I was able to cut out a LOT of DI configuration code that I would have had to maintain over time as the list of dependencies grew.
I think it's self evident that at the very least DI significantly weakens encapsulation. In additional to that here are some other downsides of DI to consider.
It makes code harder to reuse. A module which a client can use without having to explicitly provide dependencies to, is obviously easier to use than one where the client has to somehow discover what that component's dependencies are and then somehow make them available. For example a component originally created to be used in an ASP application may expect to have its dependencies provided by a DI container that provides object instances with lifetimes related to client http requests. This may not be simple to reproduce in another client that does not come with the same built in DI container as the original ASP application.
It can make code more fragile. Dependencies provided by interface specification can be implemented in unexpected ways which gives rise to a whole class of runtime bugs that are not possible with a statically resolved concrete dependency.
It can make code less flexible in the sense that you may end up with fewer choices about how you want it to work. Not every class needs to have all its dependencies in existence for the entire lifetime of the owning instance, yet with many DI implementations you have no other option.
With that in mind I think the most important question then becomes, "does a particular dependency need to be externally specified at all?". In practise I have rarely found it necessary to make a dependency externally supplied just to support testing.
Where a dependency genuinely needs to be externally supplied, that normally suggests that the relation between the objects is a collaboration rather than an internal dependency, in which case the appropriate goal is then encapsulation of each class, rather than encapsulation of one class inside the other.
In my experience the main problem regarding the use of DI is that whether you start with an application framework with built in DI, or you add DI support to your codebase, for some reason people assume that since you have DI support that must be the correct way to instantiate everything. They just never even bother to ask the question "does this dependency need to be externally specified?". And worse, they also start trying to force everyone else to use the DI support for everything too.
The result of this is that inexorably your codebase starts to devolve into a state where creating any instance of anything in your codebase requires reams of obtuse DI container configuration, and debugging anything is twice as hard because you have the extra workload of trying to identify how and where anything was instantiated.
So my answer to the question is this. Use DI where you can identify an actual problem that it solves for you, which you can't solve more simply any other way.
I agree that taken to an extreme, DI can violate encapsulation. Usually DI exposes dependencies which were never truly encapsulated. Here's a simplified example borrowed from Miško Hevery's Singletons are Pathological Liars:
You start with a CreditCard test and write a simple unit test.
#Test
public void creditCard_Charge()
{
CreditCard c = new CreditCard("1234 5678 9012 3456", 5, 2008);
c.charge(100);
}
Next month you get a bill for $100. Why did you get charged? The unit test affected a production database. Internally, CreditCard calls Database.getInstance(). Refactoring CreditCard so that it takes a DatabaseInterface in its constructor exposes the fact that there's dependency. But I would argue that the dependency was never encapsulated to begin with since the CreditCard class causes externally visible side effects. If you want to test CreditCard without refactoring, you can certainly observe the dependency.
#Before
public void setUp()
{
Database.setInstance(new MockDatabase());
}
#After
public void tearDown()
{
Database.resetInstance();
}
I don't think it's worth worrying whether exposing the Database as a dependency reduces encapsulation, because it's a good design. Not all DI decisions will be so straight forward. However, none of the other answers show a counter example.
I think it's a matter of scope. When you define encapsulation (not letting know how) you must define what is the encapsuled functionality.
Class as is: what you are encapsulating is the only responsability of the class. What it knows how to do. By example, sorting. If you inject some comparator for ordering, let's say, clients, that's not part of the encapsuled thing: quicksort.
Configured functionality: if you want to provide a ready-to-use functionality then you are not providing QuickSort class, but an instance of QuickSort class configured with a Comparator. In that case the code responsible for creating and configuring that must be hidden from the user code. And that's the encapsulation.
When you are programming classes, it is, implementing single responsibilities into classes, you are using option 1.
When you are programming applications, it is, making something that undertakes some useful concrete work then you are repeteadily using option 2.
This is the implementation of the configured instance:
<bean id="clientSorter" class="QuickSort">
<property name="comparator">
<bean class="ClientComparator"/>
</property>
</bean>
This is how some other client code use it:
<bean id="clientService" class"...">
<property name="sorter" ref="clientSorter"/>
</bean>
It is encapsulated because if you change implementation (you change clientSorter bean definition) it doesn't break client use. Maybe, as you use xml files with all written together you are seeing all the details. But believe me, the client code (ClientService)
don't know nothing about its sorter.
It's probably worth mentioning that Encapsulation is somewhat perspective dependent.
public class A {
private B b;
public A() {
this.b = new B();
}
}
public class A {
private B b;
public A(B b) {
this.b = b;
}
}
From the perspective of someone working on the A class, in the second example A knows a lot less about the nature of this.b
Whereas without DI
new A()
vs
new A(new B())
The person looking at this code knows more about the nature of A in the second example.
With DI, at least all that leaked knowledge is in one place.