Dependency Inversion Principle's second statement elaboration - oop

Following two statements are core of the Dependency Inversion Principle(DIP):
"High-level modules should not depend on low-level modules. Both should depend on abstractions."
"Abstractions should not depend on details. Details should depend on abstractions."
I read different books and article about DIP; all of them explained the first statement but none of them explain the second statement: "Abstractions should not depend on details. Details should depend on abstractions". Please explain what exactly are the meaning of this second statement.

It just means that you don't want to change an abstraction just because a detail has changed because details are likely to change.
Because both high-level and low-level modules depend on abstractions, they will also have to be changed whenever a detail has changed. This would obviously be undesirable.

Don't decide on interface (abstraction) by looking at implementation (details) first.
e.g. You can define a Repository interface. But while designing Repository interface, you should not decide on interface (abstraction) by looking at specific solutions like SQL implementation or NoSQL implementation ( details).
Let the Repository interface is generic and SQL features Or NoSQL feature implementation should be specific.
You will get clarity about the second statement if you read this article by Martin Fowler
Switch out the repository for a different storage mechanism, there's no mention of SQL in its interface so we can use an in-memory solution, a NoSql solution or a RESTful service.

You should think of "details" as "implementations":
- if you declare some interface, it does not depend on its future implementation classes.
- in the other hand, implementation classes should reference their interface and implement its methods, so they depends on it.

Related

DDD: Why separate repository methods to different interfaces?

According to Vaughn Vernon's IDDD_Samples, a repository interface has some methods: issuing an identity(nextIdentity), saving an entity(save), getting an entity(productOfId), removing an entity(remove) and so on.
However, it is rare to use all the methods in a single use-case. For example, in the case of creating a new entity, two methods nextIdentity and save is used, but the others are not used.
From the point of view of Interface Segregation Principle, I thought that the methods of the repository should be separated into some interfaces. How does this help?
My long-winded answer to another question boiled down to minimizing the ability of a client from doing the "wrong" thing.
Smaller interfaces introduced and used at the "right" times can prevent a number of bugs and accidental issues developers may incur.
This means your instincts are leading you to the right direction. You can pass these "smaller" interfaces via dependency injection or other means to components that have a more narrow scheme of what they need to do (i.e. components designed for each use case). This prevents you or others from doing something you "shouldn't" automatically.
From the point of view of Interface Segregation Principle, I thought that the methods of the repository should be separated into some interfaces. How does this help?
I would describe it this way: Interface Segregation comes at a cost.
In this case, segregating this interface introduces eight? new role interfaces that each need to be managed. Possibly more, possibly fewer, depending on how many distinct use cases we are trying to manage, and how much fine grained control we want to support.
My suspicion is that, for Vernon's purposes, what he wants is the banana -- a clear demonstration of the responsibilities of repositories without dragging in the gorilla and the rest of the jungle.
Another way of expressing the same idea: the responsibilities here have a lot of cohesion -- when you replace your persistence solution, it is likely that the implementation of all of these responsibilities will need to change, and it is natural that they change together.
The best fit solution for a tutorial, where you are trying to present to a student a single idea, and the best fit solution for a living system, where you frequently need to make fine grained changes to the implementation of responsibilities, are not necessarily the same.
Horses for courses.

Deciding extent of coupling

