Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
When you create an interface and you know you will have a dependency on another, do you make the constructor part of the interface?
In my case, I want to create
An IClientReceiveRecorder that I can give to a client and have all the network traffic collected for a short test session. It is probably just going to contain a collection of strings.
An IEvaluator that can get all the messages received and implement various things we want to test for. For example, I might have a concrete Evaluator that tests whether or not all the strings contain the letter 'c'.
I know that any IEvaluator is going to need a IClientReceiveRecorder to get the messages it is to evaluate.
So, I see a few options.
Do I do something like
interface IEvaluator
{
IEvaluator(IClientReceiveRecorder);
void Evaluate();
}
It doesn't compile, so I am guessing not.
Perhaps I do something like
interface IEvaluator
{
void Evaluate(IClientReceiveRecorder);
}
Or, do I just leave it up to the concrete class to take a IClientReceiveRecorder in its constuctor?
The straight forward answer is to leave implementation detail up to the concrete class.
Knowing that the implementation of IEvaluator is going to have a dependency of IClientReceiveRecorder is an implementation detail and would not be included in the IEvaluator interface.
If you know that the interface is going to be composed of another interface you could do something like the following:
interface IEvaluator
{
IClientReceiveRecorder { get; set; }
void Evaluate();
}
How that property is populated is an implementation detail and should not be part of the interface.
You really shouldn't need to.
An interface isn't necessarily a contract of dependencies, it's a contract of functionality. Any implementation can expose its dependencies via constructor(s). But in the event that a different implementation has different (or no) dependencies, it still implements the interface and exposes the functionality.
One thing you could do is expose a property getter in the interface which shows the dependency. This would at least imply to implementing types that they need to expose a getter with the intended type, which happens to be a dependency.
Another alternative entirely might be to use an abstract class instead of an interface. (Understanding the differences between them, of course.) That abstract class can also use a constructor to expose the dependency, and implementing types would have to use that constructor. This alternative could necessitate other changes throughout your code, so it's up to you.
I would leave any mention of the IClientReceiveRecorder out of the interface. As others have mentioned it's an implementation detail.
Further to this point, you do not know of any further uses you may have for the IEvaluator interface. If you keep the interface as follows:
public IEvaluator
{
void Evaluate();
}
then this is a very flexible interface that can be reused for any class that wants to implement evaluation semantics in future. This ties in with the Interface Segregation Principle and Single Responsibility Principle and helps to keep your classes decoupled.
Therefore, instead of including the IClientReceiveRecorder in the IEvaluateinterface simply pass it via the constructor:
public ConcreteEvaluator : IEvaluate
{
private readonly IClientReceiveRecorder recorder;
public ConcreteEvaluator(IClientReceiveRecorder recorder)
{
this.recorder = recorder;
}
public void Evaluate()
{
this.recorder.DoSomeRecording();
}
}
Interfaces don't have constructors, as you've already discovered. That's because the point of using an interface is to have your class interact with contracts for other classes, not actual implementations. That interaction is defined in the interface, but how the actual implementation gets created is not part of that interface. Ideally a class should not know how the abstractions it depends on get created.
That's a reason why constructor injection is helpful for keeping classes decoupled.
If I do this, which is a very common pattern:
public class ClassThatDependsOnSomething
{
private readonly IDependsOnThis _dependsOnThis;
public ClassThatDependsOnSomething(IDependsOnThis dependsOnThis)
{
_dependsOnThis = dependsOnThis;
}
}
then the class interacts with the interface it depends on without being responsible for creating it - calling its constructor. That keeps it truly decoupled. If my class calls the constructor, that means it knows the difference between one implementation that has one constructor vs. another implementation with a different constructor. At that point it's coupled to the implementation.
Also, what if the implementation of IDependsOnThis has its own dependencies? If ClassThatDependsOnSomething calls the implementations's constructor and passes in those dependencies, where will get those from? It would have to create them too.
This is why we use dependency injection containers. To oversimplify, a DI container allows us to declare what all of the implementations will be for all of the interfaces we use. Then we can ask the container to resolve an implementation of an interface. If that implementation has a constructor that requires more interfaces, it resolves those. And so on, and on. So when working with one class, you only need to be concerned with the that one class and the interfaces it depends on, but you shouldn't have to think about the details of the implementations of those interfaces.
One of the key benefits of this is that since a class depends on interfaces passed into its constructor, you can write unit tests for the class and pass in "mocks" or "test doubles," really simple classes that implement the interfaces and provide dummy responses to method calls. By controlling exactly what all of the dependencies do, you can test that your class behaves exactly as expected.
Related
I have a simple interface defined
public interface IBla
{
public void DoThing();
public void DoAnotherThing();
public void Thing();
}
I have a bunch of classes which implement this interface. Lots of them however only need two of the three functions which that interface implements, so currently I implement the remaining ones as well and just leave them empty like so:
public void DoThing(){}
Is there some more elegant way of doing this?
I do NOT want to have multiple interfaces defined for this.
Is there perhaps something like a "partialInterface" where I don't have to implement all of the functions from that interface into a class which implements that interface?
Thanks
When implementing an interface, the type that implements the interface must provide an implementation for everything that interface details.
There is no support for partial interfaces or anything similar to what you want, other than breaking up the interface.
You're basically asking "How can I implement the calculator interface without requiring me to provide the + operator" and in short, you can't. It would no longer be a calculator according to that interface.
The closest thing you get is that you can create a base class that provides default implementations for the whole interface or parts of it, and inherit from this base type, so that inherited classes become easier to implement with less code, but they will provide the entire interface.
I know you said you don't want separate interfaces, but for the benefit of others in future who want the right answer to this question here it is:
What you describe is the point at which you separate your interfaces out, and use interface inheritance.
public interface IBasic
{
void DoThing();
}
public interface IAdvanced : IBasic
{
void DoAnotherThing();
void Thing();
}
Implementations which only need DoThing only implement IBasic. Implementations which need all functionality implement IAdvanced which includes the method from IBasic plus the additional functionality.
If you have classes which implement not all methods, then you probably need to separate this interface into smaller interfaces.
Many specific interfaces are better than one universal.
Creating the classes which implement your interface, and throw NotImplementedException or simply do nothing looks like SOLID rules violation.
Well, it is highly discouraged to only partially implement an interface, there is a way to sort of do it.
Most answers talk about breaking up your interface into multiple interfaces, which makes sense. But, if this is not possible simply implement the members that you do not want to use in an explicit manner, and if they get called you should throw a NotSupportedException.
If you want to see an example of this in use, look no further than Microsoft's own code: http://referencesource.microsoft.com/#mscorlib/system/collections/objectmodel/readonlycollection.cs
void ICollection<T>.Add(T value)
{
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
Given that these things are being processed in a game loop, presumably implementations of IBla are things like the player character, enemies, obstacles, missiles and the like and DoThing etc and Move, Fire and so forth.
If so, then your approach is perfectly valid. An immobile object should have a Move method (so the game loop can call it), and since it can't move, an empty method is a valid implementation.
If you control both interfaces then separate the interfaces into multiple interfaces. As suggested, one interface can inherit from the other, or you could just have some classes implement both interfaces.
In this case interface inheritance is probably the better choice because you won't have to modify the classes that already implement the larger interface.
What if the larger interface is one you don't control, so splitting it into multiple interfaces isn't an option? It's not a good idea to implement the interface and leave some methods without implementations. If a class implements an interface then it should really implement the interface.
A solution is to define the smaller interface that you actually want and create a class that adapts the larger interface to your smaller one.
Suppose you have this interface
public interface IDoesFourThings
{
void DoThingOne();
void DoThingTwo();
void DoThingThree();
void DoThingFour();
}
And you want a class that only implements two of those things? You shouldn't implement IDoesFourThings if the class really only does two things.
So first, create your own interface:
public interface IDoesTwoThings
{
void DoThingA();
void DoThingB();
}
Then create a class that adapts an implementation of IDoesFourThings to your interface.
public class DoesTwoThingsUsingClassThatDoesFourThings : IDoesTwoThings
{
private readonly IDoesFourThings _doesFourThings;
public DoesTwoThingsUsingClassThatDoesFourThings(IDoesFourThings doesFourThings)
{
_doesFourThings = doesFourThings;
}
public void DoThingA()
{
_doesFourThings.DoThingTwo();
}
public void DoThingB()
{
_doesFourThings.DoThingThree();
}
}
Just for the sake of example I avoided naming the methods in IDoesTwoThings to match the ones in IDoesFourThings. Unless they're really exactly the same thing then the new interface doesn't need to match the old one. It is its own interface. That the class works by using an inner implementation of IDoesFourThings is hidden.
This relates to the Interface Segregation Principle, the I in SOLID. One way of thinking about it is this: An interface describes what a class does, but from the perspective of the client class it should describe what the client needs. In this case the client needs two things, not four.
This approach can be very helpful because it enables us to work on one class at a time and defer the implementation of other details. If we're writing a class and we realize that it's going to require a dependency that does two things, we can just write the interface for those two things and make our class depend on it. (Now that class is more testable because it depends on an interface which we can mock.) Then, whatever that new interface is that we just created, we can also create an implementation for that.
It's a great way to manage the complexity of writing code and avoid getting stuck because now we can just work on our one class with its single responsibility, not worrying too much about how the next class and the next one will work. (We likely have an idea how they will work, but maybe we don't. Either way it doesn't slow us down.)
I am struggling for last two days to get a grip of DI.
I have two problems:
If I have a some common functionality why I can't do the same thing implementing DI with an abstract class?
In my example I have many class instance created under writefile, so should I move out all object creation from there? What if I have a layered design? Should these classes be passed all along?
public interface IWriteFile
{
void write();
}
public class WriteXMLFile : IWriteFile
{
public void write()
{
}
}
public class writefile
{
IWriteFile _file;
public writefile(IWriteFile file)
{
_file = file;
}
public void WriteMyFile()
{
_file.write();
}
}
Regarding your first point:
Let's say you want to test something that uses your abstract class. If you're directly using an abstract class, then if you want to do something different in the shared functionality in the common class, there's not much you can do.
With an interface, you've broken the coupling with the dependency. This is what the Dependency Inversion Principle in SOLID is talking about when it says "High-level modules should not depend on low-level modules. Both should depend on abstractions". Your class shouldn't depend on the lower-level class (even if it's an abstract class) to get its work done. Both the lower-level and higher-level class should depend on the interface which defines how they are going to interact. Using an interface helps separate the two, giving you loose coupling. Something else can handle wiring them together.
Regarding your second point:
Powerful DI frameworks actually handle a lot of this complexity for you.
Let's say you have a class - Thing - that has a bunch of dependencies.
public Thing(
IThingRepository repository,
IEmailer emailer,
ILogger logger,
INeedMoreStuff stuff
) : IThing
When you set up your IoC container, you'd do something like the following to associate which implementation to use for each interface:
IoC.Register<MySqlThingRepository>().As<IThingRepository>();
IoC.Register<MicrosoftExchangeEmailer>().As<IEmailer>();
IoC.Register<TruncatingFileLogger>().As<ILogger>();
IoC.Register<MoreStuff>().As<INeedMoreStuff>();
IoC.Register<Thing>().As<IThing>();
Then you can simply do:
IThing thing = IoC.Resolve<IThing>();
These fancy frameworks handle getting all the dependencies for you (since you told it how to get them) and will construct a Thing for you.
That being said, sometimes a fancy framework like that is overkill. In those cases, I usually use the factory pattern to abstract out the details of creating an object while still making sure the object being created follows good DI principles like constructor injection of its dependencies.
Regarding your polymorphism and interfaces:
Someone described polymorphism as simply "Same interface, different implementation. Substitutability". Wikipedia defines it as "the provision of a single interface to entities of different types". According to those definitions, I think using interfaces doesn't go against polymorphism. I feel in C# interfaces are usually sufficient for providing different implementations of the same "interface".
Yes, you can use an abstract base class to do the same thing, but I'd only use that if there's a common set of functionality I can factor out into the base class to keep my code DRY.
Regarding multiple implementations for an interface with StructureMap
I don't how StructureMap handles this, but presumably there's some logic that will decide when you want to use Thing1 versus Things2. You might be able to provide a delegate to StructureMap that it can use to get an IThing which would contain that logic.
Alternatively, you can have a factory that takes some parameters and decides which IThing to return. There are situations where I've put an interface on my factory and constructor injected that, or alternatively have the factory creating the object using IThing use the ThingFactory to get the right one.
General architecture problem i have been thinking about
If I have an interface, and 5 classes that implement that interface, but one class does not need to implement one of the interface members, should I:
Create a seperate interface for that one class
Implement the
original interface but leave the methods empty
Implement the original interface but mark the unneccessary methods in some way
(e.g obsolete attribute)
An example is if I have an interface IRepository and 5 seperate repositories for 5 entities, but for one entity I dont want to be able to update records.
I have currently sided toward option 3, but obsolete does not seem a correct description.
any ideas?
by the way I know this is quite broad and objective but I would like to hear some opinions about the best way to go.
You could create another interface and inherite the ones you actually use
public interface IReadOnlyRepository
{
void Read();
}
public interface IRepository : IReadOnlyRepository
{
void Write();
}
Then you could use the 'base' interface IReadOnlyRepository for the class you don't want the full implementation for.
Or, using you number 3. when the user attempts to invoke C from a class that does not implement it. Throw a NotImplementedException/InvalidOperationException or other relevant exception.
I hope this helps.
Why not have 2 interfaces?
IReadableRepo
{
Data Read();
}
IUpdatableRepo : IReadableRepo
{
void Update();
}
Then implement the most relevant one in your classes.
The formal answer would be to split it into IRepository: IReadonlyRepository and implement only the interfaces that are applicable.
But as a practical approach, for just one case, you could throw a NotSupported exception from the Update() method. That's your option 3 but you cannot really mark it efficiently for compile-time feedback.
I am no expert in these matters, but from my point of view, I see an issue if you decide to stick with only one interface, it will seem you are offering a functionality that isn't supported.
In this case, you could have a base interface ReadableRepository extended by UpdateableRepository.
However, if for some reason you'll need a bit more properties for your repository, you might consider making separate interfaces for each (IDoable1, IDoable2, ..., IDoableN) and have your concrete classes implement what they need.
I am beginning my journey of learning about dependency injection, and one of the reasons that I saw why it is a good idea to use DI was that it explicitly specifies your dependencies, which also makes your code more clear.
I have also noticed that interfaces are used abundantly, but I want to know why would we not use abstract classes for the sole purpose of specifying a default constructor?
Of course no implementation could be included in the abstract class.
Wouldn't this:
abstract class FooBase
{
protected IBar _bar;
FooBase(IBar bar)
{
_bar = bar;
}
abstract void DoSomething();
abstract void DoSomethingElse();
}
Demonstrate more clearly what the dependency of a FooBase object is more than:
interface IFoo
{
IBar Bar { get; }
void DoSomething();
void DoSomethingElse();
}
?
Please keep in mind I am new to this whole concept so be nice :)
One technical reason - forcing particular parent class in languages without multiple inheritance (Java/C#) will significantly restrict freedom of implementation of the "interface".
Note that there are 2 concepts hidden behind "interface" word and it sort of make it harder to reason in C#:
"interface" and abstract concept: well defined set of properties/methods to interact with an object; contract to work with an object.
"interface" as type in particular language (C#/Java) - one possible representation of
contract in given language.
Abstract/concrete classes can be used to represent contract, but force restrictions on implementers of contract in C#.
Some other languages (like C++) don't have such restriction and abstract classes is good option there. Other languages (i.e. "duck-types" JavaScript) does not have such class/interface distinction, but you can still have "contract" with an object.
Sample:
To provide more context where you should be hitting this restriction yourself in C#: DI is commonly used along with some form of TDD or at least with basic unit tests. So you try write some code and tests that uses abstract base class for DI.
abstract class Duck {
abstract void Quack();
}
class ConcreteDuck : Duck {...}
Now if you decide to write tests you may already have test classes that helps you to mock objects (if you are not using existing once)
class MockBase {...}
class MockDuck : MockBase,?????? // Can't use Duck and MockBase together...
Interface defines a contract. An Abstract base class defines a behavior.
Essentially, you can provide a single class that implements multiple interfaces,
which then in turn can be injected into multiple classes, but you will only have
a single abstract base class (at least in C#).
Consider the point of registering a type at the container (the composition root at best)
and consider the point where you resolve the dependency (the constructor or a property).
This SO will cover some more aspects SO on interface vs base class
In .NET, you only have single inheritance. In languages/frameworks where this is the case, opting to use an abstract class as your abstraction gives the potential to "burn the base class".
This means that you force the implementer of your abstraction to inherit from a singular class, when forcing them to do so might result in inconveniencing them severely, depending on what the implementation is.
Let's say that you have your abstract class Contract. If someone has their own Base class that they want to use which exposes only protected methods (for inheritors).
Because the methods are protected, one can't use encapsulation (an instance of Base stored in a field) to access the methods in Base for your abstraction implementation.
Even worse, if you don't have access to modify Base, then you might have to resort to some very ugly workarounds (Reflection, namely).
That said, with interfaces, you give the implementer the choice of where to inherit from and don't limit their options.
The typical pattern you'll see is that you always provide an interface for your contract and code your consumers against the interface. You also provide an abstract base class that provides functionality that people may derive from for convenience, but are not obligated to derive from.
Also, if it's possible for you to provide this functionality in the form of something that is easily encapsulated (for the condition I describe above), it would be even more optimal (you'd have an abstract class which just calls the instance that exposes the methods).
I have a project where quite a few functions and variable getters will be defined, abstractly. My question is should I use an abstract class for this(with each function throwing NotImplementedException), or should I just use an interface? Or should I use both, making both an interface and then an abstract class implementing the interface?
Note, even though all of these functions and such may be defined, it does not mean they will all be used in all use cases. For instance, AddUser in an authentication class may be defined in an interface, but not ever used in a website due to closed user sign up.
In general, the answer to the question of whether or not to use inheritance or an interface can be answered by thinking about it this way:
When thinking about hypothetical
implementing classes, is it a case
where these types are what I'm
describing, or is it a case where
these types can be or can do what I'm
describing?
Consider, for example, the IEnumerable<T> interface. The classes that implement IEnumerable<T> are all different classes. They can be an enumerable structure, but they're fundamentally something else (a List<T> or a Dictionary<TKey, TValue> or a query, etc.)
On the other hand, look at the System.IO.Stream class. While the classes that inherit from that abstract class are different (FileStream vs. NetworkStream, for example), they are both fundamentally streams--just different kinds. The stream functionality is at the core of what defines these types, versus just describing a portion of the type or a set of behaviors that they provide.
Often you'll find it beneficial to do both; define an interface that defines your behavior, then an abstract class that implements it and provides core functionality. This will allow you to, if appropriate, have the best of both worlds: an abstract class for inheriting from when the functionality is core, and an interface to implement when it isn't.
Also, bear in mind that it's still possible to provide some core functionality on an interface through the use of extension methods. While this doesn't, strictly speaking, put any actual instance code on the interface (since that's impossible), you can mimic it. This is how the LINQ-to-Objects query functions work on IEnumerable<T>, by way of the static Enumerable class that defines the extension methods used for querying generic IEnumerable<T> instances.
As a side note, you don't need to throw any NotImplementedExceptions. If you define a function or property as abstract, then you don't need to (and, in fact, cannot) provide a function body for it within the abstract class; the inheriting classes will be forced to provide a method body. They might throw such an exception, but that's not something you need to worry about (and is true of interfaces as well).
Personally, I think it depends on what the "type" is defining.
If you're defining a set of behaviors, I would recommend an interface.
If, on the other hand, the type really defines a "type", then I'd prefer an abstract class. I would recommend leaving the methods abstract instead of providing an empty behavior, though.
Note, even though all of these functions and such may be defined, it does not mean they will all be used in all use cases.
If this is true, you should consider breaking this up into multiple abstract classes or interfaces. Having "inappropriate" methods in the base class/interface really is a violation of the Liskov Substitution Principle, and a sign of a design flaw.
If you're not providing any implementation, then use an interface otherwise use an abstract class. If there are some methods that may not be implemented in subclasses, it might make sense to create an intermediate abstract class to do the legwork of throwing NotSupportedException or similar.
One advantage of abstract classes is that one can add to an abstract class new class members whose default implementation can be expressed in terms of existing class members, without breaking existing inheritors of that class. By contrast, if any new members are added to an interface, every implementation of that interface must be modified to add the necessary functionality.
It would be very nice if .net allowed for an interface to include default implementations for properties, methods, and events which did not make any use of object fields. From a technical standpoint, I would think such a thing could be accomplished without too much difficulty by having for each interface a list of default vtable entries which could be used with implementations that don't define all vtable slots. Unfortunately, nothing like that ability exists in .net.
Abstract classes should be used when you can provide a partial implementation. Use interfaces when you don't want to provide any implementation at all - just definition.
In your question, it sounds like there is no implementation, so go with an interface.
Also, rather than throwing NotImplementedException you should declare your method/property with the abstract keyword so that all inheritors have to provide an implementation.
#Earlz I think refering to this: Note, even though all of these functions and such may be defined, it does not mean they will all be used in all use cases. is directly related to the best way to 'attack' this problem.
What you should aim at is minimizing the number of such functions so that it becomes irrelavant (or at least not that important) if you use either or. So improve the design as much as you can and you will see that it really doesn't matter which way you go.
Better yet post a high level of what you are trying to do and let's see if we can come up together with something nice. More brains working towards a common goal will get a better answer/design.
Another pattern that works in some situations is to create a base class that is not abstract. Its has a set of public methods that define the API. Each of these calls a Protected method that is Overideable.
This allows the derived class to pick and choose what methods it needs to implement.
So for instance
public void AddUser(object user)
{
AddUserCore(user);
}
protected virtual void AddUserCore(object user)
{
//no implementation in base
}