I've seen multiple answers regarding 'how to stub your classes so you can control what happens within the SUT'.
They say one thing:
Create an interface and inject that interface using dependency injection and create a stub using that same interface that you then inject into the SUT.
However, what I've learned in my previous working places:
If you unit test, you test all classes/functionality.
Does that mean that for every class that has a specific function-layout you have to create an interface?
That would mean the amount of classes/files would just about be twice as many.
As seen in the example below, is this 'the way to go' or am I missing something in my unit testing process?
As a note:
I am using VS2012 Express. That means no 'Faker' framework. I am using the 'standard' VS2012 unit testing framework.
As a very, very simple example, which allows me to stub each interface passed down to a SUT.
IFoo.cs
public interface IFoo
{
string GetName();
}
Foo.cs
public class Foo : IFoo
{
public string GetName()
{
return "logic goes here";
}
}
IBar.cs:
public interface IBar : IFoo
{
IFoo GetFoo();
}
Bar.cs:
public class Bar : IBar
{
public string GetName()
{
return "logic goes here";
}
public IFoo GetFoo()
{
return null; // some instance of IFoo
}
}
IBaz.cs:
public interface IBaz
{
IBar GetBar();
}
Baz.cs:
public class Baz
{
public IBar GetBar()
{
return null; // some instance of IBar
}
}
In my opinion, you should not create interfaces just for the purpose of unit testing. If you start adding code abstractions to please the tools, then they are not helping you to be more productive. The code you write should ideally serve a specific business purpose/need - either directly, or indirectly by making the code base easier to maintain or evolve.
Interfaces sometimes do this, but certainly not always. I find that providing interfaces for components is usually a good thing, but try to avoid using interfaces for internal classes (that is, code only used inside of the given project, regardless of whether the types are declared public or not). This is because a component (as in, a set of classes working together to solve some specific problem) represents a larger concept (such as a logger or a scheduler), which is something that I may feasibly want to replace or stub out when testing.
The solution (hat tip to Robert for being first in the comments) is to use a mocking framework to generate a compatible substitution type at run-time. Mocking frameworks then allow you to verify that the class being tested interacted correctly with the substituted dummy. Moq is as mentioned a snazzy choice. Rhino.Mocks and NMock are two other popular frameworks. Typemock Isolator hooks into the profiler and is among the more powerful options (allows you to substitute even non-virtual private members), but is a commercial tool.
It's no good making up rules for how much you should unit test. It depends on what you're developing and what your goals are - if correctness always trumps time-to-market and cost is not a factor then unit testing everything is great. Most people are not so lucky and will have to compromise to achieve a reasonable level of test coverage. How much you should test may also depend on overall skill level of the team, expected lifetime and reuse of the code being written, etc.
Yes and no. In order to stub dependency you need some sort of abstraction, but that's in majority because of how mocking frameworks work (not all, naturally).
Consider simple example. You test class A that takes dependencies to classes B and C. For unit tests of A to work, you need to mock B and C - you'll need IB and IC (or base classes /w virtual members). Do you need IA? No, at least not for this test. And unless A becomes dependency to some other class, abstracting it behind interface/base class is not required.
Abstraction is great as it helps you build losely coupled code. You should abstract your dependencies. However, in practice some classes need not to be abstracted as they serve top-level/end-of-hierarchy/root roles and are not used elsewhere.
Maybe from a purist perspective that is the right way to go, but the really important thing is to make sure that external dependencies (e.g. database, network access, etc), anything that is computationally expensive/time consuming, and anything that isn't fully deterministic is abstracted away and easy to replace in your unit tests.
From a testing perspective, there is no need to make an interface for every class in your code. You make an interface to hide concrete execution of external dependencies behind a layer of abstraction. So instead of having a class that requires a direct HTTP connection mixed in with your logic, you would isolate the connection code to a class, have it implement an interface that is a member of your class, and inject a mock in place pf that interface. That way, you can test your logic in isolation, free of dependency, and the only "untested" code is boilerplate HTTP connection code that can be tested through other means.
I'd go the virtual method route. Creating interfaces for every class you need to test gets really burdensome, especially when you need tools like Resharper for the "go to implementation" every time you'd like to see the definition of a method. And there's the overhead of managing and modifying both files any time a method signature is changed or a new property or method is added.
Related
I am starting to apply SOLID principles, and am finding them slightly contradictory. My issue is as follows:
My understanding of dependency inversion principle is that classes should depend on abstractions. In practice this means classes should be derived from interfaces. All fine so far.
Next my understanding of the open/closed principle is that after a certain cut off point, you should not alter the contents of a class, but should extend and override. This makes sense so far to me.
So given the above, I would end up with something like this:
public interface IAbstraction
{
string method1(int example);
}
public Class Abstraction : IAbstraction
{
public virtual string method1(int example)
{
return example.toString();
}
}
and then at time T, method1 now needs to add " ExtraInfo" onto its returned value. Rather than altering the current implementation, I would create a new class that extends Abstraction and make it do what I needed, as follows.
public Class AbstractionV2 : Abstraction
{
public override string method1(int example)
{
return example.toString() + " ExtraInfo";
}
}
And I can see the reason for doing this is that only the code I want to call this updated method will call it, and the rest of the code will call the old method.
All makes sense to me - and I assume my understanding is correct??
However, I am also using dependency injection (simple injector), so my implementations are never through a concrete class, but instead are through my DI configuration, as follows:
container.Register<IAbstraction, Abstraction>();
The issue here is that under this setup, I can either update my DI config to be:
container.Register<IAbstraction, AbstractionV2>();
In which case all instance will now call the new method, meaning I have failed to achieve not changing the original method.
OR
I create a new interface IAbstractionV2 and implement the updated functionality there - meaning duplication of the interface declaration.
I cannot see any way around this - which leads me to wonder if dependency injection and SOLID are compatible? Or am I missing something here?
TL;DR
When we say that code is "available for extension" that doesn't automatically mean that we inherit from it or add new methods to existing interfaces. Inheritance is only one way to "extend" behavior.
When we apply the Dependency Inversion Principle we don't depend directly on other concrete classes, so we don't need to change those implementations if we need them to do something different. And classes that depend on abstractions are extensible because substituting implementations of abstractions gets new behavior from existing classes without modifying them.
(I'm half inclined to delete the rest because it says the same thing in lots more words.)
Examining this sentence may help to shed some light on the question:
and then at time T, method1 now needs to add " ExtraInfo" onto its returned value.
This may sound like it's splitting hairs, but a method never needs to return anything. Methods aren't like people who have something to say and need to say it. The "need" rests with the caller of the method. The caller needs what the method returns.
If the caller was passing int example and receiving example.ToString(), but now it needs to receive example.ToString() + " ExtraInfo", then it is the need of the caller that has changed, not the need of the method being called.
If the need of the caller has changed, does it follow that the needs of all callers have changed? If you change what the method returns to meet the needs of one caller, other callers might be adversely affected. That's why you might create something new that meets the need of one particular caller while leaving the existing method or class unchanged. In that sense the existing code is "closed" while at the same time its behavior is open to extension.
Also, extending existing code doesn't necessarily mean modifying a class, adding a method to an interface, or inheriting. It just means that it incorporates the existing code while providing something extra.
Let's go back to the class you started with.
public Class Abstraction : IAbstraction
{
public virtual string method1(int example)
{
return example.toString();
}
}
Now you have a need for a class that includes the functionality of this class but does something different. It could look like this. (In this example it looks like overkill, but in real-world example it wouldn't.)
public class SomethingDifferent : IAbstraction
{
private readonly IAbstraction _inner;
public SomethingDifferent(IAbstraction inner)
{
_inner = inner;
}
public string method1(int example)
{
return _inner.method1 + " ExtraInfo";
}
}
In this case the new class happens to implement the same interface, so now you've got two implementations of the same interface. But it doesn't need to. It could be this:
public class SomethingDifferent
{
private readonly IAbstraction _inner;
public SomethingDifferent(IAbstraction inner)
{
_inner = inner;
}
public string DoMyOwnThing(int example)
{
return _inner.method1 + " ExtraInfo";
}
}
You could also "extend" the behavior of the original class through inheritance:
public Class AbstractionTwo : Abstraction
{
public overrride string method1(int example)
{
return base.method1(example) + " ExtraInfo";
}
}
All of these examples extend existing code without modifying it. In practice at times it may be beneficial to add existing properties and methods to new classes, but even then we'd like to avoid modifying the parts that are already doing their jobs. And if we're writing simple classes with single responsibilities then we're less likely to find ourselves throwing the kitchen sink into an existing class.
What does that have to do with the Dependency Inversion Principle, or depending on abstractions? Nothing directly, but applying the Dependency Inversion Principle can help us to apply the Open/Closed Principle.
Where practical, the abstractions that our classes depend on should be designed for the use of those classes. We're not just taking whatever interface someone else has created and sticking it into our central classes. We're designing the interface that meets our needs and then adapting other classes to fulfill those needs.
For example, suppose Abstraction and IAbstraction are in your class library, I happen to need something that formats numbers a certain way, and your class looks like it does what I need. I'm not just going to inject IAbstraction into my class. I'm going to write an interface that does what I want:
public interface IFormatsNumbersTheWayIWant
{
string FormatNumber(int number);
}
Then I'm going to write an implementation of that interface that uses your class, like:
public class YourAbstractionNumberFormatter : IFormatsNumbersTheWayIWant
{
public string FormatNumber(int number)
{
return new Abstraction().method1 + " my string";
}
}
(Or it could depend on IAbstraction using constructor injection, whatever.)
If I wasn't applying the Dependency Inversion principle and I depended directly on Abstraction then I'd have to figure out how to change your class to do what
I need. But because I'm depending on an abstraction that I created to meet my needs, automatically I'm thinking of how to incorporate the behavior of your class, not change it. And once I do that, I obviously wouldn't want the behavior of your class to change unexpectedly.
I could also depend on your interface - IAbstraction - and create my own implementation. But creating my own also helps me adhere to the Interface Segregation Principle. The interface I depend on was created for me, so it won't have anything I don't need. Yours might have other stuff I don't need, or you could add more in later.
Realistically we're at times just going to use abstractions that were given to us, like IDataReader. But hopefully that's later when we're writing specific implementation details. When it comes to the primary behaviors of the application (if you're doing DDD, the "domain") it's better to define the interfaces our classes will depend on and then adapt outside classes to them.
Finally, classes that depend on abstractions are also more extensible because we can substitute their dependencies - in effect altering (extending) their behavior without any change to the classes themselves. We can extend them instead of modifying them.
Addressing the exact problem you mentioned:
You have classes that depend on IAbstraction and you've registered an implementation with the container:
container.Register<IAbstraction, Abstraction>();
But you're concerned that if you change it to this:
container.Register<IAbstraction, AbstractionV2>();
then every class that depends on IAbstraction will get AbstractionV2.
You shouldn't need to choose one or the other. Most DI containers provide ways that you can register more than one implementation for the same interface, and then specify which classes get which implementations. In your scenario where only one class needs the new implementation of IAbstraction you might make the existing implementation the default, and then just specify that one particular class gets a different implementation.
I couldn't find an easy way to do this with SimpleInjector. Here's an example using Windsor:
var container = new WindsorContainer();
container.Register(
Component.For<ISaysHello, SaysHelloInSpanish>().IsDefault(),
Component.For<ISaysHello, SaysHelloInEnglish>().Named("English"),
Component.For<ISaysSomething, SaysSomething>()
.DependsOn(Dependency.OnComponent(typeof(ISaysHello),"English")));
Every class that depends on ISaysHello will get SaysHelloInSpanish except for SaysSomething. That one class gets SaysHelloInEnglish.
UPDATE:
The Simple Injector equivalent is the following:
var container = new Container();
container.Register<ISaysSomething, SaysSomething>();
container.RegisterConditional<ISayHello, SaysHelloInEnglish>(
c => c.Consumer.ImplementationType == typeof(SaysSomething));
container.RegisterConditional<ISayHello, SaysHelloInSpanish>(
c => c.Consumer.ImplementationType != typeof(SaysSomething))
Modules become closed to modification once they are referenced by other modules. What becomes closed is the public API, the interface. Behavior can be changed via polymorphic substitution (implementing the interface in a new class and injecting it). Your IoC container can inject this new implementation. This ability to polymorphically substitute is the 'Open to extension' part. So, DIP and Open/Closed work together nicely.
See Wikipedia:"During the 1990s, the open/closed principle became popularly redefined to refer to the use of abstracted interfaces..."
I am studying IoC, DDD and AOP concepts. I've read a number of articles, docs, Ninject manual (i'm restricted to use .NET 3.5), tried some stuff and so on.
It's hard to shove everything at once to my head, but motivation, concepts and technical matters are somewhat clear. And i'd been always feeling that i was missing something.
Firstly, as i understand IoC containers' purpose is initial object structure set up?
Like, set up container in composition root, create "main" object, that is being wired all the way by IoC container.
Then, as i understand, later all objects are instantiated with factories? Although i can't help myself to perceive factory as a case of service locator (that ended up considered antipattern and by the way is used as core mechanics of IoC containers).
So the question is:
What if i want to create an instance with slightly different structure, e.g. i have
interface IFoo{}
interface IBar{}
class SomeClass
{
SomeClass(IFoo obj){...}
}
class Foo : IFoo
{
Foo(IBar obj){...}
}
class Bar : IBar
{
}
class FooBar : IBar // also implements IBar interface
{
}
So, initial binding configuration is making SomeClass.Foo.Bar structure. Assume, i also need SomeClass.Foo.FooBar. What do i do? The options i can think of:
reconfigure bindings 'in place': just no.
have a constructor parameter for top class, that has configuration for whole structure. that's pretty awful. aside from the fact that all subsequent constructors (and all other project classes constructors, in the end, i'm sure) will have to have one more parameter, it is not clearly seen, how it will function and not use some dirty tricks.
substitute what is needed after object was created. it either breaks law of demeter (about which i'm not concerned too much, but in this case it's too rude) and a couple of other principles or, in general case, isn't possible at all.
use factory that is configured somehow. it just defers/transfers the need itself to later/other place in code
use some kind of contextual/conventional binding. one solution i see (didn't test yet) it's to go all the way to the top of "activation root", check, what's creating the hierarchy. m.b. we'll have to make decorator for top level class, for container to check its type and behave accordingly. actually, container may be configured in a manner, that it decides, what concrete instance to inject by "parsing" top level interface's name. something like
ICfg_ConcreteType1_ConcreteType2_...
the problems here (besides that it looks like hack):
a) we must introduce some mnemonic system, which is not obscene/user friendly.
b) we must have rules/decorators for every factory with this "feature" (but looks like we can somewhat simplify the process at least with rules)
c) it resembles me of reflection usage with convention over configuration, which i'm averted of and treat it as a hack.
Or we may use attributes to set this up. Or may be i just don't know something.
Firstly, as i understand IoC containers' purpose is initial object structure set up?
Forget about IoC containers for a moment. Dependency Injection is not about using tools. It's first and foremost about applying principles and patterns. The driving force behind Dependency Injection are the SOLID principles. I would even go as far as start your application without using an IoC container at all, and only start using one when is a really compelling reason to do so. This means that you simply build up the object graphs by hand. The right place to do this is in your Composition Root. This should be the single place where you compose your object graphs.
And do note that this advice comes from someone who is building and maintaining a IoC container himself.
Then, as i understand, later all objects are instantiated with factories?
When practicing Dependency Injection, you will see that the need to use factories actually minimizes. They can still be useful, but I only use them sparingly nowadays.
Reason for this is that a factory usually just adds an extra (useless) layer of abstraction.
When starting with making code more loosely coupled, developers are tempted to use a factory as follows:
public class SomeClass
{
public void HandleSomething() {
IFoo foo = FooFactory.Create();
foo.DoSomething();
}
}
Although this allows a Foo implementation to be decoupled from SomeClass, SomeClass still takes a strong dependency on FooFactory. This still makes SomeClass hard to test, and lowers reusability.
After experiencing such a problem, developers often start to abstract away the FooFactory class as follows:
public class SomeClass
{
private readonly IFooFactory fooFactory;
public SomeClass(IFooFactory fooFactory) {
this.fooFactory = fooFactory;
}
public void HandleSomething() {
IFoo foo = this.fooFactory.Create();
foo.DoSomething();
}
}
Here a IFooFactory abstraction is used, which is injected using constructor injection. This allows SomeClass to be completely loosely coupled.
SomeClass however now has two external dependencies. It both knows about IFooFactory and IFoo. This duplicates the complexity of SomeClass, while there is no compelling reason to do so. We will immediately notice this increase of complexity when writing unit tests. We will now suddenly have to mock two different abstactions and test them both.
Since we are practicing constructor injection here, we can simplify SomeClass -without any downsides- to the following:
public class SomeClass
{
private readonly IFoo foo;
public SomeClass(IFoo foo) {
this.foo = foo;
}
public void HandleSomething() {
this.foo.DoSomething();
}
}
Long story short, although the Factory design pattern is still valid and useful, you will hardly ever need it for retrieving injectables.
Although i can't help myself to perceive factory as a case of service locator
No. A factory is not a service Locator. The difference between a factory and a locator is that with a factory you can build up only one particular type of objects, while a locator is untyped. You can build up anything. If you use an IoC container however, you will often see that the factory implementation will forward the request to the container. This should not be a problem, because your factory implementation should be part of your composition root. The composition root always depends on your container and this is not a form of Service Location, as Mark Seemann explains here.
Or we may use attributes to set this up. Or may be i just don't know something.
Refrain from using attributes for building up object graphs. Attributes pollute your code base and cause a hard dependency on an underlying technology. You absolutely want your application to stay oblivious to any used composition tool. As I started with, you might not even use any tool at all.
For instance, your object graph can be composed quite easily as follows:
new SomeClass(
new Foo(
new Bar()));
In your example, you seem to have two IBar implementations. From the context it is completely unclear what the function of this abstraction and these implementations are. I assume that you want to be able to switch implementations one some runtime condition. This can typically be achieved by using a proxy implementation. In that case your object graph would look as follows:
new SomeClass(
new Foo(
new BarProxy(
new Bar(),
new FooBar()));
Here BarProxy looks as follows:
public class BarProxy
{
private readonly IBar left;
private readonly IBar right;
public BarProxy(IBar left, IBar right) {
this.left = left;
this.right = right;
}
public void BarMethod(BarOperation op) {
this.GetBar(op).BarMethod(op);
}
private IBar GetBar(BarOperation op) {
return op.SomeValue ? this.left : this.right;
}
}
It's hard to say when you should start using a DI container. Some people like to stay away from DI containers almost always. I found that for the type of applications I build (that are based on these and these patterns), a DI container becomes really valuable, because it saves you from having to constantly update your Composition Root. In other words:
Dependency Injection and the SOLID principles help making your application maintainable. A DI library will help in making your composition root maintainable, but only after you made your application maintainable using SOLID and DI.
You would generally use some sort of tag system.
http://www.ghij.org/blog/post/2014/05/19/how-to-tag-classes-to-determine-which-to-reflect-with-mef.aspx
I'm trying to get my feet wet with unit testing. I'm currently not in the habit of writing interfaces for classes unless I foresee some reason I would need to swap in a different implementation. Well, now I foresee a reason: mocking.
Given that I'm going to be going from just a handful of interfaces to perhaps hundreds, the first thing that popped into my head was, Where should I put all these interfaces? Do I just mix them in with all the concrete implementations or should I put them in a sub-folder. E.g., should controller interfaces go in root/Controllers/Interfaces, root/Controllers, or something else entirely? What do you advise?
Before I discuss organization:
Well, now I foresee a reason: mocking.
You can mock with classes, as well. Subclassing works well for mocking as an option instead of always making interfaces.
Interfaces are incredibly useful - but I would recommend only making an interface if there is a reason to make an interface. I often see interfaces created when a class would work fine and be more appropriate in terms of logic. You shouldn't need to make "hundreds of interfaces" just to allow yourself to mock out implementations - encapsulation and subclassing works quite well for that.
That being said - I typically will organize my interfaces along with my classes, as grouping related types into the same namespaces tends to make the most sense. The main exception is with internal implementations of interfaces - these can be anywhere, but I will sometimes make an "Internal" folder + an Internal namespace that I use specifically for "private" interface implementations (as well as other classes that are purely internal implementation). This helps me keep the main namespace uncluttered, so the only types are the main types relating to the API itself.
Here's a suggestion, if almost all of your interfaces are to support only one class, just add the interface to the same file as the class itself under the same namespace. That way you don't have a separate file for the interface which could really clutter the project or need a sub folder just for interfaces.
If you find yourself creating different classes using the same interface, I would break the interface out into the same folder as the class unless it becomes completely unruly. But I don't think that would happen because I doubt you have hundreds of class files in the same folder. If so, that should be cleaned up and subfoldered according to functionality and the rest will take care of itself.
Coding to interfaces goes far beyond being able to test code. It creates flexibility in the code allowing a different implementation to be swapped in or out depending on product requirements.
Dependency Injection is another good reason to code to interfaces.
If we have an object called Foo that is used by ten customers and now customer x wants to have Foo work in a different way. If we have coded to an interface (IFoo) we just need to implement IFoo to the new requirements in CustomFoo. As long as we don't change IFoo there is not much needed. Customer x can use the new CustomFoo and other customers can continue to use old Foo and there need be few other code changes to accommodate.
However the point I really wanted to make is that interfaces can help eliminate circular references. If we have an object X that has a dependency on object Y and object Y has a dependency on object X. We have two options 1. with object x and y have to be in the same assembly or 2. we have to find some way of breaking the circular reference. We can do this by sharing interfaces rather than sharing implementations.
/* Monolithic assembly */
public class Foo
{
IEnumerable <Bar> _bars;
public void Qux()
{
foreach (var bar in _bars)
{
bar.Baz();
}
}
/* rest of the implmentation of Foo */
}
public class Bar
{
Foo _parent;
public void Baz()
{
/* do something here */
}
/* rest of the implementation of Bar */
}
If foo and bar have completely different uses and dependencies we probably do not want them in the same assembly especially if that assembly is already large.
To do this we can create an interface on one of the classes, say Foo, and refer to the interface in Bar. Now we can put the interface in a third assembly shared by both Foo and Bar.
/* Shared Foo Assembly */
public interface IFoo
{
void Qux();
}
/* Shared Bar Assembly (could be the same as the Shared Foo assembly in some cases) */
public interface IBar
{
void Baz();
}
/* Foo Assembly */
public class Foo:IFoo
{
IEnumerable <IBar> _bars;
public void Qux()
{
foreach (var bar in _bars)
{
bar.Baz();
}
}
/* rest of the implementation of Foo */
}
/* Bar assembly */
public class Bar:IBar
{
IFoo _parent;
/* rest of the implementation of Bar */
public void Baz()
{
/* do something here */
}
I think there is also an argument for maintaining the interfaces separate from their implementations and treating these sightly differently in the release cycle as this allows interoperability between components that were not all compiled against the same sources. If fully coding to interfaces and if interfaces can only be changed for major version increments and not on minor version increments then any component components of the same major version should work with any other component of the same major version regardless of the minor version.
This way you can have a library project with a slow release cycle containing just interfaces, enums and exceptions.
It depends. I do this: If you have to add a dependent 3rd party assembly, move the concrete versions out to a different class library. If not, they can stay side byside in the same directory and namespace.
I find that when I need hundreds of interfaces in my project to isolate dependencies, I find that there may be an issue in my design. This is especially the case when a lot of these interfaces end up having only one method. An alternative to doing this is to have your objects raise events and then bind your dependencies to those events. For an example, let's say you want to mock out persisting your data. One perfectly reasonable way to do this would be to do this:
public interface IDataPersistor
{
void PersistData(Data data);
}
public class Foo
{
private IDataPersistor Persistor { get; set; }
public Foo(IDataPersistor persistor)
{
Persistor = persistor;
}
// somewhere in the implementation we call Persistor.PersistData(data);
}
Another way you could do this without using interfaces or mocks would be do do this:
public class Foo
{
public event EventHandler<PersistDataEventArgs> OnPersistData;
// somewhere in the implementation we call OnPersistData(this, new PersistDataEventArgs(data))
}
Then, in our test, you can instead of creating a mock do this:
Foo foo = new Foo();
foo.OnPersistData += (sender, e) => { // do what your mock would do here };
// finish your test
I find this to be cleaner than using mocks excessively.
I disagree quite a bit with the Accepted answer.
1: While technically correct, you do not NEED an interface because you have the option to mock a concrete implementation, you should make an interface for 2 reasons.
You can extend your code with an interface, concrete implementations require modification, if you do not have an extension, once you get a change request.
1.1:
You can make TDD(Test driven development) without any actual implemented code, as long as you only create interfaces to test. This will also force you to consider code design before you make an implementation. Which is an excellent approach to coding.
1.2:
but I would recommend only making an interface if there is a reason to make an interface. I often see interfaces created when a class would work fine and be more appropriate in terms of logic.
There is always a reason to make an interface. Because SOLID's open/close principle says you should aim for extending your code rather than modifying it.
And this is true for multiple reasons.
1.2.1:
It's easier to write new unit tests this way. You will only need the dependency to the concrete implementation you are testing in your code as a subject. (And before you have a concrete implementation you can use a mock)
1.2.2:
When you have a concrete implementation, the reference to that concrete implementation will be propagated throughout the system. With an interface, all references will be done by interface, not concrete implementation. This makes extension possible.
1.2.3
If you follow up with all "leaf" piece of code, to follow the principle, if the method has a return, the method can't have a side effect, if the method doesn't have a return, it can only have 1 side effect, you will also automatically split your code up into the "S" part of SOLID, this makes your unit tests small, and very easy to maintain.
2:
Interfaces are technically needed, if you want to write clean code. If you want to follow SOLID, I don't see how you can do it, without interfaces.
You will also need to organize your code efficiently when you break about responsibilities, as the more decoupled your code is, the more interfaces and implementations of interfaces, you will have. Thus you need to have a good project management system in place, so you don't have "hundres of interfaces" lying around randomly.
There are so very good guides in books and youtube, udemy, etc. That will teach you this. (and also some poor ones, basically, they increase in usefulness when you have to pay for them in general). You will have to know enough about the subject matter to identify if a free one is good enough, if you plan to make business decision on it, before you do so, at least.
These 2-3 last years, many projects I see, like Cuyahoga open source C# CMS, tends to define persistent and non persistent classes as Interface. Why? Is there a good reason? TDD? Mocking? A design pattern? ...
The main reason is that this makes techniques like dependency injection easier. This in turn allows for more flexibility in the software and easier reuse and recombination of existing code. Examples for where this is useful include the various forms of unit testing (as you mentioned), but also most other forms of "regular" code reuse.
A simple example:
Say you have a method that calculates emplyoee salaries. As part of its signature, it accepts an object that calculates their benefits, say an instance of BenefitCalculator:
calculateSalary(... BenefitCalculator bc, ...)
Originally, your design has only one class BenefitCalculator. But later, it turns out that you need more than one class, e.g. because different parts of the software are supposed to use different algorithms (maybe to support different countries, or because the algorithm is supposed to be user-configurable...). In that case, rather than bloat the existing implementation of BenefitCalculator, it makes sense to create new class(es), e.g. BenefitCalculatorFrance, or BenefitCalculatorSimple etc.
Now if you use the signature
calculateSalary(... BenefitCalculator bc, ...)
, you are kind of screwed, because you cannot supply different implementations. If however you use
calculateSalary(... IBenefitCalculator
bc, ...)
you can just have all classes implement the interface.
This is actually just a special case of "loose coupling": Demand as little as possible from other parts of the code. In this case, don't demand a certain class; instead just demand that certain methods exist, which is just what an Interface does.
First of all, you can't define a class as an interface. Your class implements an interface.
Interfaces are used as one way to enable polymorphic behavior. Each class that implements the interface is free to specify its own implementation of the methods defined in the interface. Take the following for example:
You are writing banking software. Your task is to write a Transaction Processor. Now, you know you need to handle different kinds of Transactions (Deposits, Withdraws, Transfers). You could write code that looks like:
public class TransactionProcessor
{
public void ProcessDeposit( // Process Deposit );
public void ProcessWithdraw( // Process Withdraw );
public void ProcessTransfer( // Process Transfer );
}
And then every time somebody adds a new Transaction type, you have to modify your class. Or, you could:
public interface ITransaction { void Process(); }
public class TransactionProcessor
{
public void ProccessTransaction(ITransaction t) { t.Process(); }
}
Now you don't need to modify your code to Process a new type of transaction. You just need people to create their own class that implements ITransaction and your class will "just handle it".
This allows you to swap implementations of an interface depending on your needs. It also enables things like Dependency Injection and Mocking Frameworks for Unit Testing.
In general though, it really is just another way to make your code more flexible.
Interfaces have the advantage that they make you independent from the implementation, which is a good thing.
During last years IoC containers become quite popular with developers.
For example, Unity Container from Microsoft Practices. So, at the start of your application you can register concrete classes which implement interfaces, and then, for example, all classes which contain these interfaces in their constructors, or their properties marked with [Dependency] attribute will be filled, when instancing objects via Unity container's resolve. Its quite useful in the apps with complicated dependencies, when one interface can be implemented in three different classed.
And all these things can't be achieved without usage of interfaces.
At a really boring level interfaces can also help make for a faster compile.
public class A {
B b;
}
public class B {
public int getCount() {
return 10;
}
}
In this case every time internal changes to B are made, the compiler needs to re-evaluate A to determine if it needs to be recompiled.
Instead we use interfaces:
class A {
IB b;
}
interface IB {
int getCount();
}
class B : IB {
public int getCount() {
return 10;
}
}
In this case A only depends on IB. No change to B requires any consideration of A at compile time.
At scale this effect on short circuiting dependency evaluation can significantly speed up compilation of large code bases. It is particularly powerful when there are a lot of classes depending on a single class that changes a lot.
Clearly this compile time benefit only works if the classes have no static dependency on the implementation classes. Doing the following would totally defeat this benefit:
class A {
IB b = new B();
}
This is where Dependency Injection comes in. The DI container would construct a B and provide it to A as an IB so A doesn't need to have the static dependency.
I have seen arguments for using explicit interfaces as a method of locking a classes usage to that interface. The argument seems to be that by forcing others to program to the interface you can ensure better decoupling of the classes and allow easier testing.
Example:
public interface ICut
{
void Cut();
}
public class Knife : ICut
{
void ICut.Cut()
{
//Cut Something
}
}
And to use the Knife object:
ICut obj = new Knife();
obj.Cut();
Would you recommend this method of interface implementation? Why or why not?
EDIT:
Also, given that I am using an explicit interface the following would NOT work.
Knife obj = new Knife();
obj.Cut();
To quote GoF chapter 1:
"Program to an interface, not an implementation".
"Favor object composition over class inheritance".
As C# does not have multiple inheritance, object composition and programming to interfaces are the way to go.
ETA: And you should never use multiple inheritance anyway but that's another topic altogether.. :-)
ETA2: I'm not so sure about the explicit interface. That doesn't seem constructive. Why would I want to have a Knife that can only Cut() if instansiated as a ICut?
I've only used it in scenarios where I want to restrict access to certain methods.
public interface IWriter
{
void Write(string message);
}
public interface IReader
{
string Read();
}
public class MessageLog : IReader, IWriter
{
public string Read()
{
// Implementation
return "";
}
void IWriter.Write(string message)
{
// Implementation
}
}
public class Foo
{
readonly MessageLog _messageLog;
IWriter _messageWriter;
public Foo()
{
_messageLog = new MessageLog();
_messageWriter = _messageLog;
}
public IReader Messages
{
get { return _messageLog; }
}
}
Now Foo can write messages to it's message log using _messageWriter, but clients can only read. This is especially beneficial in a scenario where your classes are ComVisible. Your client can't cast to the Writer type and alter the information inside the message log.
Yes. And not just for testing. It makes sense to factor common behaviour into an interface (or abstract class); that way you can make use of polymorphism.
public class Sword: ICut
{
void ICut.Cut()
{
//Cut Something
}
}
Factory could return a type of sharp implement!:
ICut obj = SharpImplementFactory();
obj.Cut();
This is a bad idea because their usage breaks polymorphism. The type of the reference used should NOT vary the behavior of the object. If you want to ensure loose coupling, make the classes internal and use a DI technology (such as Spring.Net).
There are no doubt certain advantages to forcing the users of your code to cast your objects to the interface types you want them to be using.
But, on the whole, programming to an interface is a methodology or process issue. Programming to an interface is not going to be achieved merely by making your code annoying to the user.
Using interfaces in this method does not, in and of itself, lead to decoupled code. If this is all you do, it just adds another layer of obfuscation and probably makes this more confusing later on.
However, if you combine interface based programming with Inversion of Control and Dependency Injection, then you are really getting somewhere. You can also make use of Mock Objects for Unit Testing with this type of setup if you are into Test Driven Development.
However, IOC, DI and TDD are all major topics in and of themselves, and entire books have been written on each of those subjects. Hopefully this will give you a jumping off point of things you can research.
Well there is an organizational advantage. You can encapsulate your ICuttingSurface, ICut and related functionality into an Assembly that is self-contained and unit testable. Any implementations of the ICut interface are easily Mockable and can be made to be dependant upon only the ICut interface and not actual implementations which makes for a more modular and clean system.
Also this helps keep the inheritance more simplified and gives you more flexibility to use polymoprhism.
Allowing only callers expecting to explicit interface type ensures methods are only visible in the context they are needed in.
Consider a logical entity in a game and u decide that instead of a class responsibile for drawing/ticking the entities you want the code for tick/draw to be in the entity.
implement IDrawable.draw() and ITickable.tick() ensures an entity can only ever be drawn/ticked when the game expects it to. Otherwise these methods wont ever be visible.
Lesser bonus is when implementing multiple interfaces, explicit implementations let you work around cases where two interface method names collide.
Another potential scenario for explicitly implementing an interface is when dealing with an existing class that already implements the functionality, but uses a different method name. For example, if your Knife class already had a method called Slice, you could implement the interface this way:
public class Knife : ICut
{
public void Slice()
{
// slice something
}
void ICut.Cut()
{
Slice();
}
}
If the client code doesn't care about anything other than the fact that it can use the object to Cut() things, then use ICut.
Yes, but not necessarily for the given reasons.
An example:
On my current project, we are building a tool for data entry. We have certain functions that are used by all (or almost all) tabs, and we are coding a single page (the project is web-based) to contain all of the data entry controls.
This page has navigation on it, and buttons to interact with all the common actions.
By defining an interface (IDataEntry) that implements methods for each of the functions, and implementing that interface on each of the controls, we can have the aspx page fire public methods on the user controls which do the actual data entry.
By defining a strict set of interaction methods (such as your 'cut' method in the example) Interfaces allow you to take an object (be it a business object, a web control, or what have you) and work with it in a defined way.
For your example, you could call cut on any ICut object, be it a knife, a saw, a blowtorch, or mono filament wire.
For testing purposes, I think interfaces are also good. If you define tests based around the expected functionality of the interface, you can define objects as described and test them. This is a very high-level test, but it still ensures functionality. HOWEVER, this should not replace unit testing of the individual object methods...it does no good to know that 'obj.Cut' resulted in a cutting if it resulted in the wrong thing being cut, or in the wrong place.