I have a Component which has API exposed with some 10 functionality in all. I can think of two ways to achieve it:
Give out all these functionality as separate functions.
Expose only one function which takes an XML as input. Based on request_Type specified and the parameters passed in the XML, I internally call one of the respective functions.
Q1. Will the second design be more loosely coupled than the first ?
I always read about how I should try my components to be loosely coupled, should I really go to this extent to achieve lose coupling ?
Q2. Which one of these would be a better design in terms of OOP and why?
Edit:
If I am exposing this API over D-Bus for others to use, will type checking still be a consideration to compare the two approaches? From what I understand type checking is done at compile time, but in case when this function is exposed over some IPC, issue of type checking comes into picture ?
The two alternatives you propose do not differ in the (obviously quite large) number of "functions" you want to offer from your API. However, the second seems to have many disadvantages because you are loosing any strong type checking, it will become much harder to document the functionality etc. (The only advantage I see is that you don't need to change your API if you add functionality. But at the disadvantage that users will not be able to figure out API changes like deleted functions until run-time.)
What is more related with this question is the Single Responsiblity Principle (http://en.wikipedia.org/wiki/Single_responsibility_principle). As you are talking about OOP, you should not expose your tens of functions within one class but split them among different classes, each with a single responsibility. Defining good "responsibilities" and roles requires some practice, but following some basic guidelines will help you to get started quickly. See Are there any rules for OOP? for a good starting point.
Reply to the question edit
I haven't used D-Bus, so this might be totally wrong. But from a quick look at the tutorial I read
Each object supports one or more interfaces. Think of an interface as
a named group of methods and signals, just as it is in GLib or Qt or
Java. Interfaces define the type of an object instance.
DBus identifies interfaces with a simple namespaced string, something
like org.freedesktop.Introspectable. Most bindings will map these
interface names directly to the appropriate programming language
construct, for example to Java interfaces or C++ pure virtual classes.
As far as I understand, D-Bus has the concept of differnt objects which provide interfaces consisting of several methods. This means (to me) that my answer above still applies. The "D-Bus native" way of specifying your API would mean to exhibit interfaces and I don't see any reason why good OOP design guidelines shouldn't be valid, here. As D-Bus seems to map these even to native language constructs, this is even more likely.
Of course, nobody keeps you from just building your own API description language in XML. However, things like are some kind of abuse of underlying techniques. You should have good reasons for doing such things.

Why should we place interfaces with classes that use them rather than those that implement them?

I was going through an article by Robert C. Martin and at one place he gave a example like this:
The first image shows that there's a cyclic dependency between the two packages. To remove this dependency a new interface is added in the second image. B implements the interface and Y uses it. And Martin makes the following point:
Interfaces are very often included in the package that uses them, rather than in
the package that implements them.
My question is, why should we arrange interfaces this way? What is the reasoning behind packaging interfaces this way? According to Common Closure Principle classes that change together should stay together. Is an interface closer to its implementer or its user, in terms of change???
Technically, the user is no closer to the interface than the implementor. In terms of change both will need to change when the interface changes.
However, why would the interface change?
The user calls to an interface so it can be independent of whatever implementor is available. Therefore the definition of the interface is dictated by the needs of the user.
As the user dictates the definition of the interface, there is no point changing the interface if the user doesn't need it. An implementor requiring a change to the interface to accommodate the implementation should send up red flags. Why does it need more or different information from the user? What use is that to the user?
Also, the implementor "merely" depends on the interface in as much as it needs to provide implementations for each of the methods in the interface. But it is free to provide empty stubs, in essence delivering a NOP to its clients.
So, the user's needs drive changes to the interface and changes to the interface drive changes to the implementor(s). As such the user is functionally much closer to the interface than the implementor. Which makes a good case to declare the interface with the user and not the implementor.
It should first be said that there's no one way to skin a cat.
This particular methodology is useful when splitting up a project up between multiple project teams or creating a system with decoupled sub-systems. The interface serves as a "contract" between two sub-systems. By the placing the interface on "their turf", the consuming party has a better guarantee that the interface will remain unchanged, unless the implementing party contacts the consuming party to request such a change.
Usually we use interfaces as a protocol between a server and a client so that the client knows what services are available but there's a side effect for this approach , the client will be dependent to the server and therefore if something changed in server side that affects the given interface the client should change too.
So there's this principle among the SOLID principles , invented by Robert C. Martin, and that's "Dependency Inversion Principle" or "DIP" , that as it name implies says we should invert the dependency between client and server in order to avoid client changes in future.In this approach client says what it's going to need via an interface and server should implement it to serve what it needs, therefore no changes in server side make us to change the client.
This is an issue of resolving cyclic dependencies between components AB and XY. None can be compiled without the other. AB is referencing XY and XY is referencing AB.
Robert C. Martin is appying the InversinOfControl pattern to resolve this
Now XY is referencing ABInterface. ABInterface does not need to know XY at all.
Your are right, this violates cohesion (you called it Common Closure Principle)
It also contradicts the KeepItSimple principle. The simplest solution would have only one monolitic component ABXY that is much harder to maintain.
There's no reason to implement an interface until there's something that needs it. YAGNI.

When do you need to create abstractions in the form of interfaces?

When do you encourage programming against an interface and not directly to a concrete class?
A guideline that I follow is to create abstractions whenever code requires to cross a logical/physical boundary, most especially when infrastructure-related concerns are involved.
Another checkpoint would be if a dependency will likely change in the future, due to possible additional concerns code (such as caching, transactional awareness, invoking a webservice instead of in-process execution) or if such dependencies have direct references to infrastructure integration points.
If code depends on something that does not require control to cross a logical/physical boundary, I more or less don't create abstractions to interact with those.
Am I missing anything?
Also, use interfaces when
Multiple objects will need to be acted upon in a particular fashion, but are not fundamentally related. Perhaps many of your business objects access a particular utility object, and when they do they need to give a reference of themselves to that utility object so the utility object can call a particular method. Have that method in an interface and pass that interface to that utility object.
Passing around interfaces as parameters can be very helpful in unit testing. Even if you have just one type of object that sports a particular interface, and hence don't really need a defined interface, you might define/implement an interface solely to "fake" that object in unit tests.
related to the first 2 bullets, check out the Observer pattern and the Dependency Injection. I'm not saying to implement these patterns, but they illustrate types of places where interfaces are really helpful.
Another twist on this is for implementing a couple of the SOLID Principals, Open Closed principal and the Interface Segregation principle. Like the previous bullet, don't get stressed about strictly implementing these principals everywhere (right away at least), but use these concepts to help move your thinking away from just what objects go where to thinking more about contracts and dependency
In the end, let's not make it too complicated: we're in a strongly typed world in .NET. If you need to call a method or set a property but the object you're passing/using could be fundamentally different, use an interface.
I would add that if your code is not going to be referenced by another library (for a while at least), then the decision of whether to use an interface in a particular situation is one that you can responsibly put off. The "extract interface" refactoring is easy to do these days. In my current project, I've got an object being passed around that I'm thinking maybe I should switch to an interface; I'm not stressing about it.
Interfaces abstraction are convenient when doing unit test. It helps for mocking test objects. It very useful in TDD for developing without actually using data from your database.
If you don't need any features of the class that aren't found in the Interface...then why not always prefer the Interface implementation?
It will make your code easier to modify in the future and easier to test (mocking).
you have the right idea, already. i would only add a couple of notes to this...
first, abstraction does not mean 'interface'. for example, a "connection string" is an abstraction, even though it's just a string... it's not about the 'type' of the thing in question, it's about the intention of use for that thing.
and secondly, if you are doing test automation of any kind, look for the pain and friction that are exposed by writing the tests. if you find yourself having to set up too many external conditions for a test, it's a sign that you need a better abstraction between the thing your testing and the things it interacts with.
I think you've said it pretty well. Much of this will be a stylistic thing. There are open source projects I've looked at where everything has an interface and an implementation, and it's kind of frustrating, but it might make iterative development a little easier, since any objects implementation can break but dummies will still work. But honestly, I can dummy any class that doesn't overuse the final keyword by inheritance.
I would add to your list this: anything which can be thought of as a black box should be abstracted. This includes some of the things you've mentioned, but it also includes hairy algorithms, which are likely to have multiple useful implementations with different advantages for different situation.
Additionally, interfaces come in handy very often with composite objects. That's the only way something like java's swing library gets anything done, but it can also be useful for more mundane objects. (I personally like having an interface like ValidityChecker with ways to and-compose or or-compose subordinate ValidityCheckers.)
Most of the useful things that come with the Interface passing have been already said. However I would add:
implementing an interface to an object, or later multiple objects, FORCES all the implementers to follow an IDENTICAL pattern to implement contract with the object. This can be useful in case you have not so OOP-experienced-programmers actually writing the implementation code.
in some languages you can add attributes on the interface itself, which can be different from the actual object implementation attribute as sense and intent

Does dependency injection break the Law of Demeter

I have been adding dependency injection to my code because it makes by code much easier to Unit test through mocking.
However I am requiring objects higher up my call chain to have knowledge of objects further down the call chain.
Does this break the Law of Demeter? If so does it matter?
for example: a class A has a dependency on an interface B, The implementation of this interface to use is injected into the constructor of class A. Anyone wanting to use class A must now also have a reference to an implementation of B. And can call its methods directly meaning and has knowledge of its sub components (interface B)
Wikipedia says about the law of Demeter: "The fundamental notion is that a given object should assume as little as possible about the structure or properties of anything else (including its subcomponents)."
Dependency Injection CAN break the Law of Demeter. If you force consumers to do the injection of the dependencies. This can be avoided through static factory methods, and DI frameworks.
You can have both by designing your objects in such a way that they require the dependencies be passed in, and at the same time having a mechanism for using them without explicit performing the injection (factory functions and DI frameworks).
How does it break it? DI perfectly fits in idea of least knowledge. DI gives you low coupling - objects are less defendant on each other.
Citing Wikipedia:
...an object A can request a service (call
a method) of an object instance B, but
object A cannot “reach through” object
B to access yet another object...
Usually DI works exactly the same way, i.e. you use services provided by injected components. If your object try to access some of the B's dependencies i.e. it knows much about B - that's leads to high coupling and breaks idea of DI
However I am requiring objects higher
up my call chain to have knowledge of
objects further down the call chain
Some example?
If I understand you correctly, this isn't caused by the use of dependency injection, it's caused by using mocking strategies that have you specify the function calls you expect a method to make. That's perfectly acceptable in many situations, but obviously that means you have to know something about the method you're calling, if you've specified what you think it's supposed to do.
Writing good software requires balancing tradeoffs. As the implementation becomes more complete, it becomes more inconsistent. You have to decide what risks those inconsistencies create, and whether they're worth the value created by their presence.
Does it break the law?
Strictly speaking, I think it does.
Does it matter?
The main danger of breaking the law is that you make your code more brittle.
If you really keep it to just the tests, it seems like that danger is not too bad.
Mitigation
My understanding of the Law of Demeter is that it can be followed by having "wrapper methods" which prevent directly calling down into objects.
The Law of Demeter specifies that the method M of the object O can call methods on objects created/instantiated inside M. However, there's nothing that specifies how these objects were created. I think it's perfectly fine to use an intermediary object to create these, as long as that object's purpose in life is only that - creating other objects on your behalf. In this sense, DI does not break the Law of Demeter.
This also confused me for some time. In the wiki it also says...
An object A can request a service (call a method) of an object instance B, but object A should not "reach through" object B to access yet another object, C, to request its services. Doing so would mean that object A implicitly requires greater knowledge of object B's internal structure.
And this is the crux of the matter. When you interact with Class A you should not be able to interact with the state or methods of interface B. You simply shouldn't have access to its inner workings.
As for creating class A and knowing about interface B when creating objects; that's a different scenario altogether, it is not what the law of Demeter is trying to address in software design.
I would agree with other answers in that factories and a dependency injection framework would be best to handle this. Hope that clears it up for anyone else confused by this :)
Depends :-)
I think the top answer is not correct , even with a framework a lot of code uses Dependency injection and injects high level objects. You then get spaghetti code with lots of dependencies.
Dependency injection is best used for all the stuff that would pollute your object model eg an ILogger. If you do inject business object ensure its at the lowest level possible and try to pass it the traditional method if you can . Only use the dependecy injection if it gets to messy .
Before I add my answer, I must qualify it. Service-Oriented Programming is built on top of OOP Principles and using OO Languages. Also, SOAs follow Inversion of Control and SOLID Principles to the teeth. So a lot of Service-Oriented programmers are surely arriving here. So, this answer is for Service-Oriented Programmers who arrive to this question, because SOA is built on top of OOP. This does no directly answer the OP's example, but does answer the question from an SOA Perspective.
In General, the Law of Demeter doesn't apply to Service-Oriented Architectures. For OO, the Law of Demeter is talking about "Rich Objects" in OOP which have properties and methods, and whose properties may also have methods. With OOP Rich Models, it is possible to reach through a chain of objects and access methods, properties, methods of properties, methods of properties' properties, etc. But in Service-Oriented Programming, Data (Properties) are separated from Process (Methods). Your Models (mainly) only have properties (Certainly never dependencies), and your Services only have Methods and dependencies on other Services.
In SOP, you can feel free to review the properties of a model, and properties of its properties. You won't ever be able to access methods you shouldn't, only a tree of data. But what about the Services? Does the Law of Demeter apply there?
Yes, the Law of Demeter Can Be applied to SOP Services. But again, the law was originally designed for Rich Models in OOP. And though the law Can Be applied to Services, proper Dependency Injection automagically fulfills the Law of Demeter. In that sense, DI Could not possibly break the law.
In limited opposition to Mark Roddy, I can't find any situation where you can legitimately talk about Dependency Injection and "consumers" in the same sentence. If by "consumers" you mean a class that is consuming another class, that doesn't make sense. With DI, you would have a Composition Root composing your object graph, and one class should never know another class even exists. If by "consumers" you mean a programmer, then how would they not be forced to "do the injection." The programmer is the one who has to create the Composition Root, so they must do the injection. A Programmer should never "do the injection" as an instantiation within a class to consume another class.
Please review the following example which shows actual separate solutions, their references, and the implementing code:
In the top-right, we have the "Core." A lot of packages on NuGet and NPM have a "Core" Project which has Model, Interfaces, and possibly even default implementations. The Core should never ever ever depend on anything external.
In the top-left, we have an external implementation of the Core. The implementation depends on the Core, and so has knowledge of it.
In the bottom-left, we have a standalone Domain. The Domain has a Dependency on some Implementation of the Core, but Does not need to know about the implementation.
This is where I point out that neither the Domain nor the Implementation know each other exist. There is a 0% chance that either could ever reach into (Or beyond) the other one, because they don't even know they exist. The domain only knows that there is a contract, and it can somehow consume the methods by whatever is injected into it.
In the bottom-left is the Composition Root or Entry-Point. This is also known as the "Front Boundary" of the application. The root of an application knows all of its components and does little more than take input, determine who to call, compose objects, and return outputs. In other words, it can only tell the Domain "Here, use this to fulfill your contract for ICalculateThings, then give me the result of CalculateTwoThings.
There is indeed a way to smash everything into the same project, do concrete instantiations of Services, make your dependencies public properties instead of private fields, STILL Do Dependency-Injection (horribly), and then have services call into dependencies of dependencies. But that would be bad, m'kay. You'd have to be trying to be bad to do that.
Side-note, I over-complicated this on purpose. These projects could exist in one solution (as long as the Architect controls the Reference Architecture), and there could be a few more simplifications. But the separation in the image really shows how little knowledge the system has to have about its parts. Only the Composition Root (Entry Point, Front-Boundary) need to know about the parts.
Conclusion (TL;DR;): In Oldskewl OOP, Models are Rich, and the Law of Demeter can easily be broken by looking into models of models to access their methods. But in Newskewl SOP (built on top of OOP Principles and Languages), Data is separated from Process. So you can feel free to look into properties of models. Then, for Services, dependencies are always private, and nothing knows that anything else exists other than what they are told by abstractions, contracts, interfaces.